Problem 424

Parses 200 puzzle lines from data/p424.txt, solves each as a CSP with bitmask domains, all-different on letters, and run constraints. Sums the 10-digit numbers from the solved letter mappings.

Answer1059760019628
Output1059760019628
StatusPASS
Native helperno
Runtime60 ms
Peak memory3328 KB
Time complexityO(n log n) (estimated)
Space complexityO(n^2) (estimated)

Performance comparison

MetricOur solutionBest known
Time complexityO(n log n)O(n!)
Space complexityO(n^2)O(n^2)
ApproachFlow solutionBacktracking search
VerdictOptimal

Flow source

# Project Euler 424: Cryptic Kakuro CSP with GAC propagation.
# Parses 200 puzzle lines from data/p424.txt, solves each as a CSP
# with bitmask domains, all-different on letters, and run constraints.
# Sums the 10-digit numbers from the solved letter mappings.

extern {
    function calloc(n: i64, size: i64) -> ptr<void>
    function realloc(p: ptr<void>, n: i64) -> ptr<void>
    function free(p: ptr<void>)
    function printf(fmt: ptr<i8>, ...) -> i32
    function fopen(path: ptr<i8>, mode: ptr<i8>) -> ptr<void>
    function fgets(buf: ptr<i8>, n: i32, f: ptr<void>) -> ptr<i8>
    function fclose(f: ptr<void>) -> i32
    function abort() -> void
}

const ALL10: i32 = 1023
const DIGITS_19: i32 = 1022
const MAX_GRID: i32 = 400
const MAX_RUNS: i32 = 200
const MAX_VARS: i32 = 400
const MAX_PERMS_TOTAL: i32 = 700000
const MAX_LINE: i32 = 2048

# Cell types
const CT_X: i32 = 0
const CT_O: i32 = 1
const CT_L: i32 = 2
const CT_C: i32 = 3

# PERMS table: perms_count[L][S], perms_offset[L][S], perms_data (flat)
# L=0..6, S=0..45
let mut perms_count: ptr<i32> = 0 as ptr<i32>
let mut perms_offset: ptr<i32> = 0 as ptr<i32>
let mut perms_data: ptr<i32> = 0 as ptr<i32>
let mut perms_total: i32 = 0
let mut perms_init_done: i32 = 0

# Grid (per puzzle)
let mut g_type: ptr<i32> = 0 as ptr<i32>
let mut g_letter: ptr<i32> = 0 as ptr<i32>
let mut g_h_len: ptr<i32> = 0 as ptr<i32>
let mut g_h_data: ptr<i8> = 0 as ptr<i8>
let mut g_v_len: ptr<i32> = 0 as ptr<i32>
let mut g_v_data: ptr<i8> = 0 as ptr<i8>
let mut cell_to_var: ptr<i32> = 0 as ptr<i32>

# CSP (per puzzle)
let mut csp_domains: ptr<i32> = 0 as ptr<i32>
let mut csp_nvars: i32 = 0
let mut csp_nruns: i32 = 0
# Run parallel arrays
let mut run_cv_off: ptr<i32> = 0 as ptr<i32>
let mut run_cv_data: ptr<i32> = 0 as ptr<i32>
let mut run_cv_count: ptr<i32> = 0 as ptr<i32>
let mut run_sl0: ptr<i32> = 0 as ptr<i32>
let mut run_sl1: ptr<i32> = 0 as ptr<i32>
let mut run_nsl: ptr<i32> = 0 as ptr<i32>
let mut run_inv_off: ptr<i32> = 0 as ptr<i32>
let mut run_inv_data: ptr<i32> = 0 as ptr<i32>
let mut run_inv_count: ptr<i32> = 0 as ptr<i32>
let mut run_inv_index: ptr<i32> = 0 as ptr<i32>
let mut run_length: ptr<i32> = 0 as ptr<i32>
let mut run_sums_off: ptr<i32> = 0 as ptr<i32>
let mut run_sums_data: ptr<i32> = 0 as ptr<i32>
let mut run_sums_count: ptr<i32> = 0 as ptr<i32>
let mut run_dup: ptr<i32> = 0 as ptr<i32>
let mut run_ssame: ptr<i32> = 0 as ptr<i32>
# var_to_runs
let mut v2r_off: ptr<i32> = 0 as ptr<i32>
let mut v2r_data: ptr<i32> = 0 as ptr<i32>
let mut v2r_count: ptr<i32> = 0 as ptr<i32>

# Pool allocators
let mut cv_pool: ptr<i32> = 0 as ptr<i32>
let mut cv_pool_next: i32 = 0
let mut inv_pool: ptr<i32> = 0 as ptr<i32>
let mut inv_pool_next: i32 = 0
let mut inv_idx_pool: ptr<i32> = 0 as ptr<i32>
let mut inv_idx_pool_next: i32 = 0
let mut sums_pool: ptr<i32> = 0 as ptr<i32>
let mut sums_pool_next: i32 = 0
let mut v2r_pool: ptr<i32> = 0 as ptr<i32>
let mut v2r_pool_next: i32 = 0

# Line buffer
let mut line_buf: ptr<i8> = 0 as ptr<i8>

# Temp buffer for a perm lookup
let mut perm_buf: ptr<i32> = 0 as ptr<i32>

function init_globals() -> void {
    perms_count = calloc(7 * 46, 4) as ptr<i32>
    perms_offset = calloc(7 * 46, 4) as ptr<i32>
    perms_data = calloc(MAX_PERMS_TOTAL, 4) as ptr<i32>
    g_type = calloc(MAX_GRID, 4) as ptr<i32>
    g_letter = calloc(MAX_GRID, 4) as ptr<i32>
    g_h_len = calloc(MAX_GRID, 4) as ptr<i32>
    g_h_data = calloc(MAX_GRID * 4, 1) as ptr<i8>
    g_v_len = calloc(MAX_GRID, 4) as ptr<i32>
    g_v_data = calloc(MAX_GRID * 4, 1) as ptr<i8>
    cell_to_var = calloc(MAX_GRID, 4) as ptr<i32>
    csp_domains = calloc(MAX_VARS, 4) as ptr<i32>
    run_cv_off = calloc(MAX_RUNS, 4) as ptr<i32>
    run_cv_data = calloc(MAX_RUNS * 20, 4) as ptr<i32>
    run_cv_count = calloc(MAX_RUNS, 4) as ptr<i32>
    run_sl0 = calloc(MAX_RUNS, 4) as ptr<i32>
    run_sl1 = calloc(MAX_RUNS, 4) as ptr<i32>
    run_nsl = calloc(MAX_RUNS, 4) as ptr<i32>
    run_inv_off = calloc(MAX_RUNS, 4) as ptr<i32>
    run_inv_data = calloc(MAX_RUNS * 30, 4) as ptr<i32>
    run_inv_count = calloc(MAX_RUNS, 4) as ptr<i32>
    run_inv_index = calloc(MAX_RUNS * 30, 4) as ptr<i32>
    run_length = calloc(MAX_RUNS, 4) as ptr<i32>
    run_sums_off = calloc(MAX_RUNS, 4) as ptr<i32>
    run_sums_data = calloc(MAX_RUNS * 50, 4) as ptr<i32>
    run_sums_count = calloc(MAX_RUNS, 4) as ptr<i32>
    run_dup = calloc(MAX_RUNS, 4) as ptr<i32>
    run_ssame = calloc(MAX_RUNS, 4) as ptr<i32>
    v2r_off = calloc(MAX_VARS, 4) as ptr<i32>
    v2r_data = calloc(MAX_VARS * 50, 4) as ptr<i32>
    v2r_count = calloc(MAX_VARS, 4) as ptr<i32>
    cv_pool = calloc(5000, 4) as ptr<i32>
    inv_pool = calloc(5000, 4) as ptr<i32>
    inv_idx_pool = calloc(5000, 4) as ptr<i32>
    sums_pool = calloc(10000, 4) as ptr<i32>
    v2r_pool = calloc(20000, 4) as ptr<i32>
    line_buf = calloc(MAX_LINE, 1) as ptr<i8>
    perm_buf = calloc(10, 4) as ptr<i32>
}

function popcount(x: i32) -> i32 {
    let mut c: i32 = 0
    let mut v: i32 = x
    while v > 0 {
        c = c + 1
        v = v & (v - 1)
    }
    return c
}

function ctz(x: i32) -> i32 {
    if x == 0 { return 32 }
    let mut n: i32 = 0
    let mut v: i32 = x
    while (v & 1) == 0 {
        n = n + 1
        v = v >> 1
    }
    return n
}

# Insertion sort for small arrays
function sort_i32(arr: ptr<i32>, n: i32) -> void {
    let mut i: i32 = 1
    while i < n {
        let key: i32 = arr[i]
        let mut j: i32 = i - 1
        while j >= 0 {
            if arr[j] > key {
                arr[j + 1] = arr[j]
                j = j - 1
            } else {
                break
            }
        }
        arr[j + 1] = key
        i = i + 1
    }
}

# Remove duplicates from sorted array, return new count
function unique_i32(arr: ptr<i32>, n: i32) -> i32 {
    if n <= 1 { return n }
    let mut w: i32 = 1
    let mut r: i32 = 1
    while r < n {
        if arr[r] != arr[r - 1] {
            arr[w] = arr[r]
            w = w + 1
        }
        r = r + 1
    }
    return w
}

# next_permutation on array, returns 1 if next exists, 0 if wrapped
function next_perm(arr: ptr<i32>, n: i32) -> i32 {
    if n <= 1 { return 0 }
    let mut i: i32 = n - 2
    while i >= 0 {
        if arr[i] < arr[i + 1] { break }
        i = i - 1
    }
    if i < 0 { return 0 }
    let mut j: i32 = n - 1
    while j > i {
        if arr[j] > arr[i] { break }
        j = j - 1
    }
    let tmp: i32 = arr[i]
    arr[i] = arr[j]
    arr[j] = tmp
    # reverse i+1..n-1
    let mut a: i32 = i + 1
    let mut b: i32 = n - 1
    while a < b {
        let t2: i32 = arr[a]
        arr[a] = arr[b]
        arr[b] = t2
        a = a + 1
        b = b - 1
    }
    return 1
}

# Generate all permutations of digits 1-9 taken L at a time, grouped by sum
function init_perms() -> void {
    if perms_init_done == 1 { return }
    perms_init_done = 1
    let digits: ptr<i32> = perm_buf
    let mut d: i32 = 0
    while d < 9 {
        digits[d] = d + 1
        d = d + 1
    }
    let chosen: ptr<i32> = calloc(10, 4) as ptr<i32>
    let mask: ptr<i32> = calloc(10, 4) as ptr<i32>
    # Pass 1: count perms for each (L, S)
    let mut L: i32 = 1
    while L <= 6 {
        let mut mi: i32 = 0
        while mi < 9 {
            if mi < 9 - L {
                mask[mi] = 0
            } else {
                mask[mi] = 1
            }
            mi = mi + 1
        }
        let mut first: i32 = 1
        while first == 1 || next_perm(mask, 9) == 1 {
            first = 0
            let mut ci: i32 = 0
            let mut di: i32 = 0
            while di < 9 {
                if mask[di] == 1 {
                    chosen[ci] = digits[di]
                    ci = ci + 1
                }
                di = di + 1
            }
            sort_i32(chosen, L)
            let mut first2: i32 = 1
            while first2 == 1 || next_perm(chosen, L) == 1 {
                first2 = 0
                let mut s: i32 = 0
                let mut pi: i32 = 0
                while pi < L {
                    s = s + chosen[pi]
                    pi = pi + 1
                }
                let idx: i32 = L * 46 + s
                perms_count[idx] = perms_count[idx] + 1
                perms_total = perms_total + 1
            }
        }
        L = L + 1
    }
    # Compute offsets
    let mut acc: i32 = 0
    let mut idx2: i32 = 0
    while idx2 < 7 * 46 {
        perms_offset[idx2] = acc
        let curL: i32 = idx2 / 46
        acc = acc + perms_count[idx2] * curL
        idx2 = idx2 + 1
    }
    # Use a cursor array to track fill position for each (L, S)
    let cursor: ptr<i32> = calloc(7 * 46, 4) as ptr<i32>
    idx2 = 0
    while idx2 < 7 * 46 {
        cursor[idx2] = perms_offset[idx2]
        idx2 = idx2 + 1
    }
    # Pass 2: fill perms_data grouped by (L, S)
    L = 1
    while L <= 6 {
        let mut mi: i32 = 0
        while mi < 9 {
            if mi < 9 - L {
                mask[mi] = 0
            } else {
                mask[mi] = 1
            }
            mi = mi + 1
        }
        let mut first: i32 = 1
        while first == 1 || next_perm(mask, 9) == 1 {
            first = 0
            let mut ci: i32 = 0
            let mut di: i32 = 0
            while di < 9 {
                if mask[di] == 1 {
                    chosen[ci] = digits[di]
                    ci = ci + 1
                }
                di = di + 1
            }
            sort_i32(chosen, L)
            let mut first2: i32 = 1
            while first2 == 1 || next_perm(chosen, L) == 1 {
                first2 = 0
                let mut s: i32 = 0
                let mut pi: i32 = 0
                while pi < L {
                    s = s + chosen[pi]
                    pi = pi + 1
                }
                let idx: i32 = L * 46 + s
                let off: i32 = cursor[idx]
                let mut pi2: i32 = 0
                while pi2 < L {
                    perms_data[off + pi2] = chosen[pi2]
                    pi2 = pi2 + 1
                }
                cursor[idx] = off + L
            }
        }
        L = L + 1
    }
    free(cursor)
    free(chosen)
    free(mask)
}

# Get perm p for length L, sum S, index k. Fills perm_buf[0..L-1].
function get_perm(L: i32, S: i32, k: i32) -> void {
    let idx: i32 = L * 46 + S
    let off: i32 = perms_offset[idx] + k * L
    let mut i: i32 = 0
    while i < L {
        perm_buf[i] = perms_data[off + i]
        i = i + 1
    }
}

# Split line by commas at depth 0. Fills token offsets and lengths.
# Returns number of tokens. token_off[i], token_len[i] into line_buf.
let mut token_off: ptr<i32> = 0 as ptr<i32>
let mut token_len: ptr<i32> = 0 as ptr<i32>

function split_tokens(line: ptr<i8>, line_len: i32) -> i32 {
    if token_off == 0 as ptr<i32> {
        token_off = calloc(200, 4) as ptr<i32>
        token_len = calloc(200, 4) as ptr<i32>
    }
    let mut ntok: i32 = 0
    let mut start: i32 = 0
    let mut depth: i32 = 0
    let mut i: i32 = 0
    while i < line_len {
        let ch: i8 = line[i]
        if ch == 44 && depth == 0 {
            token_off[ntok] = start
            token_len[ntok] = i - start
            ntok = ntok + 1
            start = i + 1
        } else {
            if ch == 40 {
                depth = depth + 1
            } else {
                if ch == 41 {
                    depth = depth - 1
                }
            }
        }
        i = i + 1
    }
    token_off[ntok] = start
    token_len[ntok] = line_len - start
    ntok = ntok + 1
    return ntok
}

# Parse integer from substring
function parse_int(line: ptr<i8>, off: i32, len: i32) -> i32 {
    let mut val: i32 = 0
    let mut i: i32 = 0
    while i < len {
        let ch: i8 = line[off + i]
        if ch >= 48 && ch <= 57 {
            val = val * 10 + (ch as i32 - 48)
        }
        i = i + 1
    }
    return val
}

# Parse a puzzle line into grid. Returns n (grid size).
let mut puzzle_n: i32 = 0
let mut puzzle_ngrid: i32 = 0

function parse_puzzle(line: ptr<i8>, line_len: i32) -> void {
    let ntok: i32 = split_tokens(line, line_len)
    puzzle_n = parse_int(line, token_off[0], token_len[0])
    let n: i32 = puzzle_n
    puzzle_ngrid = n * n
    let mut gi: i32 = 0
    while gi < n * n {
        g_type[gi] = CT_X
        g_letter[gi] = 0
        g_h_len[gi] = 0
        g_v_len[gi] = 0
        gi = gi + 1
    }
    let mut ti: i32 = 1
    let mut gidx: i32 = 0
    while ti < ntok {
        let off: i32 = token_off[ti]
        let tlen: i32 = token_len[ti]
        if tlen == 1 {
            let ch: i8 = line[off]
            if ch == 88 {
                g_type[gidx] = CT_X
            } else {
                if ch == 79 {
                    g_type[gidx] = CT_O
                } else {
                    if ch >= 65 && ch <= 74 {
                        g_type[gidx] = CT_L
                        g_letter[gidx] = ch as i32 - 65
                    }
                }
            }
        } else {
            if tlen > 0 {
                let first: i8 = line[off]
                if first == 40 {
                    g_type[gidx] = CT_C
                    # Parse inside parentheses: substr(1, len-2)
                    let inside_off: i32 = off + 1
                    let inside_len: i32 = tlen - 2
                    let mut pos: i32 = 0
                    while pos < inside_len {
                        # Find comma
                        let mut comma: i32 = -1
                        let mut pi: i32 = pos
                        while pi < inside_len {
                            if line[inside_off + pi] == 44 {
                                comma = pi
                                break
                            }
                            pi = pi + 1
                        }
                        let part_len: i32 = 0
                        if comma < 0 {
                            part_len = inside_len - pos
                        } else {
                            part_len = comma - pos
                        }
                        if part_len > 0 {
                            let tag: i8 = line[inside_off + pos]
                            if tag == 104 {
                                # h followed by code
                                g_h_len[gidx] = part_len - 1
                                let mut ci: i32 = 0
                                while ci < part_len - 1 {
                                    g_h_data[gidx * 4 + ci] = line[inside_off + pos + 1 + ci]
                                    ci = ci + 1
                                }
                            } else {
                                if tag == 118 {
                                    g_v_len[gidx] = part_len - 1
                                    let mut ci: i32 = 0
                                    while ci < part_len - 1 {
                                        g_v_data[gidx * 4 + ci] = line[inside_off + pos + 1 + ci]
                                        ci = ci + 1
                                    }
                                }
                            }
                        }
                        if comma < 0 { break }
                        pos = comma + 1
                    }
                }
            }
        }
        gidx = gidx + 1
        ti = ti + 1
    }
}

# Build CSP from parsed grid
function build_csp() -> void {
    init_perms()
    let n: i32 = puzzle_n
    let ngrid: i32 = n * n
    # Initialize letter domains
    let mut i: i32 = 0
    while i < 10 {
        csp_domains[i] = ALL10
        i = i + 1
    }
    # Letters get digits 1-9 only
    let mut gi: i32 = 0
    while gi < ngrid {
        if g_type[gi] == CT_L {
            csp_domains[g_letter[gi]] = csp_domains[g_letter[gi]] & DIGITS_19
        }
        gi = gi + 1
    }
    # Assign cell_to_var
    let mut ocount: i32 = 0
    let mut ci: i32 = 0
    while ci < ngrid {
        cell_to_var[ci] = -1
        ci = ci + 1
    }
    let mut r: i32 = 0
    while r < n {
        let mut c: i32 = 0
        while c < n {
            let idx: i32 = r * n + c
            if g_type[idx] == CT_O {
                cell_to_var[idx] = 10 + ocount
                ocount = ocount + 1
            } else {
                if g_type[idx] == CT_L {
                    cell_to_var[idx] = g_letter[idx]
                }
            }
            c = c + 1
        }
        r = r + 1
    }
    # Open cell domains
    let mut oi: i32 = 0
    while oi < ocount {
        csp_domains[10 + oi] = DIGITS_19
        oi = oi + 1
    }
    csp_nvars = 10 + ocount
    csp_nruns = 0
    cv_pool_next = 0
    inv_pool_next = 0
    inv_idx_pool_next = 0
    sums_pool_next = 0

    # Add runs
    let mut r2: i32 = 0
    while r2 < n {
        let mut c2: i32 = 0
        while c2 < n {
            let idx2: i32 = r2 * n + c2
            if g_type[idx2] == CT_C {
                # Horizontal run
                if g_h_len[idx2] > 0 {
                    let mut cvs_count: i32 = 0
                    let cc_start: i32 = cv_pool_next
                    let mut cc: i32 = c2 + 1
                    while cc < n {
                        let gidx2: i32 = r2 * n + cc
                        if g_type[gidx2] != CT_O && g_type[gidx2] != CT_L { break }
                        cv_pool[cv_pool_next] = cell_to_var[gidx2]
                        cv_pool_next = cv_pool_next + 1
                        cvs_count = cvs_count + 1
                        cc = cc + 1
                    }
                    if cvs_count > 0 {
                        add_run(idx2, 0, cc_start, cvs_count)
                    }
                }
                # Vertical run
                if g_v_len[idx2] > 0 {
                    let mut cvs_count2: i32 = 0
                    let cc_start2: i32 = cv_pool_next
                    let mut rr: i32 = r2 + 1
                    while rr < n {
                        let gidx3: i32 = rr * n + c2
                        if g_type[gidx3] != CT_O && g_type[gidx3] != CT_L { break }
                        cv_pool[cv_pool_next] = cell_to_var[gidx3]
                        cv_pool_next = cv_pool_next + 1
                        cvs_count2 = cvs_count2 + 1
                        rr = rr + 1
                    }
                    if cvs_count2 > 0 {
                        add_run(idx2, 1, cc_start2, cvs_count2)
                    }
                }
            }
            c2 = c2 + 1
        }
        r2 = r2 + 1
    }

    # Build var_to_runs
    let mut vi: i32 = 0
    while vi < csp_nvars {
        v2r_count[vi] = 0
        vi = vi + 1
    }
    let mut ri: i32 = 0
    while ri < csp_nruns {
        let inv_off: i32 = run_inv_off[ri]
        let ic: i32 = run_inv_count[ri]
        let mut j: i32 = 0
        while j < ic {
            let v: i32 = inv_pool[inv_off + j]
            v2r_count[v] = v2r_count[v] + 1
            j = j + 1
        }
        ri = ri + 1
    }
    # Compute offsets
    let mut acc2: i32 = 0
    let mut vi2: i32 = 0
    while vi2 < csp_nvars {
        v2r_off[vi2] = acc2
        acc2 = acc2 + v2r_count[vi2]
        v2r_count[vi2] = 0
        vi2 = vi2 + 1
    }
    # Fill data
    let mut ri2: i32 = 0
    while ri2 < csp_nruns {
        let inv_off2: i32 = run_inv_off[ri2]
        let ic2: i32 = run_inv_count[ri2]
        let mut j2: i32 = 0
        while j2 < ic2 {
            let v2: i32 = inv_pool[inv_off2 + j2]
            v2r_data[v2r_off[v2] + v2r_count[v2]] = ri2
            v2r_count[v2] = v2r_count[v2] + 1
            j2 = j2 + 1
        }
        ri2 = ri2 + 1
    }
}

# Add a run constraint. gidx = grid index, hv = 0 for h, 1 for v.
function add_run(gidx: i32, hv: i32, cv_start: i32, cv_count: i32) -> void {
    let ri: i32 = csp_nruns
    csp_nruns = csp_nruns + 1
    # cell_vars
    run_cv_off[ri] = cv_start
    run_cv_count[ri] = cv_count
    run_length[ri] = cv_count
    # sum_letters from code
    let code_off: i32 = 0
    let code_len: i32 = 0
    if hv == 0 {
        code_len = g_h_len[gidx]
        code_off = gidx * 4
    } else {
        code_len = g_v_len[gidx]
        code_off = gidx * 4
    }
    if code_len == 1 {
        run_nsl[ri] = 1
        run_sl0[ri] = g_h_data[code_off] as i32 - 65
        if hv == 1 {
            run_sl0[ri] = g_v_data[code_off] as i32 - 65
        }
        run_sl1[ri] = 0
    } else {
        run_nsl[ri] = 2
        if hv == 0 {
            run_sl0[ri] = g_h_data[code_off] as i32 - 65
            run_sl1[ri] = g_h_data[code_off + 1] as i32 - 65
        } else {
            run_sl0[ri] = g_v_data[code_off] as i32 - 65
            run_sl1[ri] = g_v_data[code_off + 1] as i32 - 65
        }
    }
    # sums_list: all S where perms_count[L][S] > 0
    let sums_start: i32 = sums_pool_next
    let mut scount: i32 = 0
    let L: i32 = run_length[ri]
    let mut s: i32 = 1
    while s <= 45 {
        let pidx: i32 = L * 46 + s
        if perms_count[pidx] > 0 {
            sums_pool[sums_pool_next] = s
            sums_pool_next = sums_pool_next + 1
            scount = scount + 1
        }
        s = s + 1
    }
    run_sums_off[ri] = sums_start
    run_sums_count[ri] = scount
    # involved = cell_vars + sum_letters, sorted, unique
    let inv_start: i32 = inv_pool_next
    let mut icount: i32 = 0
    let mut ci: i32 = 0
    while ci < cv_count {
        inv_pool[inv_pool_next] = cv_pool[cv_start + ci]
        inv_pool_next = inv_pool_next + 1
        icount = icount + 1
        ci = ci + 1
    }
    inv_pool[inv_pool_next] = run_sl0[ri]
    inv_pool_next = inv_pool_next + 1
    icount = icount + 1
    if run_nsl[ri] == 2 {
        inv_pool[inv_pool_next] = run_sl1[ri]
        inv_pool_next = inv_pool_next + 1
        icount = icount + 1
    }
    sort_i32(inv_pool + inv_start, icount)
    icount = unique_i32(inv_pool + inv_start, icount)
    run_inv_off[ri] = inv_start
    run_inv_count[ri] = icount
    # inv_index: for each involved var, its index
    let inv_idx_start: i32 = inv_idx_pool_next
    let mut ii: i32 = 0
    while ii < icount {
        inv_idx_pool[inv_idx_pool_next] = ii
        inv_idx_pool_next = inv_idx_pool_next + 1
        ii = ii + 1
    }
    run_inv_index[ri] = inv_idx_start
    # Wait, inv_index is a map from var -> index. We need to look up by var.
    # Store as: for each involved var at position j, inv_index[j] = j.
    # Actually the C++ code uses inv_index[var] = position. Since involved is sorted,
    # we can binary search. Let's store involved and do binary search instead.
    # dup_cells
    let mut tmp_arr: ptr<i32> = calloc(cv_count, 4) as ptr<i32>
    let mut di: i32 = 0
    while di < cv_count {
        tmp_arr[di] = cv_pool[cv_start + di]
        di = di + 1
    }
    sort_i32(tmp_arr, cv_count)
    let mut dup: i32 = 0
    let mut di2: i32 = 1
    while di2 < cv_count {
        if tmp_arr[di2] == tmp_arr[di2 - 1] {
            dup = 1
            break
        }
        di2 = di2 + 1
    }
    run_dup[ri] = dup
    free(tmp_arr)
    # sum_same
    if run_nsl[ri] == 2 && run_sl0[ri] == run_sl1[ri] {
        run_ssame[ri] = 1
    } else {
        run_ssame[ri] = 0
    }
}

# Binary search for var in involved list of run ri. Returns index or -1.
function inv_index_lookup(ri: i32, v: i32) -> i32 {
    let off: i32 = run_inv_off[ri]
    let n: i32 = run_inv_count[ri]
    let mut lo: i32 = 0
    let mut hi: i32 = n - 1
    while lo <= hi {
        let mid: i32 = (lo + hi) / 2
        let val: i32 = inv_pool[off + mid]
        if val == v { return mid }
        if val < v {
            lo = mid + 1
        } else {
            hi = mid - 1
        }
    }
    return -1
}

# enforce_all_diff: returns 1 if contradiction, 0 if ok. Fills changed list.
let mut ad_changed: ptr<i32> = 0 as ptr<i32>
let mut ad_changed_n: i32 = 0

let mut ad_seen: ptr<i32> = 0 as ptr<i32>

function enforce_all_diff(dom: ptr<i32>) -> i32 {
    let mut fixed_mask: i32 = 0
    if ad_seen == 0 as ptr<i32> {
        ad_seen = calloc(10, 4) as ptr<i32>
    }
    let mut i: i32 = 0
    while i < 10 {
        ad_seen[i] = 0
        i = i + 1
    }
    i = 0
    while i < 10 {
        if popcount(dom[i]) == 1 {
            let d: i32 = ctz(dom[i])
            if ad_seen[d] == 1 {
                return 1
            }
            ad_seen[d] = 1
            fixed_mask = fixed_mask | (1 << d)
        }
        i = i + 1
    }
    if ad_changed == 0 as ptr<i32> {
        ad_changed = calloc(20, 4) as ptr<i32>
    }
    ad_changed_n = 0
    i = 0
    while i < 10 {
        if popcount(dom[i]) > 1 {
            let neu: i32 = dom[i] & (0 - 1 - fixed_mask)
            if neu == 0 { return 1 }
            if neu != dom[i] {
                dom[i] = neu
                ad_changed[ad_changed_n] = i
                ad_changed_n = ad_changed_n + 1
            }
        }
        i = i + 1
    }
    return 0
}

# process_run: returns 1 if contradiction, 0 if ok. Fills pr_changed.
let mut pr_changed: ptr<i32> = 0 as ptr<i32>
let mut pr_changed_n: i32 = 0
let mut pr_support: ptr<i32> = 0 as ptr<i32>

function process_run(ri: i32, dom: ptr<i32>) -> i32 {
    if run_dup[ri] == 1 { return 1 }
    let ninv: i32 = run_inv_count[ri]
    if pr_support == 0 as ptr<i32> {
        pr_support = calloc(40, 4) as ptr<i32>
    }
    if pr_changed == 0 as ptr<i32> {
        pr_changed = calloc(40, 4) as ptr<i32>
    }
    let mut i: i32 = 0
    while i < ninv {
        pr_support[i] = 0
        i = i + 1
    }
    let L: i32 = run_length[ri]
    let cv_off: i32 = run_cv_off[ri]
    let sums_off: i32 = run_sums_off[ri]
    let sums_count: i32 = run_sums_count[ri]
    if run_nsl[ri] == 1 {
        let l: i32 = run_sl0[ri]
        let li: i32 = inv_index_lookup(ri, l)
        let doml: i32 = dom[l]
        let mut si: i32 = 0
        while si < sums_count {
            let S: i32 = sums_pool[sums_off + si]
            if S <= 9 {
                if (doml & (1 << S)) != 0 {
                    let pidx: i32 = L * 46 + S
                    let mut pk: i32 = 0
                    while pk < perms_count[pidx] {
                        get_perm(L, S, pk)
                        # Check all cells compatible
                        let mut ok: i32 = 1
                        let mut ci: i32 = 0
                        while ci < L {
                            let cv: i32 = cv_pool[cv_off + ci]
                            if (dom[cv] & (1 << perm_buf[ci])) == 0 {
                                ok = 0
                                break
                            }
                            ci = ci + 1
                        }
                        if ok == 1 {
                            # Mark support
                            let mut ci2: i32 = 0
                            while ci2 < L {
                                let cv2: i32 = cv_pool[cv_off + ci2]
                                let idx2: i32 = inv_index_lookup(ri, cv2)
                                pr_support[idx2] = pr_support[idx2] | (1 << perm_buf[ci2])
                                ci2 = ci2 + 1
                            }
                            pr_support[li] = pr_support[li] | (1 << S)
                        }
                        pk = pk + 1
                    }
                }
            }
            si = si + 1
        }
    } else {
        let a: i32 = run_sl0[ri]
        let b: i32 = run_sl1[ri]
        let ai: i32 = inv_index_lookup(ri, a)
        let bi: i32 = inv_index_lookup(ri, b)
        if run_ssame[ri] == 1 {
            let doma: i32 = dom[a]
            let mut si: i32 = 0
            while si < sums_count {
                let S: i32 = sums_pool[sums_off + si]
                if S >= 10 {
                    let t: i32 = S / 10
                    let o: i32 = S % 10
                    if t == o {
                        if (doma & (1 << t)) != 0 {
                            let pidx: i32 = L * 46 + S
                            let mut pk: i32 = 0
                            while pk < perms_count[pidx] {
                                get_perm(L, S, pk)
                                if ri == 0 && S == 22 && pk < 3 {
                                    printf("  S=22 pk=%d perm: %d %d %d %d\n", pk, perm_buf[0], perm_buf[1], perm_buf[2], perm_buf[3])
                                }
                                let mut ok: i32 = 1
                                let mut ci: i32 = 0
                                while ci < L {
                                    let cv: i32 = cv_pool[cv_off + ci]
                                    if (dom[cv] & (1 << perm_buf[ci])) == 0 {
                                        ok = 0
                                        break
                                    }
                                    ci = ci + 1
                                }
                                if ok == 1 {
                                    let mut ci2: i32 = 0
                                    while ci2 < L {
                                        let cv2: i32 = cv_pool[cv_off + ci2]
                                        let idx2: i32 = inv_index_lookup(ri, cv2)
                                        pr_support[idx2] = pr_support[idx2] | (1 << perm_buf[ci2])
                                        ci2 = ci2 + 1
                                    }
                                    pr_support[ai] = pr_support[ai] | (1 << t)
                                }
                                pk = pk + 1
                            }
                        }
                    }
                }
                si = si + 1
            }
        } else {
            let doma: i32 = dom[a]
            let domb: i32 = dom[b]
            let mut si: i32 = 0
            while si < sums_count {
                let S: i32 = sums_pool[sums_off + si]
                if S >= 10 {
                    let t: i32 = S / 10
                    let o: i32 = S % 10
                    if t != o {
                        if (doma & (1 << t)) != 0 && (domb & (1 << o)) != 0 {
                            let pidx: i32 = L * 46 + S
                            let mut pk: i32 = 0
                            while pk < perms_count[pidx] {
                                get_perm(L, S, pk)
                                let mut ok: i32 = 1
                                let mut ci: i32 = 0
                                while ci < L {
                                    let cv: i32 = cv_pool[cv_off + ci]
                                    if (dom[cv] & (1 << perm_buf[ci])) == 0 {
                                        ok = 0
                                        break
                                    }
                                    ci = ci + 1
                                }
                                if ok == 1 {
                                    let mut ci2: i32 = 0
                                    while ci2 < L {
                                        let cv2: i32 = cv_pool[cv_off + ci2]
                                        let idx2: i32 = inv_index_lookup(ri, cv2)
                                        pr_support[idx2] = pr_support[idx2] | (1 << perm_buf[ci2])
                                        ci2 = ci2 + 1
                                    }
                                    pr_support[ai] = pr_support[ai] | (1 << t)
                                    pr_support[bi] = pr_support[bi] | (1 << o)
                                }
                                pk = pk + 1
                            }
                        }
                    }
                }
                si = si + 1
            }
        }
    }

    # Apply support
    pr_changed_n = 0
    let mut i2: i32 = 0
    while i2 < ninv {
        let v: i32 = inv_pool[run_inv_off[ri] + i2]
        let sup: i32 = pr_support[i2]
        if sup == 0 { return 1 }
        let neu: i32 = dom[v] & sup
        if neu == 0 { return 1 }
        if neu != dom[v] {
            dom[v] = neu
            pr_changed[pr_changed_n] = v
            pr_changed_n = pr_changed_n + 1
        }
        i2 = i2 + 1
    }
    return 0
}

# Propagation queue
let mut prop_q: ptr<i32> = 0 as ptr<i32>
let mut prop_inq: ptr<i32> = 0 as ptr<i32>

function propagate(dom: ptr<i32>) -> i32 {
    if prop_q == 0 as ptr<i32> {
        prop_q = calloc(MAX_RUNS + 100, 4) as ptr<i32>
        prop_inq = calloc(MAX_RUNS + 100, 4) as ptr<i32>
    }
    let mut qhead: i32 = 0
    let mut qtail: i32 = 0
    let mut i: i32 = 0
    while i < csp_nruns {
        prop_inq[i] = 1
        prop_q[qtail] = i
        qtail = qtail + 1
        i = i + 1
    }
    while 1 == 1 {
        let fail: i32 = enforce_all_diff(dom)
        if fail == 1 { return 0 }
        let mut ci: i32 = 0
        while ci < ad_changed_n {
            let l: i32 = ad_changed[ci]
            let mut ri: i32 = 0
            while ri < v2r_count[l] {
                let ridx: i32 = v2r_data[v2r_off[l] + ri]
                if prop_inq[ridx] == 0 {
                    prop_q[qtail] = ridx
                    qtail = qtail + 1
                    prop_inq[ridx] = 1
                }
                ri = ri + 1
            }
            ci = ci + 1
        }
        if qhead >= qtail { return 1 }
        let ri2: i32 = prop_q[qhead]
        qhead = qhead + 1
        prop_inq[ri2] = 0
        let fail2: i32 = process_run(ri2, dom)
        if fail2 == 1 { return 0 }
        let mut vi: i32 = 0
        while vi < pr_changed_n {
            let v: i32 = pr_changed[vi]
            let mut rj: i32 = 0
            while rj < v2r_count[v] {
                let ridx2: i32 = v2r_data[v2r_off[v] + rj]
                if prop_inq[ridx2] == 0 {
                    prop_q[qtail] = ridx2
                    qtail = qtail + 1
                    prop_inq[ridx2] = 1
                }
                rj = rj + 1
            }
            vi = vi + 1
        }
    }
    return 1
}

function select_var(dom: ptr<i32>) -> i32 {
    let mut best: i32 = -1
    let mut best_c: i32 = 999
    let mut i: i32 = 0
    while i < csp_nvars {
        let c: i32 = popcount(dom[i])
        if c > 1 {
            if c < best_c {
                best_c = c
                best = i
                if c == 2 { break }
            }
        }
        i = i + 1
    }
    return best
}

# Recursive solve. dom is a copy. sol is filled on success.
let mut sol_buf: ptr<i32> = 0 as ptr<i32>

function solve_rec(dom: ptr<i32>) -> i32 {
    let fail: i32 = propagate(dom)
    if fail == 0 { return 0 }
    let v: i32 = select_var(dom)
    if v < 0 {
        # Solution found, copy to sol_buf
        let mut i: i32 = 0
        while i < csp_nvars {
            sol_buf[i] = dom[i]
            i = i + 1
        }
        return 1
    }
    let mask: i32 = dom[v]
    let mut d: i32 = 0
    while d < 10 {
        if (mask & (1 << d)) != 0 {
            let dom2: ptr<i32> = calloc(csp_nvars, 4) as ptr<i32>
            let mut i: i32 = 0
            while i < csp_nvars {
                dom2[i] = dom[i]
                i = i + 1
            }
            dom2[v] = 1 << d
            let res: i32 = solve_rec(dom2)
            free(dom2)
            if res == 1 { return 1 }
        }
        d = d + 1
    }
    return 0
}

function mapping_to_number(sol: ptr<i32>) -> i64 {
    let mut num: i64 = 0
    let mut i: i32 = 0
    while i < 10 {
        let d: i32 = ctz(sol[i])
        num = num * 10 + (d as i64)
        i = i + 1
    }
    return num
}

function solve_puzzle(line: ptr<i8>, line_len: i32) -> i64 {
    parse_puzzle(line, line_len)
    build_csp()
    if sol_buf == 0 as ptr<i32> {
        sol_buf = calloc(MAX_VARS, 4) as ptr<i32>
    }
    let res: i32 = solve_rec(csp_domains)
    if res == 0 {
        abort()
    }
    return mapping_to_number(sol_buf)
}

function main() -> i32 {
    init_globals()
    let f: ptr<void> = fopen("data/p424.txt", "r")
    if f == 0 as ptr<void> {
        printf("cannot open data/p424.txt\n")
        return 1
    }
    let mut total: i64 = 0
    while 1 == 1 {
        let res: ptr<i8> = fgets(line_buf, MAX_LINE, f)
        if res == 0 as ptr<i8> { break }
        # Find line length, strip newline/CR
        let mut len: i32 = 0
        while len < MAX_LINE {
            let ch: i8 = line_buf[len]
            if ch == 0 { break }
            if ch == 10 { break }
            len = len + 1
        }
        if len > 0 {
            if line_buf[len - 1] == 13 {
                len = len - 1
            }
        }
        if len > 0 {
            total = total + solve_puzzle(line_buf, len)
        }
    }
    fclose(f)
    printf("%lld\n", total)
    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 init_globals(void);
int32_t popcount_i32(int32_t x);
int32_t ctz_i32(int32_t x);
void sort_i32_ptr_i32_i32(int32_t* arr, int32_t n);
int32_t unique_i32_ptr_i32_i32(int32_t* arr, int32_t n);
int32_t next_perm_ptr_i32_i32(int32_t* arr, int32_t n);
void init_perms(void);
void get_perm_i32_i32_i32(int32_t L, int32_t S, int32_t k);
int32_t split_tokens_ptr_i8_i32(int8_t* line, int32_t line_len);
int32_t parse_int_ptr_i8_i32_i32(int8_t* line, int32_t off, int32_t len);
void parse_puzzle_ptr_i8_i32(int8_t* line, int32_t line_len);
void build_csp(void);
void add_run_i32_i32_i32_i32(int32_t gidx, int32_t hv, int32_t cv_start, int32_t cv_count);
int32_t inv_index_lookup_i32_i32(int32_t ri, int32_t v);
int32_t enforce_all_diff_ptr_i32(int32_t* dom);
int32_t process_run_i32_ptr_i32(int32_t ri, int32_t* dom);
int32_t propagate_ptr_i32(int32_t* dom);
int32_t select_var_ptr_i32(int32_t* dom);
int32_t solve_rec_ptr_i32(int32_t* dom);
int64_t mapping_to_number_ptr_i32(int32_t* sol);
int64_t solve_puzzle_ptr_i8_i32(int8_t* line, int32_t line_len);
int32_t main(void);

static const int32_t ALL10 = 1023;
static const int32_t DIGITS_19 = 1022;
static const int32_t MAX_GRID = 400;
static const int32_t MAX_RUNS = 200;
static const int32_t MAX_VARS = 400;
static const int32_t MAX_PERMS_TOTAL = 700000;
static const int32_t MAX_LINE = 2048;
static const int32_t CT_X = 0;
static const int32_t CT_O = 1;
static const int32_t CT_L = 2;
static const int32_t CT_C = 3;

/* Module statics */
static int32_t* perms_count = ((int32_t*)(0));
static int32_t* perms_offset = ((int32_t*)(0));
static int32_t* perms_data = ((int32_t*)(0));
static int32_t perms_total = 0;
static int32_t perms_init_done = 0;
static int32_t* g_type = ((int32_t*)(0));
static int32_t* g_letter = ((int32_t*)(0));
static int32_t* g_h_len = ((int32_t*)(0));
static int8_t* g_h_data = ((int8_t*)(0));
static int32_t* g_v_len = ((int32_t*)(0));
static int8_t* g_v_data = ((int8_t*)(0));
static int32_t* cell_to_var = ((int32_t*)(0));
static int32_t* csp_domains = ((int32_t*)(0));
static int32_t csp_nvars = 0;
static int32_t csp_nruns = 0;
static int32_t* run_cv_off = ((int32_t*)(0));
static int32_t* run_cv_data = ((int32_t*)(0));
static int32_t* run_cv_count = ((int32_t*)(0));
static int32_t* run_sl0 = ((int32_t*)(0));
static int32_t* run_sl1 = ((int32_t*)(0));
static int32_t* run_nsl = ((int32_t*)(0));
static int32_t* run_inv_off = ((int32_t*)(0));
static int32_t* run_inv_data = ((int32_t*)(0));
static int32_t* run_inv_count = ((int32_t*)(0));
static int32_t* run_inv_index = ((int32_t*)(0));
static int32_t* run_length = ((int32_t*)(0));
static int32_t* run_sums_off = ((int32_t*)(0));
static int32_t* run_sums_data = ((int32_t*)(0));
static int32_t* run_sums_count = ((int32_t*)(0));
static int32_t* run_dup = ((int32_t*)(0));
static int32_t* run_ssame = ((int32_t*)(0));
static int32_t* v2r_off = ((int32_t*)(0));
static int32_t* v2r_data = ((int32_t*)(0));
static int32_t* v2r_count = ((int32_t*)(0));
static int32_t* cv_pool = ((int32_t*)(0));
static int32_t cv_pool_next = 0;
static int32_t* inv_pool = ((int32_t*)(0));
static int32_t inv_pool_next = 0;
static int32_t* inv_idx_pool = ((int32_t*)(0));
static int32_t inv_idx_pool_next = 0;
static int32_t* sums_pool = ((int32_t*)(0));
static int32_t sums_pool_next = 0;
static int32_t* v2r_pool = ((int32_t*)(0));
static int32_t v2r_pool_next = 0;
static int8_t* line_buf = ((int8_t*)(0));
static int32_t* perm_buf = ((int32_t*)(0));
static int32_t* token_off = ((int32_t*)(0));
static int32_t* token_len = ((int32_t*)(0));
static int32_t puzzle_n = 0;
static int32_t puzzle_ngrid = 0;
static int32_t* ad_changed = ((int32_t*)(0));
static int32_t ad_changed_n = 0;
static int32_t* ad_seen = ((int32_t*)(0));
static int32_t* pr_changed = ((int32_t*)(0));
static int32_t pr_changed_n = 0;
static int32_t* pr_support = ((int32_t*)(0));
static int32_t* prop_q = ((int32_t*)(0));
static int32_t* prop_inq = ((int32_t*)(0));
static int32_t* sol_buf = ((int32_t*)(0));









void init_globals(void) {
    perms_count = ((int32_t*)(calloc((7 * 46), 4)));
    perms_offset = ((int32_t*)(calloc((7 * 46), 4)));
    perms_data = ((int32_t*)(calloc(MAX_PERMS_TOTAL, 4)));
    g_type = ((int32_t*)(calloc(MAX_GRID, 4)));
    g_letter = ((int32_t*)(calloc(MAX_GRID, 4)));
    g_h_len = ((int32_t*)(calloc(MAX_GRID, 4)));
    g_h_data = ((int8_t*)(calloc((MAX_GRID * 4), 1)));
    g_v_len = ((int32_t*)(calloc(MAX_GRID, 4)));
    g_v_data = ((int8_t*)(calloc((MAX_GRID * 4), 1)));
    cell_to_var = ((int32_t*)(calloc(MAX_GRID, 4)));
    csp_domains = ((int32_t*)(calloc(MAX_VARS, 4)));
    run_cv_off = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_cv_data = ((int32_t*)(calloc((MAX_RUNS * 20), 4)));
    run_cv_count = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_sl0 = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_sl1 = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_nsl = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_inv_off = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_inv_data = ((int32_t*)(calloc((MAX_RUNS * 30), 4)));
    run_inv_count = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_inv_index = ((int32_t*)(calloc((MAX_RUNS * 30), 4)));
    run_length = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_sums_off = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_sums_data = ((int32_t*)(calloc((MAX_RUNS * 50), 4)));
    run_sums_count = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_dup = ((int32_t*)(calloc(MAX_RUNS, 4)));
    run_ssame = ((int32_t*)(calloc(MAX_RUNS, 4)));
    v2r_off = ((int32_t*)(calloc(MAX_VARS, 4)));
    v2r_data = ((int32_t*)(calloc((MAX_VARS * 50), 4)));
    v2r_count = ((int32_t*)(calloc(MAX_VARS, 4)));
    cv_pool = ((int32_t*)(calloc(5000, 4)));
    inv_pool = ((int32_t*)(calloc(5000, 4)));
    inv_idx_pool = ((int32_t*)(calloc(5000, 4)));
    sums_pool = ((int32_t*)(calloc(10000, 4)));
    v2r_pool = ((int32_t*)(calloc(20000, 4)));
    line_buf = ((int8_t*)(calloc(MAX_LINE, 1)));
    perm_buf = ((int32_t*)(calloc(10, 4)));
}

int32_t popcount_i32(int32_t x) {
    int32_t c = 0;
    int32_t v = x;
    while (v > 0) {
        c = (c + 1);
        v = (v & (v - 1));
    }
    return c;
}

int32_t ctz_i32(int32_t x) {
    if (x == 0) {
        return 32;
    }
    int32_t n = 0;
    int32_t v = x;
    while ((v & 1) == 0) {
        n = (n + 1);
        v = FLOW_CHECKED_SHR((v), (1));
    }
    return n;
}

void sort_i32_ptr_i32_i32(int32_t* arr, int32_t n) {
    int32_t i = 1;
    while (i < n) {
        int32_t key = arr[i];
        int32_t j = (i - 1);
        while (j >= 0) {
            if (arr[j] > key) {
                arr[(j + 1)] = arr[j];
                j = (j - 1);
            } else {
                break;
            }
        }
        arr[(j + 1)] = key;
        i = (i + 1);
    }
}

int32_t unique_i32_ptr_i32_i32(int32_t* arr, int32_t n) {
    if (n <= 1) {
        return n;
    }
    int32_t w = 1;
    int32_t r = 1;
    while (r < n) {
        if (arr[r] != arr[(r - 1)]) {
            arr[w] = arr[r];
            w = (w + 1);
        }
        r = (r + 1);
    }
    return w;
}

int32_t next_perm_ptr_i32_i32(int32_t* arr, int32_t n) {
    if (n <= 1) {
        return 0;
    }
    int32_t i = (n - 2);
    while (i >= 0) {
        if (arr[i] < arr[(i + 1)]) {
            break;
        }
        i = (i - 1);
    }
    if (i < 0) {
        return 0;
    }
    int32_t j = (n - 1);
    while (j > i) {
        if (arr[j] > arr[i]) {
            break;
        }
        j = (j - 1);
    }
    int32_t tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    int32_t a = (i + 1);
    int32_t b = (n - 1);
    while (a < b) {
        int32_t t2 = arr[a];
        arr[a] = arr[b];
        arr[b] = t2;
        a = (a + 1);
        b = (b - 1);
    }
    return 1;
}

void init_perms(void) {
    if (perms_init_done == 1) {
        return;
    }
    perms_init_done = 1;
    int32_t* digits = (int32_t*)(perm_buf);
    int32_t d = 0;
    while (d < 9) {
        digits[d] = (d + 1);
        d = (d + 1);
    }
    int32_t* chosen = (int32_t*)(((int32_t*)(calloc(10, 4))));
    int32_t* mask = (int32_t*)(((int32_t*)(calloc(10, 4))));
    int32_t L = 1;
    while (L <= 6) {
        int32_t mi = 0;
        while (mi < 9) {
            if (mi < (9 - L)) {
                mask[mi] = 0;
            } else {
                mask[mi] = 1;
            }
            mi = (mi + 1);
        }
        int32_t first = 1;
        while ((first == 1 || next_perm_ptr_i32_i32(mask, 9) == 1)) {
            first = 0;
            int32_t ci = 0;
            int32_t di = 0;
            while (di < 9) {
                if (mask[di] == 1) {
                    chosen[ci] = digits[di];
                    ci = (ci + 1);
                }
                di = (di + 1);
            }
            sort_i32_ptr_i32_i32(chosen, L);
            int32_t first2 = 1;
            while ((first2 == 1 || next_perm_ptr_i32_i32(chosen, L) == 1)) {
                first2 = 0;
                int32_t s = 0;
                int32_t pi = 0;
                while (pi < L) {
                    s = (s + chosen[pi]);
                    pi = (pi + 1);
                }
                int32_t idx = ((L * 46) + s);
                perms_count[idx] = (perms_count[idx] + 1);
                perms_total = (perms_total + 1);
            }
        }
        L = (L + 1);
    }
    int32_t acc = 0;
    int32_t idx2 = 0;
    while (idx2 < (7 * 46)) {
        perms_offset[idx2] = acc;
        int32_t curL = FLOW_CHECKED_DIV((idx2), (46));
        acc = (acc + (perms_count[idx2] * curL));
        idx2 = (idx2 + 1);
    }
    int32_t* cursor = (int32_t*)(((int32_t*)(calloc((7 * 46), 4))));
    idx2 = 0;
    while (idx2 < (7 * 46)) {
        cursor[idx2] = perms_offset[idx2];
        idx2 = (idx2 + 1);
    }
    L = 1;
    while (L <= 6) {
        int32_t mi = 0;
        while (mi < 9) {
            if (mi < (9 - L)) {
                mask[mi] = 0;
            } else {
                mask[mi] = 1;
            }
            mi = (mi + 1);
        }
        int32_t first = 1;
        while ((first == 1 || next_perm_ptr_i32_i32(mask, 9) == 1)) {
            first = 0;
            int32_t ci = 0;
            int32_t di = 0;
            while (di < 9) {
                if (mask[di] == 1) {
                    chosen[ci] = digits[di];
                    ci = (ci + 1);
                }
                di = (di + 1);
            }
            sort_i32_ptr_i32_i32(chosen, L);
            int32_t first2 = 1;
            while ((first2 == 1 || next_perm_ptr_i32_i32(chosen, L) == 1)) {
                first2 = 0;
                int32_t s = 0;
                int32_t pi = 0;
                while (pi < L) {
                    s = (s + chosen[pi]);
                    pi = (pi + 1);
                }
                int32_t idx = ((L * 46) + s);
                int32_t off = cursor[idx];
                int32_t pi2 = 0;
                while (pi2 < L) {
                    perms_data[(off + pi2)] = chosen[pi2];
                    pi2 = (pi2 + 1);
                }
                cursor[idx] = (off + L);
            }
        }
        L = (L + 1);
    }
    free(cursor);
    free(chosen);
    free(mask);
}

void get_perm_i32_i32_i32(int32_t L, int32_t S, int32_t k) {
    int32_t idx = ((L * 46) + S);
    int32_t off = (perms_offset[idx] + (k * L));
    int32_t i = 0;
    while (i < L) {
        perm_buf[i] = perms_data[(off + i)];
        i = (i + 1);
    }
}

int32_t split_tokens_ptr_i8_i32(int8_t* line, int32_t line_len) {
    if (token_off == ((int32_t*)(0))) {
        token_off = ((int32_t*)(calloc(200, 4)));
        token_len = ((int32_t*)(calloc(200, 4)));
    }
    int32_t ntok = 0;
    int32_t start = 0;
    int32_t depth = 0;
    int32_t i = 0;
    while (i < line_len) {
        int8_t ch = line[i];
        if ((ch == 44 && depth == 0)) {
            token_off[ntok] = start;
            token_len[ntok] = (i - start);
            ntok = (ntok + 1);
            start = (i + 1);
        } else {
            if (ch == 40) {
                depth = (depth + 1);
            } else {
                if (ch == 41) {
                    depth = (depth - 1);
                }
            }
        }
        i = (i + 1);
    }
    token_off[ntok] = start;
    token_len[ntok] = (line_len - start);
    ntok = (ntok + 1);
    return ntok;
}

int32_t parse_int_ptr_i8_i32_i32(int8_t* line, int32_t off, int32_t len) {
    int32_t val = 0;
    int32_t i = 0;
    while (i < len) {
        int8_t ch = line[(off + i)];
        if ((ch >= 48 && ch <= 57)) {
            val = ((val * 10) + (((int32_t)(ch)) - 48));
        }
        i = (i + 1);
    }
    return val;
}

void parse_puzzle_ptr_i8_i32(int8_t* line, int32_t line_len) {
    int32_t ntok = split_tokens_ptr_i8_i32(line, line_len);
    puzzle_n = parse_int_ptr_i8_i32_i32(line, token_off[0], token_len[0]);
    int32_t n = puzzle_n;
    puzzle_ngrid = (n * n);
    int32_t gi = 0;
    while (gi < (n * n)) {
        g_type[gi] = CT_X;
        g_letter[gi] = 0;
        g_h_len[gi] = 0;
        g_v_len[gi] = 0;
        gi = (gi + 1);
    }
    int32_t ti = 1;
    int32_t gidx = 0;
    while (ti < ntok) {
        int32_t off = token_off[ti];
        int32_t tlen = token_len[ti];
        if (tlen == 1) {
            int8_t ch = line[off];
            if (ch == 88) {
                g_type[gidx] = CT_X;
            } else {
                if (ch == 79) {
                    g_type[gidx] = CT_O;
                } else {
                    if ((ch >= 65 && ch <= 74)) {
                        g_type[gidx] = CT_L;
                        g_letter[gidx] = (((int32_t)(ch)) - 65);
                    }
                }
            }
        } else {
            if (tlen > 0) {
                int8_t first = line[off];
                if (first == 40) {
                    g_type[gidx] = CT_C;
                    int32_t inside_off = (off + 1);
                    int32_t inside_len = (tlen - 2);
                    int32_t pos = 0;
                    while (pos < inside_len) {
                        int32_t comma = (-1);
                        int32_t pi = pos;
                        while (pi < inside_len) {
                            if (line[(inside_off + pi)] == 44) {
                                comma = pi;
                                break;
                            }
                            pi = (pi + 1);
                        }
                        int32_t part_len = 0;
                        if (comma < 0) {
                            part_len = (inside_len - pos);
                        } else {
                            part_len = (comma - pos);
                        }
                        if (part_len > 0) {
                            int8_t tag = line[(inside_off + pos)];
                            if (tag == 104) {
                                g_h_len[gidx] = (part_len - 1);
                                int32_t ci = 0;
                                while (ci < (part_len - 1)) {
                                    g_h_data[((gidx * 4) + ci)] = line[(((inside_off + pos) + 1) + ci)];
                                    ci = (ci + 1);
                                }
                            } else {
                                if (tag == 118) {
                                    g_v_len[gidx] = (part_len - 1);
                                    int32_t ci = 0;
                                    while (ci < (part_len - 1)) {
                                        g_v_data[((gidx * 4) + ci)] = line[(((inside_off + pos) + 1) + ci)];
                                        ci = (ci + 1);
                                    }
                                }
                            }
                        }
                        if (comma < 0) {
                            break;
                        }
                        pos = (comma + 1);
                    }
                }
            }
        }
        gidx = (gidx + 1);
        ti = (ti + 1);
    }
}

void build_csp(void) {
    init_perms();
    int32_t n = puzzle_n;
    int32_t ngrid = (n * n);
    int32_t i = 0;
    while (i < 10) {
        csp_domains[i] = ALL10;
        i = (i + 1);
    }
    int32_t gi = 0;
    while (gi < ngrid) {
        if (g_type[gi] == CT_L) {
            csp_domains[g_letter[gi]] = (csp_domains[g_letter[gi]] & DIGITS_19);
        }
        gi = (gi + 1);
    }
    int32_t ocount = 0;
    int32_t ci = 0;
    while (ci < ngrid) {
        cell_to_var[ci] = (-1);
        ci = (ci + 1);
    }
    int32_t r = 0;
    while (r < n) {
        int32_t c = 0;
        while (c < n) {
            int32_t idx = ((r * n) + c);
            if (g_type[idx] == CT_O) {
                cell_to_var[idx] = (10 + ocount);
                ocount = (ocount + 1);
            } else {
                if (g_type[idx] == CT_L) {
                    cell_to_var[idx] = g_letter[idx];
                }
            }
            c = (c + 1);
        }
        r = (r + 1);
    }
    int32_t oi = 0;
    while (oi < ocount) {
        csp_domains[(10 + oi)] = DIGITS_19;
        oi = (oi + 1);
    }
    csp_nvars = (10 + ocount);
    csp_nruns = 0;
    cv_pool_next = 0;
    inv_pool_next = 0;
    inv_idx_pool_next = 0;
    sums_pool_next = 0;
    int32_t r2 = 0;
    while (r2 < n) {
        int32_t c2 = 0;
        while (c2 < n) {
            int32_t idx2 = ((r2 * n) + c2);
            if (g_type[idx2] == CT_C) {
                if (g_h_len[idx2] > 0) {
                    int32_t cvs_count = 0;
                    int32_t cc_start = cv_pool_next;
                    int32_t cc = (c2 + 1);
                    while (cc < n) {
                        int32_t gidx2 = ((r2 * n) + cc);
                        if ((g_type[gidx2] != CT_O && g_type[gidx2] != CT_L)) {
                            break;
                        }
                        cv_pool[cv_pool_next] = cell_to_var[gidx2];
                        cv_pool_next = (cv_pool_next + 1);
                        cvs_count = (cvs_count + 1);
                        cc = (cc + 1);
                    }
                    if (cvs_count > 0) {
                        add_run_i32_i32_i32_i32(idx2, 0, cc_start, cvs_count);
                    }
                }
                if (g_v_len[idx2] > 0) {
                    int32_t cvs_count2 = 0;
                    int32_t cc_start2 = cv_pool_next;
                    int32_t rr = (r2 + 1);
                    while (rr < n) {
                        int32_t gidx3 = ((rr * n) + c2);
                        if ((g_type[gidx3] != CT_O && g_type[gidx3] != CT_L)) {
                            break;
                        }
                        cv_pool[cv_pool_next] = cell_to_var[gidx3];
                        cv_pool_next = (cv_pool_next + 1);
                        cvs_count2 = (cvs_count2 + 1);
                        rr = (rr + 1);
                    }
                    if (cvs_count2 > 0) {
                        add_run_i32_i32_i32_i32(idx2, 1, cc_start2, cvs_count2);
                    }
                }
            }
            c2 = (c2 + 1);
        }
        r2 = (r2 + 1);
    }
    int32_t vi = 0;
    while (vi < csp_nvars) {
        v2r_count[vi] = 0;
        vi = (vi + 1);
    }
    int32_t ri = 0;
    while (ri < csp_nruns) {
        int32_t inv_off = run_inv_off[ri];
        int32_t ic = run_inv_count[ri];
        int32_t j = 0;
        while (j < ic) {
            int32_t v = inv_pool[(inv_off + j)];
            v2r_count[v] = (v2r_count[v] + 1);
            j = (j + 1);
        }
        ri = (ri + 1);
    }
    int32_t acc2 = 0;
    int32_t vi2 = 0;
    while (vi2 < csp_nvars) {
        v2r_off[vi2] = acc2;
        acc2 = (acc2 + v2r_count[vi2]);
        v2r_count[vi2] = 0;
        vi2 = (vi2 + 1);
    }
    int32_t ri2 = 0;
    while (ri2 < csp_nruns) {
        int32_t inv_off2 = run_inv_off[ri2];
        int32_t ic2 = run_inv_count[ri2];
        int32_t j2 = 0;
        while (j2 < ic2) {
            int32_t v2 = inv_pool[(inv_off2 + j2)];
            v2r_data[(v2r_off[v2] + v2r_count[v2])] = ri2;
            v2r_count[v2] = (v2r_count[v2] + 1);
            j2 = (j2 + 1);
        }
        ri2 = (ri2 + 1);
    }
}

void add_run_i32_i32_i32_i32(int32_t gidx, int32_t hv, int32_t cv_start, int32_t cv_count) {
    int32_t ri = csp_nruns;
    csp_nruns = (csp_nruns + 1);
    run_cv_off[ri] = cv_start;
    run_cv_count[ri] = cv_count;
    run_length[ri] = cv_count;
    int32_t code_off = 0;
    int32_t code_len = 0;
    if (hv == 0) {
        code_len = g_h_len[gidx];
        code_off = (gidx * 4);
    } else {
        code_len = g_v_len[gidx];
        code_off = (gidx * 4);
    }
    if (code_len == 1) {
        run_nsl[ri] = 1;
        run_sl0[ri] = (((int32_t)(g_h_data[code_off])) - 65);
        if (hv == 1) {
            run_sl0[ri] = (((int32_t)(g_v_data[code_off])) - 65);
        }
        run_sl1[ri] = 0;
    } else {
        run_nsl[ri] = 2;
        if (hv == 0) {
            run_sl0[ri] = (((int32_t)(g_h_data[code_off])) - 65);
            run_sl1[ri] = (((int32_t)(g_h_data[(code_off + 1)])) - 65);
        } else {
            run_sl0[ri] = (((int32_t)(g_v_data[code_off])) - 65);
            run_sl1[ri] = (((int32_t)(g_v_data[(code_off + 1)])) - 65);
        }
    }
    int32_t sums_start = sums_pool_next;
    int32_t scount = 0;
    int32_t L = run_length[ri];
    int32_t s = 1;
    while (s <= 45) {
        int32_t pidx = ((L * 46) + s);
        if (perms_count[pidx] > 0) {
            sums_pool[sums_pool_next] = s;
            sums_pool_next = (sums_pool_next + 1);
            scount = (scount + 1);
        }
        s = (s + 1);
    }
    run_sums_off[ri] = sums_start;
    run_sums_count[ri] = scount;
    int32_t inv_start = inv_pool_next;
    int32_t icount = 0;
    int32_t ci = 0;
    while (ci < cv_count) {
        inv_pool[inv_pool_next] = cv_pool[(cv_start + ci)];
        inv_pool_next = (inv_pool_next + 1);
        icount = (icount + 1);
        ci = (ci + 1);
    }
    inv_pool[inv_pool_next] = run_sl0[ri];
    inv_pool_next = (inv_pool_next + 1);
    icount = (icount + 1);
    if (run_nsl[ri] == 2) {
        inv_pool[inv_pool_next] = run_sl1[ri];
        inv_pool_next = (inv_pool_next + 1);
        icount = (icount + 1);
    }
    sort_i32_ptr_i32_i32((inv_pool + inv_start), icount);
    icount = unique_i32_ptr_i32_i32((inv_pool + inv_start), icount);
    run_inv_off[ri] = inv_start;
    run_inv_count[ri] = icount;
    int32_t inv_idx_start = inv_idx_pool_next;
    int32_t ii = 0;
    while (ii < icount) {
        inv_idx_pool[inv_idx_pool_next] = ii;
        inv_idx_pool_next = (inv_idx_pool_next + 1);
        ii = (ii + 1);
    }
    run_inv_index[ri] = inv_idx_start;
    int32_t* tmp_arr = (int32_t*)(((int32_t*)(calloc(cv_count, 4))));
    int32_t di = 0;
    while (di < cv_count) {
        tmp_arr[di] = cv_pool[(cv_start + di)];
        di = (di + 1);
    }
    sort_i32_ptr_i32_i32(tmp_arr, cv_count);
    int32_t dup = 0;
    int32_t di2 = 1;
    while (di2 < cv_count) {
        if (tmp_arr[di2] == tmp_arr[(di2 - 1)]) {
            dup = 1;
            break;
        }
        di2 = (di2 + 1);
    }
    run_dup[ri] = dup;
    free(tmp_arr);
    if ((run_nsl[ri] == 2 && run_sl0[ri] == run_sl1[ri])) {
        run_ssame[ri] = 1;
    } else {
        run_ssame[ri] = 0;
    }
}

int32_t inv_index_lookup_i32_i32(int32_t ri, int32_t v) {
    int32_t off = run_inv_off[ri];
    int32_t n = run_inv_count[ri];
    int32_t lo = 0;
    int32_t hi = (n - 1);
    while (lo <= hi) {
        int32_t mid = FLOW_CHECKED_DIV(((lo + hi)), (2));
        int32_t val = inv_pool[(off + mid)];
        if (val == v) {
            return mid;
        }
        if (val < v) {
            lo = (mid + 1);
        } else {
            hi = (mid - 1);
        }
    }
    return (-1);
}

int32_t enforce_all_diff_ptr_i32(int32_t* dom) {
    int32_t fixed_mask = 0;
    if (ad_seen == ((int32_t*)(0))) {
        ad_seen = ((int32_t*)(calloc(10, 4)));
    }
    int32_t i = 0;
    while (i < 10) {
        ad_seen[i] = 0;
        i = (i + 1);
    }
    i = 0;
    while (i < 10) {
        if (popcount_i32(dom[i]) == 1) {
            int32_t d = ctz_i32(dom[i]);
            if (ad_seen[d] == 1) {
                return 1;
            }
            ad_seen[d] = 1;
            fixed_mask = (fixed_mask | FLOW_CHECKED_SHL((1), (d)));
        }
        i = (i + 1);
    }
    if (ad_changed == ((int32_t*)(0))) {
        ad_changed = ((int32_t*)(calloc(20, 4)));
    }
    ad_changed_n = 0;
    i = 0;
    while (i < 10) {
        if (popcount_i32(dom[i]) > 1) {
            int32_t neu = (dom[i] & ((0 - 1) - fixed_mask));
            if (neu == 0) {
                return 1;
            }
            if (neu != dom[i]) {
                dom[i] = neu;
                ad_changed[ad_changed_n] = i;
                ad_changed_n = (ad_changed_n + 1);
            }
        }
        i = (i + 1);
    }
    return 0;
}

int32_t process_run_i32_ptr_i32(int32_t ri, int32_t* dom) {
    if (run_dup[ri] == 1) {
        return 1;
    }
    int32_t ninv = run_inv_count[ri];
    if (pr_support == ((int32_t*)(0))) {
        pr_support = ((int32_t*)(calloc(40, 4)));
    }
    if (pr_changed == ((int32_t*)(0))) {
        pr_changed = ((int32_t*)(calloc(40, 4)));
    }
    int32_t i = 0;
    while (i < ninv) {
        pr_support[i] = 0;
        i = (i + 1);
    }
    int32_t L = run_length[ri];
    int32_t cv_off = run_cv_off[ri];
    int32_t sums_off = run_sums_off[ri];
    int32_t sums_count = run_sums_count[ri];
    if (run_nsl[ri] == 1) {
        int32_t l = run_sl0[ri];
        int32_t li = inv_index_lookup_i32_i32(ri, l);
        int32_t doml = dom[l];
        int32_t si = 0;
        while (si < sums_count) {
            int32_t S = sums_pool[(sums_off + si)];
            if (S <= 9) {
                if ((doml & FLOW_CHECKED_SHL((1), (S))) != 0) {
                    int32_t pidx = ((L * 46) + S);
                    int32_t pk = 0;
                    while (pk < perms_count[pidx]) {
                        get_perm_i32_i32_i32(L, S, pk);
                        int32_t ok = 1;
                        int32_t ci = 0;
                        while (ci < L) {
                            int32_t cv = cv_pool[(cv_off + ci)];
                            if ((dom[cv] & FLOW_CHECKED_SHL((1), (perm_buf[ci]))) == 0) {
                                ok = 0;
                                break;
                            }
                            ci = (ci + 1);
                        }
                        if (ok == 1) {
                            int32_t ci2 = 0;
                            while (ci2 < L) {
                                int32_t cv2 = cv_pool[(cv_off + ci2)];
                                int32_t idx2 = inv_index_lookup_i32_i32(ri, cv2);
                                pr_support[idx2] = (pr_support[idx2] | FLOW_CHECKED_SHL((1), (perm_buf[ci2])));
                                ci2 = (ci2 + 1);
                            }
                            pr_support[li] = (pr_support[li] | FLOW_CHECKED_SHL((1), (S)));
                        }
                        pk = (pk + 1);
                    }
                }
            }
            si = (si + 1);
        }
    } else {
        int32_t a = run_sl0[ri];
        int32_t b = run_sl1[ri];
        int32_t ai = inv_index_lookup_i32_i32(ri, a);
        int32_t bi = inv_index_lookup_i32_i32(ri, b);
        if (run_ssame[ri] == 1) {
            int32_t doma = dom[a];
            int32_t si = 0;
            while (si < sums_count) {
                int32_t S = sums_pool[(sums_off + si)];
                if (S >= 10) {
                    int32_t t = FLOW_CHECKED_DIV((S), (10));
                    int32_t o = FLOW_CHECKED_MOD((S), (10));
                    if (t == o) {
                        if ((doma & FLOW_CHECKED_SHL((1), (t))) != 0) {
                            int32_t pidx = ((L * 46) + S);
                            int32_t pk = 0;
                            while (pk < perms_count[pidx]) {
                                get_perm_i32_i32_i32(L, S, pk);
                                if (((ri == 0 && S == 22) && pk < 3)) {
                                    printf("  S=22 pk=%d perm: %d %d %d %d\n", pk, perm_buf[0], perm_buf[1], perm_buf[2], perm_buf[3]);
                                }
                                int32_t ok = 1;
                                int32_t ci = 0;
                                while (ci < L) {
                                    int32_t cv = cv_pool[(cv_off + ci)];
                                    if ((dom[cv] & FLOW_CHECKED_SHL((1), (perm_buf[ci]))) == 0) {
                                        ok = 0;
                                        break;
                                    }
                                    ci = (ci + 1);
                                }
                                if (ok == 1) {
                                    int32_t ci2 = 0;
                                    while (ci2 < L) {
                                        int32_t cv2 = cv_pool[(cv_off + ci2)];
                                        int32_t idx2 = inv_index_lookup_i32_i32(ri, cv2);
                                        pr_support[idx2] = (pr_support[idx2] | FLOW_CHECKED_SHL((1), (perm_buf[ci2])));
                                        ci2 = (ci2 + 1);
                                    }
                                    pr_support[ai] = (pr_support[ai] | FLOW_CHECKED_SHL((1), (t)));
                                }
                                pk = (pk + 1);
                            }
                        }
                    }
                }
                si = (si + 1);
            }
        } else {
            int32_t doma = dom[a];
            int32_t domb = dom[b];
            int32_t si = 0;
            while (si < sums_count) {
                int32_t S = sums_pool[(sums_off + si)];
                if (S >= 10) {
                    int32_t t = FLOW_CHECKED_DIV((S), (10));
                    int32_t o = FLOW_CHECKED_MOD((S), (10));
                    if (t != o) {
                        if (((doma & FLOW_CHECKED_SHL((1), (t))) != 0 && (domb & FLOW_CHECKED_SHL((1), (o))) != 0)) {
                            int32_t pidx = ((L * 46) + S);
                            int32_t pk = 0;
                            while (pk < perms_count[pidx]) {
                                get_perm_i32_i32_i32(L, S, pk);
                                int32_t ok = 1;
                                int32_t ci = 0;
                                while (ci < L) {
                                    int32_t cv = cv_pool[(cv_off + ci)];
                                    if ((dom[cv] & FLOW_CHECKED_SHL((1), (perm_buf[ci]))) == 0) {
                                        ok = 0;
                                        break;
                                    }
                                    ci = (ci + 1);
                                }
                                if (ok == 1) {
                                    int32_t ci2 = 0;
                                    while (ci2 < L) {
                                        int32_t cv2 = cv_pool[(cv_off + ci2)];
                                        int32_t idx2 = inv_index_lookup_i32_i32(ri, cv2);
                                        pr_support[idx2] = (pr_support[idx2] | FLOW_CHECKED_SHL((1), (perm_buf[ci2])));
                                        ci2 = (ci2 + 1);
                                    }
                                    pr_support[ai] = (pr_support[ai] | FLOW_CHECKED_SHL((1), (t)));
                                    pr_support[bi] = (pr_support[bi] | FLOW_CHECKED_SHL((1), (o)));
                                }
                                pk = (pk + 1);
                            }
                        }
                    }
                }
                si = (si + 1);
            }
        }
    }
    pr_changed_n = 0;
    int32_t i2 = 0;
    while (i2 < ninv) {
        int32_t v = inv_pool[(run_inv_off[ri] + i2)];
        int32_t sup = pr_support[i2];
        if (sup == 0) {
            return 1;
        }
        int32_t neu = (dom[v] & sup);
        if (neu == 0) {
            return 1;
        }
        if (neu != dom[v]) {
            dom[v] = neu;
            pr_changed[pr_changed_n] = v;
            pr_changed_n = (pr_changed_n + 1);
        }
        i2 = (i2 + 1);
    }
    return 0;
}

int32_t propagate_ptr_i32(int32_t* dom) {
    if (prop_q == ((int32_t*)(0))) {
        prop_q = ((int32_t*)(calloc((MAX_RUNS + 100), 4)));
        prop_inq = ((int32_t*)(calloc((MAX_RUNS + 100), 4)));
    }
    int32_t qhead = 0;
    int32_t qtail = 0;
    int32_t i = 0;
    while (i < csp_nruns) {
        prop_inq[i] = 1;
        prop_q[qtail] = i;
        qtail = (qtail + 1);
        i = (i + 1);
    }
    while (1 == 1) {
        int32_t fail = enforce_all_diff_ptr_i32(dom);
        if (fail == 1) {
            return 0;
        }
        int32_t ci = 0;
        while (ci < ad_changed_n) {
            int32_t l = ad_changed[ci];
            int32_t ri = 0;
            while (ri < v2r_count[l]) {
                int32_t ridx = v2r_data[(v2r_off[l] + ri)];
                if (prop_inq[ridx] == 0) {
                    prop_q[qtail] = ridx;
                    qtail = (qtail + 1);
                    prop_inq[ridx] = 1;
                }
                ri = (ri + 1);
            }
            ci = (ci + 1);
        }
        if (qhead >= qtail) {
            return 1;
        }
        int32_t ri2 = prop_q[qhead];
        qhead = (qhead + 1);
        prop_inq[ri2] = 0;
        int32_t fail2 = process_run_i32_ptr_i32(ri2, dom);
        if (fail2 == 1) {
            return 0;
        }
        int32_t vi = 0;
        while (vi < pr_changed_n) {
            int32_t v = pr_changed[vi];
            int32_t rj = 0;
            while (rj < v2r_count[v]) {
                int32_t ridx2 = v2r_data[(v2r_off[v] + rj)];
                if (prop_inq[ridx2] == 0) {
                    prop_q[qtail] = ridx2;
                    qtail = (qtail + 1);
                    prop_inq[ridx2] = 1;
                }
                rj = (rj + 1);
            }
            vi = (vi + 1);
        }
    }
    return 1;
}

int32_t select_var_ptr_i32(int32_t* dom) {
    int32_t best = (-1);
    int32_t best_c = 999;
    int32_t i = 0;
    while (i < csp_nvars) {
        int32_t c = popcount_i32(dom[i]);
        if (c > 1) {
            if (c < best_c) {
                best_c = c;
                best = i;
                if (c == 2) {
                    break;
                }
            }
        }
        i = (i + 1);
    }
    return best;
}

int32_t solve_rec_ptr_i32(int32_t* dom) {
    int32_t fail = propagate_ptr_i32(dom);
    if (fail == 0) {
        return 0;
    }
    int32_t v = select_var_ptr_i32(dom);
    if (v < 0) {
        int32_t i = 0;
        while (i < csp_nvars) {
            sol_buf[i] = dom[i];
            i = (i + 1);
        }
        return 1;
    }
    int32_t mask = dom[v];
    int32_t d = 0;
    while (d < 10) {
        if ((mask & FLOW_CHECKED_SHL((1), (d))) != 0) {
            int32_t* dom2 = (int32_t*)(((int32_t*)(calloc(csp_nvars, 4))));
            int32_t i = 0;
            while (i < csp_nvars) {
                dom2[i] = dom[i];
                i = (i + 1);
            }
            dom2[v] = FLOW_CHECKED_SHL((1), (d));
            int32_t res = solve_rec_ptr_i32(dom2);
            free(dom2);
            if (res == 1) {
                return 1;
            }
        }
        d = (d + 1);
    }
    return 0;
}

int64_t mapping_to_number_ptr_i32(int32_t* sol) {
    int64_t num = 0;
    int32_t i = 0;
    while (i < 10) {
        int32_t d = ctz_i32(sol[i]);
        num = ((num * 10) + ((int64_t)(d)));
        i = (i + 1);
    }
    return num;
}

int64_t solve_puzzle_ptr_i8_i32(int8_t* line, int32_t line_len) {
    parse_puzzle_ptr_i8_i32(line, line_len);
    build_csp();
    if (sol_buf == ((int32_t*)(0))) {
        sol_buf = ((int32_t*)(calloc(MAX_VARS, 4)));
    }
    int32_t res = solve_rec_ptr_i32(csp_domains);
    if (res == 0) {
        abort();
    }
    return mapping_to_number_ptr_i32(sol_buf);
}

int32_t main(void) {
    init_globals();
    void* f = (void*)(fopen("data/p424.txt", "r"));
    if (f == ((void*)(0))) {
        printf("cannot open data/p424.txt\n");
        return 1;
    }
    int64_t total = 0;
    while (1 == 1) {
        int8_t* res = (int8_t*)(fgets(line_buf, MAX_LINE, f));
        if (res == ((int8_t*)(0))) {
            break;
        }
        int32_t len = 0;
        while (len < MAX_LINE) {
            int8_t ch = line_buf[len];
            if (ch == 0) {
                break;
            }
            if (ch == 10) {
                break;
            }
            len = (len + 1);
        }
        if (len > 0) {
            if (line_buf[(len - 1)] == 13) {
                len = (len - 1);
            }
        }
        if (len > 0) {
            total = (total + solve_puzzle_ptr_i8_i32(line_buf, len));
        }
    }
    fclose(f);
    printf("%lld\n", total);
    return 0;
}

Generated MLIR

module {
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str_0("  S=22 pk=%d perm: %d %d %d %d\n\00") {addr_space = 0 : i32} : !llvm.array<32 x i8>
  llvm.mlir.global internal constant @str_1("data/p424.txt\00") {addr_space = 0 : i32} : !llvm.array<14 x i8>
  llvm.mlir.global internal constant @str_2("r\00") {addr_space = 0 : i32} : !llvm.array<2 x i8>
  llvm.mlir.global internal constant @str_3("cannot open data/p424.txt\n\00") {addr_space = 0 : i32} : !llvm.array<27 x i8>
  llvm.mlir.global internal constant @str_4("%lld\n\00") {addr_space = 0 : i32} : !llvm.array<6 x i8>
  func.func private @calloc(i64, i64) -> !llvm.ptr
  func.func private @realloc(!llvm.ptr, i64) -> !llvm.ptr
  func.func private @free(!llvm.ptr) -> ()

  func.func private @fopen(!llvm.ptr, !llvm.ptr) -> !llvm.ptr
  func.func private @fgets(!llvm.ptr, i32, !llvm.ptr) -> !llvm.ptr
  func.func private @fclose(!llvm.ptr) -> i32
  func.func private @abort() -> ()
  // Constant: ALL10
  llvm.mlir.global internal constant @ALL10(1023 : i32) : i32
  // Constant: DIGITS_19
  llvm.mlir.global internal constant @DIGITS_19(1022 : i32) : i32
  // Constant: MAX_GRID
  llvm.mlir.global internal constant @MAX_GRID(400 : i32) : i32
  // Constant: MAX_RUNS
  llvm.mlir.global internal constant @MAX_RUNS(200 : i32) : i32
  // Constant: MAX_VARS
  llvm.mlir.global internal constant @MAX_VARS(400 : i32) : i32
  // Constant: MAX_PERMS_TOTAL
  llvm.mlir.global internal constant @MAX_PERMS_TOTAL(700000 : i32) : i32
  // Constant: MAX_LINE
  llvm.mlir.global internal constant @MAX_LINE(2048 : i32) : i32
  // Constant: CT_X
  llvm.mlir.global internal constant @CT_X(0 : i32) : i32
  // Constant: CT_O
  llvm.mlir.global internal constant @CT_O(1 : i32) : i32
  // Constant: CT_L
  llvm.mlir.global internal constant @CT_L(2 : i32) : i32
  // Constant: CT_C
  llvm.mlir.global internal constant @CT_C(3 : i32) : i32
  // Module static: perms_count
  llvm.mlir.global internal @perms_count() {addr_space = 0 : i32} : !llvm.ptr {
    %0 = llvm.mlir.zero : !llvm.ptr
    llvm.return %0 : !llvm.ptr
  }
  // Module static: perms_offset
  llvm.mlir.global internal @perms_offset() {addr_space = 0 : i32} : !llvm.ptr {
    %1 = llvm.mlir.zero : !llvm.ptr
    llvm.return %1 : !llvm.ptr
  }
  // Module static: perms_data
  llvm.mlir.global internal @perms_data() {addr_space = 0 : i32} : !llvm.ptr {
    %2 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2 : !llvm.ptr
  }
  // Module static: perms_total
  llvm.mlir.global internal @perms_total(0 : i32) : i32
  // Module static: perms_init_done
  llvm.mlir.global internal @perms_init_done(0 : i32) : i32
  // Module static: g_type
  llvm.mlir.global internal @g_type() {addr_space = 0 : i32} : !llvm.ptr {
    %3 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3 : !llvm.ptr
  }
  // Module static: g_letter
  llvm.mlir.global internal @g_letter() {addr_space = 0 : i32} : !llvm.ptr {
    %4 = llvm.mlir.zero : !llvm.ptr
    llvm.return %4 : !llvm.ptr
  }
  // Module static: g_h_len
  llvm.mlir.global internal @g_h_len() {addr_space = 0 : i32} : !llvm.ptr {
    %5 = llvm.mlir.zero : !llvm.ptr
    llvm.return %5 : !llvm.ptr
  }
  // Module static: g_h_data
  llvm.mlir.global internal @g_h_data() {addr_space = 0 : i32} : !llvm.ptr {
    %6 = llvm.mlir.zero : !llvm.ptr
    llvm.return %6 : !llvm.ptr
  }
  // Module static: g_v_len
  llvm.mlir.global internal @g_v_len() {addr_space = 0 : i32} : !llvm.ptr {
    %7 = llvm.mlir.zero : !llvm.ptr
    llvm.return %7 : !llvm.ptr
  }
  // Module static: g_v_data
  llvm.mlir.global internal @g_v_data() {addr_space = 0 : i32} : !llvm.ptr {
    %8 = llvm.mlir.zero : !llvm.ptr
    llvm.return %8 : !llvm.ptr
  }
  // Module static: cell_to_var
  llvm.mlir.global internal @cell_to_var() {addr_space = 0 : i32} : !llvm.ptr {
    %9 = llvm.mlir.zero : !llvm.ptr
    llvm.return %9 : !llvm.ptr
  }
  // Module static: csp_domains
  llvm.mlir.global internal @csp_domains() {addr_space = 0 : i32} : !llvm.ptr {
    %10 = llvm.mlir.zero : !llvm.ptr
    llvm.return %10 : !llvm.ptr
  }
  // Module static: csp_nvars
  llvm.mlir.global internal @csp_nvars(0 : i32) : i32
  // Module static: csp_nruns
  llvm.mlir.global internal @csp_nruns(0 : i32) : i32
  // Module static: run_cv_off
  llvm.mlir.global internal @run_cv_off() {addr_space = 0 : i32} : !llvm.ptr {
    %11 = llvm.mlir.zero : !llvm.ptr
    llvm.return %11 : !llvm.ptr
  }
  // Module static: run_cv_data
  llvm.mlir.global internal @run_cv_data() {addr_space = 0 : i32} : !llvm.ptr {
    %12 = llvm.mlir.zero : !llvm.ptr
    llvm.return %12 : !llvm.ptr
  }
  // Module static: run_cv_count
  llvm.mlir.global internal @run_cv_count() {addr_space = 0 : i32} : !llvm.ptr {
    %13 = llvm.mlir.zero : !llvm.ptr
    llvm.return %13 : !llvm.ptr
  }
  // Module static: run_sl0
  llvm.mlir.global internal @run_sl0() {addr_space = 0 : i32} : !llvm.ptr {
    %14 = llvm.mlir.zero : !llvm.ptr
    llvm.return %14 : !llvm.ptr
  }
  // Module static: run_sl1
  llvm.mlir.global internal @run_sl1() {addr_space = 0 : i32} : !llvm.ptr {
    %15 = llvm.mlir.zero : !llvm.ptr
    llvm.return %15 : !llvm.ptr
  }
  // Module static: run_nsl
  llvm.mlir.global internal @run_nsl() {addr_space = 0 : i32} : !llvm.ptr {
    %16 = llvm.mlir.zero : !llvm.ptr
    llvm.return %16 : !llvm.ptr
  }
  // Module static: run_inv_off
  llvm.mlir.global internal @run_inv_off() {addr_space = 0 : i32} : !llvm.ptr {
    %17 = llvm.mlir.zero : !llvm.ptr
    llvm.return %17 : !llvm.ptr
  }
  // Module static: run_inv_data
  llvm.mlir.global internal @run_inv_data() {addr_space = 0 : i32} : !llvm.ptr {
    %18 = llvm.mlir.zero : !llvm.ptr
    llvm.return %18 : !llvm.ptr
  }
  // Module static: run_inv_count
  llvm.mlir.global internal @run_inv_count() {addr_space = 0 : i32} : !llvm.ptr {
    %19 = llvm.mlir.zero : !llvm.ptr
    llvm.return %19 : !llvm.ptr
  }
  // Module static: run_inv_index
  llvm.mlir.global internal @run_inv_index() {addr_space = 0 : i32} : !llvm.ptr {
    %20 = llvm.mlir.zero : !llvm.ptr
    llvm.return %20 : !llvm.ptr
  }
  // Module static: run_length
  llvm.mlir.global internal @run_length() {addr_space = 0 : i32} : !llvm.ptr {
    %21 = llvm.mlir.zero : !llvm.ptr
    llvm.return %21 : !llvm.ptr
  }
  // Module static: run_sums_off
  llvm.mlir.global internal @run_sums_off() {addr_space = 0 : i32} : !llvm.ptr {
    %22 = llvm.mlir.zero : !llvm.ptr
    llvm.return %22 : !llvm.ptr
  }
  // Module static: run_sums_data
  llvm.mlir.global internal @run_sums_data() {addr_space = 0 : i32} : !llvm.ptr {
    %23 = llvm.mlir.zero : !llvm.ptr
    llvm.return %23 : !llvm.ptr
  }
  // Module static: run_sums_count
  llvm.mlir.global internal @run_sums_count() {addr_space = 0 : i32} : !llvm.ptr {
    %24 = llvm.mlir.zero : !llvm.ptr
    llvm.return %24 : !llvm.ptr
  }
  // Module static: run_dup
  llvm.mlir.global internal @run_dup() {addr_space = 0 : i32} : !llvm.ptr {
    %25 = llvm.mlir.zero : !llvm.ptr
    llvm.return %25 : !llvm.ptr
  }
  // Module static: run_ssame
  llvm.mlir.global internal @run_ssame() {addr_space = 0 : i32} : !llvm.ptr {
    %26 = llvm.mlir.zero : !llvm.ptr
    llvm.return %26 : !llvm.ptr
  }
  // Module static: v2r_off
  llvm.mlir.global internal @v2r_off() {addr_space = 0 : i32} : !llvm.ptr {
    %27 = llvm.mlir.zero : !llvm.ptr
    llvm.return %27 : !llvm.ptr
  }
  // Module static: v2r_data
  llvm.mlir.global internal @v2r_data() {addr_space = 0 : i32} : !llvm.ptr {
    %28 = llvm.mlir.zero : !llvm.ptr
    llvm.return %28 : !llvm.ptr
  }
  // Module static: v2r_count
  llvm.mlir.global internal @v2r_count() {addr_space = 0 : i32} : !llvm.ptr {
    %29 = llvm.mlir.zero : !llvm.ptr
    llvm.return %29 : !llvm.ptr
  }
  // Module static: cv_pool
  llvm.mlir.global internal @cv_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %30 = llvm.mlir.zero : !llvm.ptr
    llvm.return %30 : !llvm.ptr
  }
  // Module static: cv_pool_next
  llvm.mlir.global internal @cv_pool_next(0 : i32) : i32
  // Module static: inv_pool
  llvm.mlir.global internal @inv_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %31 = llvm.mlir.zero : !llvm.ptr
    llvm.return %31 : !llvm.ptr
  }
  // Module static: inv_pool_next
  llvm.mlir.global internal @inv_pool_next(0 : i32) : i32
  // Module static: inv_idx_pool
  llvm.mlir.global internal @inv_idx_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %32 = llvm.mlir.zero : !llvm.ptr
    llvm.return %32 : !llvm.ptr
  }
  // Module static: inv_idx_pool_next
  llvm.mlir.global internal @inv_idx_pool_next(0 : i32) : i32
  // Module static: sums_pool
  llvm.mlir.global internal @sums_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %33 = llvm.mlir.zero : !llvm.ptr
    llvm.return %33 : !llvm.ptr
  }
  // Module static: sums_pool_next
  llvm.mlir.global internal @sums_pool_next(0 : i32) : i32
  // Module static: v2r_pool
  llvm.mlir.global internal @v2r_pool() {addr_space = 0 : i32} : !llvm.ptr {
    %34 = llvm.mlir.zero : !llvm.ptr
    llvm.return %34 : !llvm.ptr
  }
  // Module static: v2r_pool_next
  llvm.mlir.global internal @v2r_pool_next(0 : i32) : i32
  // Module static: line_buf
  llvm.mlir.global internal @line_buf() {addr_space = 0 : i32} : !llvm.ptr {
    %35 = llvm.mlir.zero : !llvm.ptr
    llvm.return %35 : !llvm.ptr
  }
  // Module static: perm_buf
  llvm.mlir.global internal @perm_buf() {addr_space = 0 : i32} : !llvm.ptr {
    %36 = llvm.mlir.zero : !llvm.ptr
    llvm.return %36 : !llvm.ptr
  }
  func.func @init_globals() -> () {
    %38 = arith.constant 7 : i32
    %39 = arith.constant 46 : i32
    %40 = arith.muli %38, %39 : i32
    %41 = arith.constant 4 : i32
    %42 = arith.extsi %40 : i32 to i64
    %43 = arith.extsi %41 : i32 to i64
    %37 = func.call @calloc(%42, %43) : (i64, i64) -> !llvm.ptr
    %44 = llvm.mlir.addressof @perms_count : !llvm.ptr
    llvm.store %37, %44 : !llvm.ptr, !llvm.ptr
    %46 = arith.constant 7 : i32
    %47 = arith.constant 46 : i32
    %48 = arith.muli %46, %47 : i32
    %49 = arith.constant 4 : i32
    %50 = arith.extsi %48 : i32 to i64
    %51 = arith.extsi %49 : i32 to i64
    %45 = func.call @calloc(%50, %51) : (i64, i64) -> !llvm.ptr
    %52 = llvm.mlir.addressof @perms_offset : !llvm.ptr
    llvm.store %45, %52 : !llvm.ptr, !llvm.ptr
    %54 = llvm.mlir.addressof @MAX_PERMS_TOTAL : !llvm.ptr
    %55 = llvm.load %54 : !llvm.ptr -> i32
    %56 = arith.constant 4 : i32
    %57 = arith.extsi %55 : i32 to i64
    %58 = arith.extsi %56 : i32 to i64
    %53 = func.call @calloc(%57, %58) : (i64, i64) -> !llvm.ptr
    %59 = llvm.mlir.addressof @perms_data : !llvm.ptr
    llvm.store %53, %59 : !llvm.ptr, !llvm.ptr
    %61 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %62 = llvm.load %61 : !llvm.ptr -> i32
    %63 = arith.constant 4 : i32
    %64 = arith.extsi %62 : i32 to i64
    %65 = arith.extsi %63 : i32 to i64
    %60 = func.call @calloc(%64, %65) : (i64, i64) -> !llvm.ptr
    %66 = llvm.mlir.addressof @g_type : !llvm.ptr
    llvm.store %60, %66 : !llvm.ptr, !llvm.ptr
    %68 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %69 = llvm.load %68 : !llvm.ptr -> i32
    %70 = arith.constant 4 : i32
    %71 = arith.extsi %69 : i32 to i64
    %72 = arith.extsi %70 : i32 to i64
    %67 = func.call @calloc(%71, %72) : (i64, i64) -> !llvm.ptr
    %73 = llvm.mlir.addressof @g_letter : !llvm.ptr
    llvm.store %67, %73 : !llvm.ptr, !llvm.ptr
    %75 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %76 = llvm.load %75 : !llvm.ptr -> i32
    %77 = arith.constant 4 : i32
    %78 = arith.extsi %76 : i32 to i64
    %79 = arith.extsi %77 : i32 to i64
    %74 = func.call @calloc(%78, %79) : (i64, i64) -> !llvm.ptr
    %80 = llvm.mlir.addressof @g_h_len : !llvm.ptr
    llvm.store %74, %80 : !llvm.ptr, !llvm.ptr
    %82 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %83 = llvm.load %82 : !llvm.ptr -> i32
    %84 = arith.constant 4 : i32
    %85 = arith.muli %83, %84 : i32
    %86 = arith.constant 1 : i32
    %87 = arith.extsi %85 : i32 to i64
    %88 = arith.extsi %86 : i32 to i64
    %81 = func.call @calloc(%87, %88) : (i64, i64) -> !llvm.ptr
    %89 = llvm.mlir.addressof @g_h_data : !llvm.ptr
    llvm.store %81, %89 : !llvm.ptr, !llvm.ptr
    %91 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %92 = llvm.load %91 : !llvm.ptr -> i32
    %93 = arith.constant 4 : i32
    %94 = arith.extsi %92 : i32 to i64
    %95 = arith.extsi %93 : i32 to i64
    %90 = func.call @calloc(%94, %95) : (i64, i64) -> !llvm.ptr
    %96 = llvm.mlir.addressof @g_v_len : !llvm.ptr
    llvm.store %90, %96 : !llvm.ptr, !llvm.ptr
    %98 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %99 = llvm.load %98 : !llvm.ptr -> i32
    %100 = arith.constant 4 : i32
    %101 = arith.muli %99, %100 : i32
    %102 = arith.constant 1 : i32
    %103 = arith.extsi %101 : i32 to i64
    %104 = arith.extsi %102 : i32 to i64
    %97 = func.call @calloc(%103, %104) : (i64, i64) -> !llvm.ptr
    %105 = llvm.mlir.addressof @g_v_data : !llvm.ptr
    llvm.store %97, %105 : !llvm.ptr, !llvm.ptr
    %107 = llvm.mlir.addressof @MAX_GRID : !llvm.ptr
    %108 = llvm.load %107 : !llvm.ptr -> i32
    %109 = arith.constant 4 : i32
    %110 = arith.extsi %108 : i32 to i64
    %111 = arith.extsi %109 : i32 to i64
    %106 = func.call @calloc(%110, %111) : (i64, i64) -> !llvm.ptr
    %112 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
    llvm.store %106, %112 : !llvm.ptr, !llvm.ptr
    %114 = llvm.mlir.addressof @MAX_VARS : !llvm.ptr
    %115 = llvm.load %114 : !llvm.ptr -> i32
    %116 = arith.constant 4 : i32
    %117 = arith.extsi %115 : i32 to i64
    %118 = arith.extsi %116 : i32 to i64
    %113 = func.call @calloc(%117, %118) : (i64, i64) -> !llvm.ptr
    %119 = llvm.mlir.addressof @csp_domains : !llvm.ptr
    llvm.store %113, %119 : !llvm.ptr, !llvm.ptr
    %121 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %122 = llvm.load %121 : !llvm.ptr -> i32
    %123 = arith.constant 4 : i32
    %124 = arith.extsi %122 : i32 to i64
    %125 = arith.extsi %123 : i32 to i64
    %120 = func.call @calloc(%124, %125) : (i64, i64) -> !llvm.ptr
    %126 = llvm.mlir.addressof @run_cv_off : !llvm.ptr
    llvm.store %120, %126 : !llvm.ptr, !llvm.ptr
    %128 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %129 = llvm.load %128 : !llvm.ptr -> i32
    %130 = arith.constant 20 : i32
    %131 = arith.muli %129, %130 : i32
    %132 = arith.constant 4 : i32
    %133 = arith.extsi %131 : i32 to i64
    %134 = arith.extsi %132 : i32 to i64
    %127 = func.call @calloc(%133, %134) : (i64, i64) -> !llvm.ptr
    %135 = llvm.mlir.addressof @run_cv_data : !llvm.ptr
    llvm.store %127, %135 : !llvm.ptr, !llvm.ptr
    %137 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %138 = llvm.load %137 : !llvm.ptr -> i32
    %139 = arith.constant 4 : i32
    %140 = arith.extsi %138 : i32 to i64
    %141 = arith.extsi %139 : i32 to i64
    %136 = func.call @calloc(%140, %141) : (i64, i64) -> !llvm.ptr
    %142 = llvm.mlir.addressof @run_cv_count : !llvm.ptr
    llvm.store %136, %142 : !llvm.ptr, !llvm.ptr
    %144 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %145 = llvm.load %144 : !llvm.ptr -> i32
    %146 = arith.constant 4 : i32
    %147 = arith.extsi %145 : i32 to i64
    %148 = arith.extsi %146 : i32 to i64
    %143 = func.call @calloc(%147, %148) : (i64, i64) -> !llvm.ptr
    %149 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
    llvm.store %143, %149 : !llvm.ptr, !llvm.ptr
    %151 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %152 = llvm.load %151 : !llvm.ptr -> i32
    %153 = arith.constant 4 : i32
    %154 = arith.extsi %152 : i32 to i64
    %155 = arith.extsi %153 : i32 to i64
    %150 = func.call @calloc(%154, %155) : (i64, i64) -> !llvm.ptr
    %156 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
    llvm.store %150, %156 : !llvm.ptr, !llvm.ptr
    %158 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %159 = llvm.load %158 : !llvm.ptr -> i32
    %160 = arith.constant 4 : i32
    %161 = arith.extsi %159 : i32 to i64
    %162 = arith.extsi %160 : i32 to i64
    %157 = func.call @calloc(%161, %162) : (i64, i64) -> !llvm.ptr
    %163 = llvm.mlir.addressof @run_nsl : !llvm.ptr
    llvm.store %157, %163 : !llvm.ptr, !llvm.ptr
    %165 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %166 = llvm.load %165 : !llvm.ptr -> i32
    %167 = arith.constant 4 : i32
    %168 = arith.extsi %166 : i32 to i64
    %169 = arith.extsi %167 : i32 to i64
    %164 = func.call @calloc(%168, %169) : (i64, i64) -> !llvm.ptr
    %170 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
    llvm.store %164, %170 : !llvm.ptr, !llvm.ptr
    %172 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %173 = llvm.load %172 : !llvm.ptr -> i32
    %174 = arith.constant 30 : i32
    %175 = arith.muli %173, %174 : i32
    %176 = arith.constant 4 : i32
    %177 = arith.extsi %175 : i32 to i64
    %178 = arith.extsi %176 : i32 to i64
    %171 = func.call @calloc(%177, %178) : (i64, i64) -> !llvm.ptr
    %179 = llvm.mlir.addressof @run_inv_data : !llvm.ptr
    llvm.store %171, %179 : !llvm.ptr, !llvm.ptr
    %181 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %182 = llvm.load %181 : !llvm.ptr -> i32
    %183 = arith.constant 4 : i32
    %184 = arith.extsi %182 : i32 to i64
    %185 = arith.extsi %183 : i32 to i64
    %180 = func.call @calloc(%184, %185) : (i64, i64) -> !llvm.ptr
    %186 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
    llvm.store %180, %186 : !llvm.ptr, !llvm.ptr
    %188 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %189 = llvm.load %188 : !llvm.ptr -> i32
    %190 = arith.constant 30 : i32
    %191 = arith.muli %189, %190 : i32
    %192 = arith.constant 4 : i32
    %193 = arith.extsi %191 : i32 to i64
    %194 = arith.extsi %192 : i32 to i64
    %187 = func.call @calloc(%193, %194) : (i64, i64) -> !llvm.ptr
    %195 = llvm.mlir.addressof @run_inv_index : !llvm.ptr
    llvm.store %187, %195 : !llvm.ptr, !llvm.ptr
    %197 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %198 = llvm.load %197 : !llvm.ptr -> i32
    %199 = arith.constant 4 : i32
    %200 = arith.extsi %198 : i32 to i64
    %201 = arith.extsi %199 : i32 to i64
    %196 = func.call @calloc(%200, %201) : (i64, i64) -> !llvm.ptr
    %202 = llvm.mlir.addressof @run_length : !llvm.ptr
    llvm.store %196, %202 : !llvm.ptr, !llvm.ptr
    %204 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %205 = llvm.load %204 : !llvm.ptr -> i32
    %206 = arith.constant 4 : i32
    %207 = arith.extsi %205 : i32 to i64
    %208 = arith.extsi %206 : i32 to i64
    %203 = func.call @calloc(%207, %208) : (i64, i64) -> !llvm.ptr
    %209 = llvm.mlir.addressof @run_sums_off : !llvm.ptr
    llvm.store %203, %209 : !llvm.ptr, !llvm.ptr
    %211 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %212 = llvm.load %211 : !llvm.ptr -> i32
    %213 = arith.constant 50 : i32
    %214 = arith.muli %212, %213 : i32
    %215 = arith.constant 4 : i32
    %216 = arith.extsi %214 : i32 to i64
    %217 = arith.extsi %215 : i32 to i64
    %210 = func.call @calloc(%216, %217) : (i64, i64) -> !llvm.ptr
    %218 = llvm.mlir.addressof @run_sums_data : !llvm.ptr
    llvm.store %210, %218 : !llvm.ptr, !llvm.ptr
    %220 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %221 = llvm.load %220 : !llvm.ptr -> i32
    %222 = arith.constant 4 : i32
    %223 = arith.extsi %221 : i32 to i64
    %224 = arith.extsi %222 : i32 to i64
    %219 = func.call @calloc(%223, %224) : (i64, i64) -> !llvm.ptr
    %225 = llvm.mlir.addressof @run_sums_count : !llvm.ptr
    llvm.store %219, %225 : !llvm.ptr, !llvm.ptr
    %227 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %228 = llvm.load %227 : !llvm.ptr -> i32
    %229 = arith.constant 4 : i32
    %230 = arith.extsi %228 : i32 to i64
    %231 = arith.extsi %229 : i32 to i64
    %226 = func.call @calloc(%230, %231) : (i64, i64) -> !llvm.ptr
    %232 = llvm.mlir.addressof @run_dup : !llvm.ptr
    llvm.store %226, %232 : !llvm.ptr, !llvm.ptr
    %234 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
    %235 = llvm.load %234 : !llvm.ptr -> i32
    %236 = arith.constant 4 : i32
    %237 = arith.extsi %235 : i32 to i64
    %238 = arith.extsi %236 : i32 to i64
    %233 = func.call @calloc(%237, %238) : (i64, i64) -> !llvm.ptr
    %239 = llvm.mlir.addressof @run_ssame : !llvm.ptr
    llvm.store %233, %239 : !llvm.ptr, !llvm.ptr
    %241 = llvm.mlir.addressof @MAX_VARS : !llvm.ptr
    %242 = llvm.load %241 : !llvm.ptr -> i32
    %243 = arith.constant 4 : i32
    %244 = arith.extsi %242 : i32 to i64
    %245 = arith.extsi %243 : i32 to i64
    %240 = func.call @calloc(%244, %245) : (i64, i64) -> !llvm.ptr
    %246 = llvm.mlir.addressof @v2r_off : !llvm.ptr
    llvm.store %240, %246 : !llvm.ptr, !llvm.ptr
    %248 = llvm.mlir.addressof @MAX_VARS : !llvm.ptr
    %249 = llvm.load %248 : !llvm.ptr -> i32
    %250 = arith.constant 50 : i32
    %251 = arith.muli %249, %250 : i32
    %252 = arith.constant 4 : i32
    %253 = arith.extsi %251 : i32 to i64
    %254 = arith.extsi %252 : i32 to i64
    %247 = func.call @calloc(%253, %254) : (i64, i64) -> !llvm.ptr
    %255 = llvm.mlir.addressof @v2r_data : !llvm.ptr
    llvm.store %247, %255 : !llvm.ptr, !llvm.ptr
    %257 = llvm.mlir.addressof @MAX_VARS : !llvm.ptr
    %258 = llvm.load %257 : !llvm.ptr -> i32
    %259 = arith.constant 4 : i32
    %260 = arith.extsi %258 : i32 to i64
    %261 = arith.extsi %259 : i32 to i64
    %256 = func.call @calloc(%260, %261) : (i64, i64) -> !llvm.ptr
    %262 = llvm.mlir.addressof @v2r_count : !llvm.ptr
    llvm.store %256, %262 : !llvm.ptr, !llvm.ptr
    %264 = arith.constant 5000 : i32
    %265 = arith.constant 4 : i32
    %266 = arith.extsi %264 : i32 to i64
    %267 = arith.extsi %265 : i32 to i64
    %263 = func.call @calloc(%266, %267) : (i64, i64) -> !llvm.ptr
    %268 = llvm.mlir.addressof @cv_pool : !llvm.ptr
    llvm.store %263, %268 : !llvm.ptr, !llvm.ptr
    %270 = arith.constant 5000 : i32
    %271 = arith.constant 4 : i32
    %272 = arith.extsi %270 : i32 to i64
    %273 = arith.extsi %271 : i32 to i64
    %269 = func.call @calloc(%272, %273) : (i64, i64) -> !llvm.ptr
    %274 = llvm.mlir.addressof @inv_pool : !llvm.ptr
    llvm.store %269, %274 : !llvm.ptr, !llvm.ptr
    %276 = arith.constant 5000 : i32
    %277 = arith.constant 4 : i32
    %278 = arith.extsi %276 : i32 to i64
    %279 = arith.extsi %277 : i32 to i64
    %275 = func.call @calloc(%278, %279) : (i64, i64) -> !llvm.ptr
    %280 = llvm.mlir.addressof @inv_idx_pool : !llvm.ptr
    llvm.store %275, %280 : !llvm.ptr, !llvm.ptr
    %282 = arith.constant 10000 : i32
    %283 = arith.constant 4 : i32
    %284 = arith.extsi %282 : i32 to i64
    %285 = arith.extsi %283 : i32 to i64
    %281 = func.call @calloc(%284, %285) : (i64, i64) -> !llvm.ptr
    %286 = llvm.mlir.addressof @sums_pool : !llvm.ptr
    llvm.store %281, %286 : !llvm.ptr, !llvm.ptr
    %288 = arith.constant 20000 : i32
    %289 = arith.constant 4 : i32
    %290 = arith.extsi %288 : i32 to i64
    %291 = arith.extsi %289 : i32 to i64
    %287 = func.call @calloc(%290, %291) : (i64, i64) -> !llvm.ptr
    %292 = llvm.mlir.addressof @v2r_pool : !llvm.ptr
    llvm.store %287, %292 : !llvm.ptr, !llvm.ptr
    %294 = llvm.mlir.addressof @MAX_LINE : !llvm.ptr
    %295 = llvm.load %294 : !llvm.ptr -> i32
    %296 = arith.constant 1 : i32
    %297 = arith.extsi %295 : i32 to i64
    %298 = arith.extsi %296 : i32 to i64
    %293 = func.call @calloc(%297, %298) : (i64, i64) -> !llvm.ptr
    %299 = llvm.mlir.addressof @line_buf : !llvm.ptr
    llvm.store %293, %299 : !llvm.ptr, !llvm.ptr
    %301 = arith.constant 10 : i32
    %302 = arith.constant 4 : i32
    %303 = arith.extsi %301 : i32 to i64
    %304 = arith.extsi %302 : i32 to i64
    %300 = func.call @calloc(%303, %304) : (i64, i64) -> !llvm.ptr
    %305 = llvm.mlir.addressof @perm_buf : !llvm.ptr
    llvm.store %300, %305 : !llvm.ptr, !llvm.ptr
    func.return
  }
  func.func @popcount(%arg0: i32) -> i32 {
    %306 = arith.constant 0 : i32
    %307 = llvm.mlir.constant(1 : i64) : i64
    %308 = llvm.alloca %307 x i32 : (i64) -> !llvm.ptr
    llvm.store %306, %308 : i32, !llvm.ptr
    %309 = llvm.mlir.constant(1 : i64) : i64
    %310 = llvm.alloca %309 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg0, %310 : i32, !llvm.ptr
    cf.br ^bb0
    ^bb0:
    %311 = llvm.load %310 : !llvm.ptr -> i32
    %312 = arith.constant 0 : i32
    %313 = arith.cmpi sgt, %311, %312 : i32
    cf.cond_br %313, ^bb1, ^bb2
    ^bb1:
      %314 = llvm.load %308 : !llvm.ptr -> i32
      %315 = arith.constant 1 : i32
      %316 = arith.addi %314, %315 : i32
      llvm.store %316, %308 : i32, !llvm.ptr
      %317 = llvm.load %310 : !llvm.ptr -> i32
      %318 = llvm.load %310 : !llvm.ptr -> i32
      %319 = arith.constant 1 : i32
      %320 = arith.subi %318, %319 : i32
      %321 = arith.andi %317, %320 : i32
      llvm.store %321, %310 : i32, !llvm.ptr
      cf.br ^bb0
    ^bb2:
    %322 = llvm.load %308 : !llvm.ptr -> i32
    func.return %322 : i32
  }
  func.func @ctz(%arg0: i32) -> i32 {
    %323 = arith.constant 0 : i32
    %324 = arith.cmpi eq, %arg0, %323 : i32
    cf.cond_br %324, ^bb3, ^bb4
    ^bb3:
      %325 = arith.constant 32 : i32
      func.return %325 : i32
    ^bb4:
      cf.br ^bb5
    ^bb5:
    %326 = arith.constant 0 : i32
    %327 = llvm.mlir.constant(1 : i64) : i64
    %328 = llvm.alloca %327 x i32 : (i64) -> !llvm.ptr
    llvm.store %326, %328 : i32, !llvm.ptr
    %329 = llvm.mlir.constant(1 : i64) : i64
    %330 = llvm.alloca %329 x i32 : (i64) -> !llvm.ptr
    llvm.store %arg0, %330 : i32, !llvm.ptr
    cf.br ^bb6
    ^bb6:
    %331 = llvm.load %330 : !llvm.ptr -> i32
    %332 = arith.constant 1 : i32
    %333 = arith.andi %331, %332 : i32
    %334 = arith.constant 0 : i32
    %335 = arith.cmpi eq, %333, %334 : i32
    cf.cond_br %335, ^bb7, ^bb8
    ^bb7:
      %336 = llvm.load %328 : !llvm.ptr -> i32
      %337 = arith.constant 1 : i32
      %338 = arith.addi %336, %337 : i32
      llvm.store %338, %328 : i32, !llvm.ptr
      %339 = llvm.load %330 : !llvm.ptr -> i32
      %340 = arith.constant 1 : i32
      %341 = arith.shrsi %339, %340 : i32
      llvm.store %341, %330 : i32, !llvm.ptr
      cf.br ^bb6
    ^bb8:
    %342 = llvm.load %328 : !llvm.ptr -> i32
    func.return %342 : i32
  }
  func.func @sort_i32(%arg0: !llvm.ptr, %arg1: i32) -> () {
    %343 = arith.constant 1 : i32
    %344 = llvm.mlir.constant(1 : i64) : i64
    %345 = llvm.alloca %344 x i32 : (i64) -> !llvm.ptr
    llvm.store %343, %345 : i32, !llvm.ptr
    cf.br ^bb9
    ^bb9:
    %346 = llvm.load %345 : !llvm.ptr -> i32
    %347 = arith.cmpi slt, %346, %arg1 : i32
    cf.cond_br %347, ^bb10, ^bb11
    ^bb10:
      %349 = llvm.load %345 : !llvm.ptr -> i32
      %350 = arith.extsi %349 : i32 to i64
      %351 = llvm.getelementptr %arg0[%350] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %348 = llvm.load %351 : !llvm.ptr -> i32
      %352 = llvm.load %345 : !llvm.ptr -> i32
      %353 = arith.constant 1 : i32
      %354 = arith.subi %352, %353 : i32
      %355 = llvm.mlir.constant(1 : i64) : i64
      %356 = llvm.alloca %355 x i32 : (i64) -> !llvm.ptr
      llvm.store %354, %356 : i32, !llvm.ptr
      cf.br ^bb12
      ^bb12:
      %357 = llvm.load %356 : !llvm.ptr -> i32
      %358 = arith.constant 0 : i32
      %359 = arith.cmpi sge, %357, %358 : i32
      cf.cond_br %359, ^bb13, ^bb14
      ^bb13:
        %361 = llvm.load %356 : !llvm.ptr -> i32
        %362 = arith.extsi %361 : i32 to i64
        %363 = llvm.getelementptr %arg0[%362] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %360 = llvm.load %363 : !llvm.ptr -> i32
        %364 = arith.cmpi sgt, %360, %348 : i32
        cf.cond_br %364, ^bb15, ^bb16
        ^bb15:
          %366 = llvm.load %356 : !llvm.ptr -> i32
          %367 = arith.extsi %366 : i32 to i64
          %368 = llvm.getelementptr %arg0[%367] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %365 = llvm.load %368 : !llvm.ptr -> i32
          %369 = llvm.load %356 : !llvm.ptr -> i32
          %370 = arith.constant 1 : i32
          %371 = arith.addi %369, %370 : i32
          %372 = arith.extsi %371 : i32 to i64
          %373 = llvm.getelementptr %arg0[%372] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %365, %373 : i32, !llvm.ptr
          %374 = llvm.load %356 : !llvm.ptr -> i32
          %375 = arith.constant 1 : i32
          %376 = arith.subi %374, %375 : i32
          llvm.store %376, %356 : i32, !llvm.ptr
          cf.br ^bb17
        ^bb16:
          cf.br ^bb14
        ^bb17:
        cf.br ^bb12
      ^bb14:
      %377 = llvm.load %356 : !llvm.ptr -> i32
      %378 = arith.constant 1 : i32
      %379 = arith.addi %377, %378 : i32
      %380 = arith.extsi %379 : i32 to i64
      %381 = llvm.getelementptr %arg0[%380] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %348, %381 : i32, !llvm.ptr
      %382 = llvm.load %345 : !llvm.ptr -> i32
      %383 = arith.constant 1 : i32
      %384 = arith.addi %382, %383 : i32
      llvm.store %384, %345 : i32, !llvm.ptr
      cf.br ^bb9
    ^bb11:
    func.return
  }
  func.func @unique_i32(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
    %385 = arith.constant 1 : i32
    %386 = arith.cmpi sle, %arg1, %385 : i32
    cf.cond_br %386, ^bb18, ^bb19
    ^bb18:
      func.return %arg1 : i32
    ^bb19:
      cf.br ^bb20
    ^bb20:
    %387 = arith.constant 1 : i32
    %388 = llvm.mlir.constant(1 : i64) : i64
    %389 = llvm.alloca %388 x i32 : (i64) -> !llvm.ptr
    llvm.store %387, %389 : i32, !llvm.ptr
    %390 = arith.constant 1 : i32
    %391 = llvm.mlir.constant(1 : i64) : i64
    %392 = llvm.alloca %391 x i32 : (i64) -> !llvm.ptr
    llvm.store %390, %392 : i32, !llvm.ptr
    cf.br ^bb21
    ^bb21:
    %393 = llvm.load %392 : !llvm.ptr -> i32
    %394 = arith.cmpi slt, %393, %arg1 : i32
    cf.cond_br %394, ^bb22, ^bb23
    ^bb22:
      %396 = llvm.load %392 : !llvm.ptr -> i32
      %397 = arith.extsi %396 : i32 to i64
      %398 = llvm.getelementptr %arg0[%397] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %395 = llvm.load %398 : !llvm.ptr -> i32
      %400 = llvm.load %392 : !llvm.ptr -> i32
      %401 = arith.constant 1 : i32
      %402 = arith.subi %400, %401 : i32
      %403 = arith.extsi %402 : i32 to i64
      %404 = llvm.getelementptr %arg0[%403] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %399 = llvm.load %404 : !llvm.ptr -> i32
      %405 = arith.cmpi ne, %395, %399 : i32
      cf.cond_br %405, ^bb24, ^bb25
      ^bb24:
        %407 = llvm.load %392 : !llvm.ptr -> i32
        %408 = arith.extsi %407 : i32 to i64
        %409 = llvm.getelementptr %arg0[%408] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %406 = llvm.load %409 : !llvm.ptr -> i32
        %410 = llvm.load %389 : !llvm.ptr -> i32
        %411 = arith.extsi %410 : i32 to i64
        %412 = llvm.getelementptr %arg0[%411] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %406, %412 : i32, !llvm.ptr
        %413 = llvm.load %389 : !llvm.ptr -> i32
        %414 = arith.constant 1 : i32
        %415 = arith.addi %413, %414 : i32
        llvm.store %415, %389 : i32, !llvm.ptr
        cf.br ^bb26
      ^bb25:
        cf.br ^bb26
      ^bb26:
      %416 = llvm.load %392 : !llvm.ptr -> i32
      %417 = arith.constant 1 : i32
      %418 = arith.addi %416, %417 : i32
      llvm.store %418, %392 : i32, !llvm.ptr
      cf.br ^bb21
    ^bb23:
    %419 = llvm.load %389 : !llvm.ptr -> i32
    func.return %419 : i32
  }
  func.func @next_perm(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
    %420 = arith.constant 1 : i32
    %421 = arith.cmpi sle, %arg1, %420 : i32
    cf.cond_br %421, ^bb27, ^bb28
    ^bb27:
      %422 = arith.constant 0 : i32
      func.return %422 : i32
    ^bb28:
      cf.br ^bb29
    ^bb29:
    %423 = arith.constant 2 : i32
    %424 = arith.subi %arg1, %423 : i32
    %425 = llvm.mlir.constant(1 : i64) : i64
    %426 = llvm.alloca %425 x i32 : (i64) -> !llvm.ptr
    llvm.store %424, %426 : i32, !llvm.ptr
    cf.br ^bb30
    ^bb30:
    %427 = llvm.load %426 : !llvm.ptr -> i32
    %428 = arith.constant 0 : i32
    %429 = arith.cmpi sge, %427, %428 : i32
    cf.cond_br %429, ^bb31, ^bb32
    ^bb31:
      %431 = llvm.load %426 : !llvm.ptr -> i32
      %432 = arith.extsi %431 : i32 to i64
      %433 = llvm.getelementptr %arg0[%432] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %430 = llvm.load %433 : !llvm.ptr -> i32
      %435 = llvm.load %426 : !llvm.ptr -> i32
      %436 = arith.constant 1 : i32
      %437 = arith.addi %435, %436 : i32
      %438 = arith.extsi %437 : i32 to i64
      %439 = llvm.getelementptr %arg0[%438] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %434 = llvm.load %439 : !llvm.ptr -> i32
      %440 = arith.cmpi slt, %430, %434 : i32
      cf.cond_br %440, ^bb33, ^bb34
      ^bb33:
        cf.br ^bb32
      ^bb34:
        cf.br ^bb35
      ^bb35:
      %441 = llvm.load %426 : !llvm.ptr -> i32
      %442 = arith.constant 1 : i32
      %443 = arith.subi %441, %442 : i32
      llvm.store %443, %426 : i32, !llvm.ptr
      cf.br ^bb30
    ^bb32:
    %444 = llvm.load %426 : !llvm.ptr -> i32
    %445 = arith.constant 0 : i32
    %446 = arith.cmpi slt, %444, %445 : i32
    cf.cond_br %446, ^bb36, ^bb37
    ^bb36:
      %447 = arith.constant 0 : i32
      func.return %447 : i32
    ^bb37:
      cf.br ^bb38
    ^bb38:
    %448 = arith.constant 1 : i32
    %449 = arith.subi %arg1, %448 : i32
    %450 = llvm.mlir.constant(1 : i64) : i64
    %451 = llvm.alloca %450 x i32 : (i64) -> !llvm.ptr
    llvm.store %449, %451 : i32, !llvm.ptr
    cf.br ^bb39
    ^bb39:
    %452 = llvm.load %451 : !llvm.ptr -> i32
    %453 = llvm.load %426 : !llvm.ptr -> i32
    %454 = arith.cmpi sgt, %452, %453 : i32
    cf.cond_br %454, ^bb40, ^bb41
    ^bb40:
      %456 = llvm.load %451 : !llvm.ptr -> i32
      %457 = arith.extsi %456 : i32 to i64
      %458 = llvm.getelementptr %arg0[%457] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %455 = llvm.load %458 : !llvm.ptr -> i32
      %460 = llvm.load %426 : !llvm.ptr -> i32
      %461 = arith.extsi %460 : i32 to i64
      %462 = llvm.getelementptr %arg0[%461] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %459 = llvm.load %462 : !llvm.ptr -> i32
      %463 = arith.cmpi sgt, %455, %459 : i32
      cf.cond_br %463, ^bb42, ^bb43
      ^bb42:
        cf.br ^bb41
      ^bb43:
        cf.br ^bb44
      ^bb44:
      %464 = llvm.load %451 : !llvm.ptr -> i32
      %465 = arith.constant 1 : i32
      %466 = arith.subi %464, %465 : i32
      llvm.store %466, %451 : i32, !llvm.ptr
      cf.br ^bb39
    ^bb41:
    %468 = llvm.load %426 : !llvm.ptr -> i32
    %469 = arith.extsi %468 : i32 to i64
    %470 = llvm.getelementptr %arg0[%469] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %467 = llvm.load %470 : !llvm.ptr -> i32
    %472 = llvm.load %451 : !llvm.ptr -> i32
    %473 = arith.extsi %472 : i32 to i64
    %474 = llvm.getelementptr %arg0[%473] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %471 = llvm.load %474 : !llvm.ptr -> i32
    %475 = llvm.load %426 : !llvm.ptr -> i32
    %476 = arith.extsi %475 : i32 to i64
    %477 = llvm.getelementptr %arg0[%476] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %471, %477 : i32, !llvm.ptr
    %478 = llvm.load %451 : !llvm.ptr -> i32
    %479 = arith.extsi %478 : i32 to i64
    %480 = llvm.getelementptr %arg0[%479] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %467, %480 : i32, !llvm.ptr
    %481 = llvm.load %426 : !llvm.ptr -> i32
    %482 = arith.constant 1 : i32
    %483 = arith.addi %481, %482 : i32
    %484 = llvm.mlir.constant(1 : i64) : i64
    %485 = llvm.alloca %484 x i32 : (i64) -> !llvm.ptr
    llvm.store %483, %485 : i32, !llvm.ptr
    %486 = arith.constant 1 : i32
    %487 = arith.subi %arg1, %486 : i32
    %488 = llvm.mlir.constant(1 : i64) : i64
    %489 = llvm.alloca %488 x i32 : (i64) -> !llvm.ptr
    llvm.store %487, %489 : i32, !llvm.ptr
    cf.br ^bb45
    ^bb45:
    %490 = llvm.load %485 : !llvm.ptr -> i32
    %491 = llvm.load %489 : !llvm.ptr -> i32
    %492 = arith.cmpi slt, %490, %491 : i32
    cf.cond_br %492, ^bb46, ^bb47
    ^bb46:
      %494 = llvm.load %485 : !llvm.ptr -> i32
      %495 = arith.extsi %494 : i32 to i64
      %496 = llvm.getelementptr %arg0[%495] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %493 = llvm.load %496 : !llvm.ptr -> i32
      %498 = llvm.load %489 : !llvm.ptr -> i32
      %499 = arith.extsi %498 : i32 to i64
      %500 = llvm.getelementptr %arg0[%499] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %497 = llvm.load %500 : !llvm.ptr -> i32
      %501 = llvm.load %485 : !llvm.ptr -> i32
      %502 = arith.extsi %501 : i32 to i64
      %503 = llvm.getelementptr %arg0[%502] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %497, %503 : i32, !llvm.ptr
      %504 = llvm.load %489 : !llvm.ptr -> i32
      %505 = arith.extsi %504 : i32 to i64
      %506 = llvm.getelementptr %arg0[%505] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %493, %506 : i32, !llvm.ptr
      %507 = llvm.load %485 : !llvm.ptr -> i32
      %508 = arith.constant 1 : i32
      %509 = arith.addi %507, %508 : i32
      llvm.store %509, %485 : i32, !llvm.ptr
      %510 = llvm.load %489 : !llvm.ptr -> i32
      %511 = arith.constant 1 : i32
      %512 = arith.subi %510, %511 : i32
      llvm.store %512, %489 : i32, !llvm.ptr
      cf.br ^bb45
    ^bb47:
    %513 = arith.constant 1 : i32
    func.return %513 : i32
  }
  func.func @init_perms() -> () {
    %514 = llvm.mlir.addressof @perms_init_done : !llvm.ptr
    %515 = llvm.load %514 : !llvm.ptr -> i32
    %516 = arith.constant 1 : i32
    %517 = arith.cmpi eq, %515, %516 : i32
    cf.cond_br %517, ^bb48, ^bb49
    ^bb48:
      func.return
    ^bb49:
      cf.br ^bb50
    ^bb50:
    %518 = arith.constant 1 : i32
    %519 = llvm.mlir.addressof @perms_init_done : !llvm.ptr
    llvm.store %518, %519 : i32, !llvm.ptr
    %520 = llvm.mlir.addressof @perm_buf : !llvm.ptr
    %521 = llvm.load %520 : !llvm.ptr -> !llvm.ptr
    %522 = arith.constant 0 : i32
    %523 = llvm.mlir.constant(1 : i64) : i64
    %524 = llvm.alloca %523 x i32 : (i64) -> !llvm.ptr
    llvm.store %522, %524 : i32, !llvm.ptr
    cf.br ^bb51
    ^bb51:
    %525 = llvm.load %524 : !llvm.ptr -> i32
    %526 = arith.constant 9 : i32
    %527 = arith.cmpi slt, %525, %526 : i32
    cf.cond_br %527, ^bb52, ^bb53
    ^bb52:
      %528 = llvm.load %524 : !llvm.ptr -> i32
      %529 = arith.constant 1 : i32
      %530 = arith.addi %528, %529 : i32
      %531 = llvm.load %524 : !llvm.ptr -> i32
      %532 = arith.extsi %531 : i32 to i64
      %533 = llvm.getelementptr %521[%532] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %530, %533 : i32, !llvm.ptr
      %534 = llvm.load %524 : !llvm.ptr -> i32
      %535 = arith.constant 1 : i32
      %536 = arith.addi %534, %535 : i32
      llvm.store %536, %524 : i32, !llvm.ptr
      cf.br ^bb51
    ^bb53:
    %538 = arith.constant 10 : i32
    %539 = arith.constant 4 : i32
    %540 = arith.extsi %538 : i32 to i64
    %541 = arith.extsi %539 : i32 to i64
    %537 = func.call @calloc(%540, %541) : (i64, i64) -> !llvm.ptr
    %543 = arith.constant 10 : i32
    %544 = arith.constant 4 : i32
    %545 = arith.extsi %543 : i32 to i64
    %546 = arith.extsi %544 : i32 to i64
    %542 = func.call @calloc(%545, %546) : (i64, i64) -> !llvm.ptr
    %547 = arith.constant 1 : i32
    %548 = llvm.mlir.constant(1 : i64) : i64
    %549 = llvm.alloca %548 x i32 : (i64) -> !llvm.ptr
    llvm.store %547, %549 : i32, !llvm.ptr
    cf.br ^bb54
    ^bb54:
    %550 = llvm.load %549 : !llvm.ptr -> i32
    %551 = arith.constant 6 : i32
    %552 = arith.cmpi sle, %550, %551 : i32
    cf.cond_br %552, ^bb55, ^bb56
    ^bb55:
      %553 = arith.constant 0 : i32
      %554 = llvm.mlir.constant(1 : i64) : i64
      %555 = llvm.alloca %554 x i32 : (i64) -> !llvm.ptr
      llvm.store %553, %555 : i32, !llvm.ptr
      cf.br ^bb57
      ^bb57:
      %556 = llvm.load %555 : !llvm.ptr -> i32
      %557 = arith.constant 9 : i32
      %558 = arith.cmpi slt, %556, %557 : i32
      cf.cond_br %558, ^bb58, ^bb59
      ^bb58:
        %559 = llvm.load %555 : !llvm.ptr -> i32
        %560 = arith.constant 9 : i32
        %561 = llvm.load %549 : !llvm.ptr -> i32
        %562 = arith.subi %560, %561 : i32
        %563 = arith.cmpi slt, %559, %562 : i32
        cf.cond_br %563, ^bb60, ^bb61
        ^bb60:
          %564 = arith.constant 0 : i32
          %565 = llvm.load %555 : !llvm.ptr -> i32
          %566 = arith.extsi %565 : i32 to i64
          %567 = llvm.getelementptr %542[%566] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %564, %567 : i32, !llvm.ptr
          cf.br ^bb62
        ^bb61:
          %568 = arith.constant 1 : i32
          %569 = llvm.load %555 : !llvm.ptr -> i32
          %570 = arith.extsi %569 : i32 to i64
          %571 = llvm.getelementptr %542[%570] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %568, %571 : i32, !llvm.ptr
          cf.br ^bb62
        ^bb62:
        %572 = llvm.load %555 : !llvm.ptr -> i32
        %573 = arith.constant 1 : i32
        %574 = arith.addi %572, %573 : i32
        llvm.store %574, %555 : i32, !llvm.ptr
        cf.br ^bb57
      ^bb59:
      %575 = arith.constant 1 : i32
      %576 = llvm.mlir.constant(1 : i64) : i64
      %577 = llvm.alloca %576 x i32 : (i64) -> !llvm.ptr
      llvm.store %575, %577 : i32, !llvm.ptr
      cf.br ^bb63
      ^bb63:
      %578 = llvm.load %577 : !llvm.ptr -> i32
      %579 = arith.constant 1 : i32
      %580 = arith.cmpi eq, %578, %579 : i32
      %581 = scf.if %580 -> (i1) {
        %582 = arith.constant true
        scf.yield %582 : i1
      } else {
        %584 = arith.constant 9 : i32
        %583 = func.call @next_perm(%542, %584) : (!llvm.ptr, i32) -> i32
        %585 = arith.constant 1 : i32
        %586 = arith.cmpi eq, %583, %585 : i32
        scf.yield %586 : i1
      }
      cf.cond_br %581, ^bb64, ^bb65
      ^bb64:
        %587 = arith.constant 0 : i32
        llvm.store %587, %577 : i32, !llvm.ptr
        %588 = arith.constant 0 : i32
        %589 = llvm.mlir.constant(1 : i64) : i64
        %590 = llvm.alloca %589 x i32 : (i64) -> !llvm.ptr
        llvm.store %588, %590 : i32, !llvm.ptr
        %591 = arith.constant 0 : i32
        %592 = llvm.mlir.constant(1 : i64) : i64
        %593 = llvm.alloca %592 x i32 : (i64) -> !llvm.ptr
        llvm.store %591, %593 : i32, !llvm.ptr
        cf.br ^bb66
        ^bb66:
        %594 = llvm.load %593 : !llvm.ptr -> i32
        %595 = arith.constant 9 : i32
        %596 = arith.cmpi slt, %594, %595 : i32
        cf.cond_br %596, ^bb67, ^bb68
        ^bb67:
          %598 = llvm.load %593 : !llvm.ptr -> i32
          %599 = arith.extsi %598 : i32 to i64
          %600 = llvm.getelementptr %542[%599] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %597 = llvm.load %600 : !llvm.ptr -> i32
          %601 = arith.constant 1 : i32
          %602 = arith.cmpi eq, %597, %601 : i32
          cf.cond_br %602, ^bb69, ^bb70
          ^bb69:
            %604 = llvm.load %593 : !llvm.ptr -> i32
            %605 = arith.extsi %604 : i32 to i64
            %606 = llvm.getelementptr %521[%605] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %603 = llvm.load %606 : !llvm.ptr -> i32
            %607 = llvm.load %590 : !llvm.ptr -> i32
            %608 = arith.extsi %607 : i32 to i64
            %609 = llvm.getelementptr %537[%608] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %603, %609 : i32, !llvm.ptr
            %610 = llvm.load %590 : !llvm.ptr -> i32
            %611 = arith.constant 1 : i32
            %612 = arith.addi %610, %611 : i32
            llvm.store %612, %590 : i32, !llvm.ptr
            cf.br ^bb71
          ^bb70:
            cf.br ^bb71
          ^bb71:
          %613 = llvm.load %593 : !llvm.ptr -> i32
          %614 = arith.constant 1 : i32
          %615 = arith.addi %613, %614 : i32
          llvm.store %615, %593 : i32, !llvm.ptr
          cf.br ^bb66
        ^bb68:
        %617 = llvm.load %549 : !llvm.ptr -> i32
        func.call @sort_i32(%537, %617) : (!llvm.ptr, i32) -> ()
        %618 = arith.constant 1 : i32
        %619 = llvm.mlir.constant(1 : i64) : i64
        %620 = llvm.alloca %619 x i32 : (i64) -> !llvm.ptr
        llvm.store %618, %620 : i32, !llvm.ptr
        cf.br ^bb72
        ^bb72:
        %621 = llvm.load %620 : !llvm.ptr -> i32
        %622 = arith.constant 1 : i32
        %623 = arith.cmpi eq, %621, %622 : i32
        %624 = scf.if %623 -> (i1) {
          %625 = arith.constant true
          scf.yield %625 : i1
        } else {
          %627 = llvm.load %549 : !llvm.ptr -> i32
          %626 = func.call @next_perm(%537, %627) : (!llvm.ptr, i32) -> i32
          %628 = arith.constant 1 : i32
          %629 = arith.cmpi eq, %626, %628 : i32
          scf.yield %629 : i1
        }
        cf.cond_br %624, ^bb73, ^bb74
        ^bb73:
          %630 = arith.constant 0 : i32
          llvm.store %630, %620 : i32, !llvm.ptr
          %631 = arith.constant 0 : i32
          %632 = llvm.mlir.constant(1 : i64) : i64
          %633 = llvm.alloca %632 x i32 : (i64) -> !llvm.ptr
          llvm.store %631, %633 : i32, !llvm.ptr
          %634 = arith.constant 0 : i32
          %635 = llvm.mlir.constant(1 : i64) : i64
          %636 = llvm.alloca %635 x i32 : (i64) -> !llvm.ptr
          llvm.store %634, %636 : i32, !llvm.ptr
          cf.br ^bb75
          ^bb75:
          %637 = llvm.load %636 : !llvm.ptr -> i32
          %638 = llvm.load %549 : !llvm.ptr -> i32
          %639 = arith.cmpi slt, %637, %638 : i32
          cf.cond_br %639, ^bb76, ^bb77
          ^bb76:
            %640 = llvm.load %633 : !llvm.ptr -> i32
            %642 = llvm.load %636 : !llvm.ptr -> i32
            %643 = arith.extsi %642 : i32 to i64
            %644 = llvm.getelementptr %537[%643] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %641 = llvm.load %644 : !llvm.ptr -> i32
            %645 = arith.addi %640, %641 : i32
            llvm.store %645, %633 : i32, !llvm.ptr
            %646 = llvm.load %636 : !llvm.ptr -> i32
            %647 = arith.constant 1 : i32
            %648 = arith.addi %646, %647 : i32
            llvm.store %648, %636 : i32, !llvm.ptr
            cf.br ^bb75
          ^bb77:
          %649 = llvm.load %549 : !llvm.ptr -> i32
          %650 = arith.constant 46 : i32
          %651 = arith.muli %649, %650 : i32
          %652 = llvm.load %633 : !llvm.ptr -> i32
          %653 = arith.addi %651, %652 : i32
          %655 = llvm.mlir.addressof @perms_count : !llvm.ptr
          %656 = llvm.load %655 : !llvm.ptr -> !llvm.ptr
          %657 = arith.extsi %653 : i32 to i64
          %658 = llvm.getelementptr %656[%657] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %654 = llvm.load %658 : !llvm.ptr -> i32
          %659 = arith.constant 1 : i32
          %660 = arith.addi %654, %659 : i32
          %661 = llvm.mlir.addressof @perms_count : !llvm.ptr
          %662 = llvm.load %661 : !llvm.ptr -> !llvm.ptr
          %663 = arith.extsi %653 : i32 to i64
          %664 = llvm.getelementptr %662[%663] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %660, %664 : i32, !llvm.ptr
          %665 = llvm.mlir.addressof @perms_total : !llvm.ptr
          %666 = llvm.load %665 : !llvm.ptr -> i32
          %667 = arith.constant 1 : i32
          %668 = arith.addi %666, %667 : i32
          %669 = llvm.mlir.addressof @perms_total : !llvm.ptr
          llvm.store %668, %669 : i32, !llvm.ptr
          cf.br ^bb72
        ^bb74:
        cf.br ^bb63
      ^bb65:
      %670 = llvm.load %549 : !llvm.ptr -> i32
      %671 = arith.constant 1 : i32
      %672 = arith.addi %670, %671 : i32
      llvm.store %672, %549 : i32, !llvm.ptr
      cf.br ^bb54
    ^bb56:
    %673 = arith.constant 0 : i32
    %674 = llvm.mlir.constant(1 : i64) : i64
    %675 = llvm.alloca %674 x i32 : (i64) -> !llvm.ptr
    llvm.store %673, %675 : i32, !llvm.ptr
    %676 = arith.constant 0 : i32
    %677 = llvm.mlir.constant(1 : i64) : i64
    %678 = llvm.alloca %677 x i32 : (i64) -> !llvm.ptr
    llvm.store %676, %678 : i32, !llvm.ptr
    cf.br ^bb78
    ^bb78:
    %679 = llvm.load %678 : !llvm.ptr -> i32
    %680 = arith.constant 7 : i32
    %681 = arith.constant 46 : i32
    %682 = arith.muli %680, %681 : i32
    %683 = arith.cmpi slt, %679, %682 : i32
    cf.cond_br %683, ^bb79, ^bb80
    ^bb79:
      %684 = llvm.load %675 : !llvm.ptr -> i32
      %685 = llvm.mlir.addressof @perms_offset : !llvm.ptr
      %686 = llvm.load %685 : !llvm.ptr -> !llvm.ptr
      %687 = llvm.load %678 : !llvm.ptr -> i32
      %688 = arith.extsi %687 : i32 to i64
      %689 = llvm.getelementptr %686[%688] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %684, %689 : i32, !llvm.ptr
      %690 = llvm.load %678 : !llvm.ptr -> i32
      %691 = arith.constant 46 : i32
      %692 = arith.divsi %690, %691 : i32
      %693 = llvm.load %675 : !llvm.ptr -> i32
      %695 = llvm.mlir.addressof @perms_count : !llvm.ptr
      %696 = llvm.load %695 : !llvm.ptr -> !llvm.ptr
      %697 = llvm.load %678 : !llvm.ptr -> i32
      %698 = arith.extsi %697 : i32 to i64
      %699 = llvm.getelementptr %696[%698] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %694 = llvm.load %699 : !llvm.ptr -> i32
      %700 = arith.muli %694, %692 : i32
      %701 = arith.addi %693, %700 : i32
      llvm.store %701, %675 : i32, !llvm.ptr
      %702 = llvm.load %678 : !llvm.ptr -> i32
      %703 = arith.constant 1 : i32
      %704 = arith.addi %702, %703 : i32
      llvm.store %704, %678 : i32, !llvm.ptr
      cf.br ^bb78
    ^bb80:
    %706 = arith.constant 7 : i32
    %707 = arith.constant 46 : i32
    %708 = arith.muli %706, %707 : i32
    %709 = arith.constant 4 : i32
    %710 = arith.extsi %708 : i32 to i64
    %711 = arith.extsi %709 : i32 to i64
    %705 = func.call @calloc(%710, %711) : (i64, i64) -> !llvm.ptr
    %712 = arith.constant 0 : i32
    llvm.store %712, %678 : i32, !llvm.ptr
    cf.br ^bb81
    ^bb81:
    %713 = llvm.load %678 : !llvm.ptr -> i32
    %714 = arith.constant 7 : i32
    %715 = arith.constant 46 : i32
    %716 = arith.muli %714, %715 : i32
    %717 = arith.cmpi slt, %713, %716 : i32
    cf.cond_br %717, ^bb82, ^bb83
    ^bb82:
      %719 = llvm.mlir.addressof @perms_offset : !llvm.ptr
      %720 = llvm.load %719 : !llvm.ptr -> !llvm.ptr
      %721 = llvm.load %678 : !llvm.ptr -> i32
      %722 = arith.extsi %721 : i32 to i64
      %723 = llvm.getelementptr %720[%722] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %718 = llvm.load %723 : !llvm.ptr -> i32
      %724 = llvm.load %678 : !llvm.ptr -> i32
      %725 = arith.extsi %724 : i32 to i64
      %726 = llvm.getelementptr %705[%725] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %718, %726 : i32, !llvm.ptr
      %727 = llvm.load %678 : !llvm.ptr -> i32
      %728 = arith.constant 1 : i32
      %729 = arith.addi %727, %728 : i32
      llvm.store %729, %678 : i32, !llvm.ptr
      cf.br ^bb81
    ^bb83:
    %730 = arith.constant 1 : i32
    llvm.store %730, %549 : i32, !llvm.ptr
    cf.br ^bb84
    ^bb84:
    %731 = llvm.load %549 : !llvm.ptr -> i32
    %732 = arith.constant 6 : i32
    %733 = arith.cmpi sle, %731, %732 : i32
    cf.cond_br %733, ^bb85, ^bb86
    ^bb85:
      %734 = arith.constant 0 : i32
      %735 = llvm.mlir.constant(1 : i64) : i64
      %736 = llvm.alloca %735 x i32 : (i64) -> !llvm.ptr
      llvm.store %734, %736 : i32, !llvm.ptr
      cf.br ^bb87
      ^bb87:
      %737 = llvm.load %736 : !llvm.ptr -> i32
      %738 = arith.constant 9 : i32
      %739 = arith.cmpi slt, %737, %738 : i32
      cf.cond_br %739, ^bb88, ^bb89
      ^bb88:
        %740 = llvm.load %736 : !llvm.ptr -> i32
        %741 = arith.constant 9 : i32
        %742 = llvm.load %549 : !llvm.ptr -> i32
        %743 = arith.subi %741, %742 : i32
        %744 = arith.cmpi slt, %740, %743 : i32
        cf.cond_br %744, ^bb90, ^bb91
        ^bb90:
          %745 = arith.constant 0 : i32
          %746 = llvm.load %736 : !llvm.ptr -> i32
          %747 = arith.extsi %746 : i32 to i64
          %748 = llvm.getelementptr %542[%747] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %745, %748 : i32, !llvm.ptr
          cf.br ^bb92
        ^bb91:
          %749 = arith.constant 1 : i32
          %750 = llvm.load %736 : !llvm.ptr -> i32
          %751 = arith.extsi %750 : i32 to i64
          %752 = llvm.getelementptr %542[%751] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %749, %752 : i32, !llvm.ptr
          cf.br ^bb92
        ^bb92:
        %753 = llvm.load %736 : !llvm.ptr -> i32
        %754 = arith.constant 1 : i32
        %755 = arith.addi %753, %754 : i32
        llvm.store %755, %736 : i32, !llvm.ptr
        cf.br ^bb87
      ^bb89:
      %756 = arith.constant 1 : i32
      %757 = llvm.mlir.constant(1 : i64) : i64
      %758 = llvm.alloca %757 x i32 : (i64) -> !llvm.ptr
      llvm.store %756, %758 : i32, !llvm.ptr
      cf.br ^bb93
      ^bb93:
      %759 = llvm.load %758 : !llvm.ptr -> i32
      %760 = arith.constant 1 : i32
      %761 = arith.cmpi eq, %759, %760 : i32
      %762 = scf.if %761 -> (i1) {
        %763 = arith.constant true
        scf.yield %763 : i1
      } else {
        %765 = arith.constant 9 : i32
        %764 = func.call @next_perm(%542, %765) : (!llvm.ptr, i32) -> i32
        %766 = arith.constant 1 : i32
        %767 = arith.cmpi eq, %764, %766 : i32
        scf.yield %767 : i1
      }
      cf.cond_br %762, ^bb94, ^bb95
      ^bb94:
        %768 = arith.constant 0 : i32
        llvm.store %768, %758 : i32, !llvm.ptr
        %769 = arith.constant 0 : i32
        %770 = llvm.mlir.constant(1 : i64) : i64
        %771 = llvm.alloca %770 x i32 : (i64) -> !llvm.ptr
        llvm.store %769, %771 : i32, !llvm.ptr
        %772 = arith.constant 0 : i32
        %773 = llvm.mlir.constant(1 : i64) : i64
        %774 = llvm.alloca %773 x i32 : (i64) -> !llvm.ptr
        llvm.store %772, %774 : i32, !llvm.ptr
        cf.br ^bb96
        ^bb96:
        %775 = llvm.load %774 : !llvm.ptr -> i32
        %776 = arith.constant 9 : i32
        %777 = arith.cmpi slt, %775, %776 : i32
        cf.cond_br %777, ^bb97, ^bb98
        ^bb97:
          %779 = llvm.load %774 : !llvm.ptr -> i32
          %780 = arith.extsi %779 : i32 to i64
          %781 = llvm.getelementptr %542[%780] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %778 = llvm.load %781 : !llvm.ptr -> i32
          %782 = arith.constant 1 : i32
          %783 = arith.cmpi eq, %778, %782 : i32
          cf.cond_br %783, ^bb99, ^bb100
          ^bb99:
            %785 = llvm.load %774 : !llvm.ptr -> i32
            %786 = arith.extsi %785 : i32 to i64
            %787 = llvm.getelementptr %521[%786] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %784 = llvm.load %787 : !llvm.ptr -> i32
            %788 = llvm.load %771 : !llvm.ptr -> i32
            %789 = arith.extsi %788 : i32 to i64
            %790 = llvm.getelementptr %537[%789] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %784, %790 : i32, !llvm.ptr
            %791 = llvm.load %771 : !llvm.ptr -> i32
            %792 = arith.constant 1 : i32
            %793 = arith.addi %791, %792 : i32
            llvm.store %793, %771 : i32, !llvm.ptr
            cf.br ^bb101
          ^bb100:
            cf.br ^bb101
          ^bb101:
          %794 = llvm.load %774 : !llvm.ptr -> i32
          %795 = arith.constant 1 : i32
          %796 = arith.addi %794, %795 : i32
          llvm.store %796, %774 : i32, !llvm.ptr
          cf.br ^bb96
        ^bb98:
        %798 = llvm.load %549 : !llvm.ptr -> i32
        func.call @sort_i32(%537, %798) : (!llvm.ptr, i32) -> ()
        %799 = arith.constant 1 : i32
        %800 = llvm.mlir.constant(1 : i64) : i64
        %801 = llvm.alloca %800 x i32 : (i64) -> !llvm.ptr
        llvm.store %799, %801 : i32, !llvm.ptr
        cf.br ^bb102
        ^bb102:
        %802 = llvm.load %801 : !llvm.ptr -> i32
        %803 = arith.constant 1 : i32
        %804 = arith.cmpi eq, %802, %803 : i32
        %805 = scf.if %804 -> (i1) {
          %806 = arith.constant true
          scf.yield %806 : i1
        } else {
          %808 = llvm.load %549 : !llvm.ptr -> i32
          %807 = func.call @next_perm(%537, %808) : (!llvm.ptr, i32) -> i32
          %809 = arith.constant 1 : i32
          %810 = arith.cmpi eq, %807, %809 : i32
          scf.yield %810 : i1
        }
        cf.cond_br %805, ^bb103, ^bb104
        ^bb103:
          %811 = arith.constant 0 : i32
          llvm.store %811, %801 : i32, !llvm.ptr
          %812 = arith.constant 0 : i32
          %813 = llvm.mlir.constant(1 : i64) : i64
          %814 = llvm.alloca %813 x i32 : (i64) -> !llvm.ptr
          llvm.store %812, %814 : i32, !llvm.ptr
          %815 = arith.constant 0 : i32
          %816 = llvm.mlir.constant(1 : i64) : i64
          %817 = llvm.alloca %816 x i32 : (i64) -> !llvm.ptr
          llvm.store %815, %817 : i32, !llvm.ptr
          cf.br ^bb105
          ^bb105:
          %818 = llvm.load %817 : !llvm.ptr -> i32
          %819 = llvm.load %549 : !llvm.ptr -> i32
          %820 = arith.cmpi slt, %818, %819 : i32
          cf.cond_br %820, ^bb106, ^bb107
          ^bb106:
            %821 = llvm.load %814 : !llvm.ptr -> i32
            %823 = llvm.load %817 : !llvm.ptr -> i32
            %824 = arith.extsi %823 : i32 to i64
            %825 = llvm.getelementptr %537[%824] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %822 = llvm.load %825 : !llvm.ptr -> i32
            %826 = arith.addi %821, %822 : i32
            llvm.store %826, %814 : i32, !llvm.ptr
            %827 = llvm.load %817 : !llvm.ptr -> i32
            %828 = arith.constant 1 : i32
            %829 = arith.addi %827, %828 : i32
            llvm.store %829, %817 : i32, !llvm.ptr
            cf.br ^bb105
          ^bb107:
          %830 = llvm.load %549 : !llvm.ptr -> i32
          %831 = arith.constant 46 : i32
          %832 = arith.muli %830, %831 : i32
          %833 = llvm.load %814 : !llvm.ptr -> i32
          %834 = arith.addi %832, %833 : i32
          %836 = arith.extsi %834 : i32 to i64
          %837 = llvm.getelementptr %705[%836] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %835 = llvm.load %837 : !llvm.ptr -> i32
          %838 = arith.constant 0 : i32
          %839 = llvm.mlir.constant(1 : i64) : i64
          %840 = llvm.alloca %839 x i32 : (i64) -> !llvm.ptr
          llvm.store %838, %840 : i32, !llvm.ptr
          cf.br ^bb108
          ^bb108:
          %841 = llvm.load %840 : !llvm.ptr -> i32
          %842 = llvm.load %549 : !llvm.ptr -> i32
          %843 = arith.cmpi slt, %841, %842 : i32
          cf.cond_br %843, ^bb109, ^bb110
          ^bb109:
            %845 = llvm.load %840 : !llvm.ptr -> i32
            %846 = arith.extsi %845 : i32 to i64
            %847 = llvm.getelementptr %537[%846] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %844 = llvm.load %847 : !llvm.ptr -> i32
            %848 = llvm.mlir.addressof @perms_data : !llvm.ptr
            %849 = llvm.load %848 : !llvm.ptr -> !llvm.ptr
            %850 = llvm.load %840 : !llvm.ptr -> i32
            %851 = arith.addi %835, %850 : i32
            %852 = arith.extsi %851 : i32 to i64
            %853 = llvm.getelementptr %849[%852] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %844, %853 : i32, !llvm.ptr
            %854 = llvm.load %840 : !llvm.ptr -> i32
            %855 = arith.constant 1 : i32
            %856 = arith.addi %854, %855 : i32
            llvm.store %856, %840 : i32, !llvm.ptr
            cf.br ^bb108
          ^bb110:
          %857 = llvm.load %549 : !llvm.ptr -> i32
          %858 = arith.addi %835, %857 : i32
          %859 = arith.extsi %834 : i32 to i64
          %860 = llvm.getelementptr %705[%859] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %858, %860 : i32, !llvm.ptr
          cf.br ^bb102
        ^bb104:
        cf.br ^bb93
      ^bb95:
      %861 = llvm.load %549 : !llvm.ptr -> i32
      %862 = arith.constant 1 : i32
      %863 = arith.addi %861, %862 : i32
      llvm.store %863, %549 : i32, !llvm.ptr
      cf.br ^bb84
    ^bb86:
    func.call @free(%705) : (!llvm.ptr) -> ()
    func.call @free(%537) : (!llvm.ptr) -> ()
    func.call @free(%542) : (!llvm.ptr) -> ()
    func.return
  }
  func.func @get_perm(%arg0: i32, %arg1: i32, %arg2: i32) -> () {
    %867 = arith.constant 46 : i32
    %868 = arith.muli %arg0, %867 : i32
    %869 = arith.addi %868, %arg1 : i32
    %871 = llvm.mlir.addressof @perms_offset : !llvm.ptr
    %872 = llvm.load %871 : !llvm.ptr -> !llvm.ptr
    %873 = arith.extsi %869 : i32 to i64
    %874 = llvm.getelementptr %872[%873] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %870 = llvm.load %874 : !llvm.ptr -> i32
    %875 = arith.muli %arg2, %arg0 : i32
    %876 = arith.addi %870, %875 : i32
    %877 = arith.constant 0 : i32
    %878 = llvm.mlir.constant(1 : i64) : i64
    %879 = llvm.alloca %878 x i32 : (i64) -> !llvm.ptr
    llvm.store %877, %879 : i32, !llvm.ptr
    cf.br ^bb111
    ^bb111:
    %880 = llvm.load %879 : !llvm.ptr -> i32
    %881 = arith.cmpi slt, %880, %arg0 : i32
    cf.cond_br %881, ^bb112, ^bb113
    ^bb112:
      %883 = llvm.mlir.addressof @perms_data : !llvm.ptr
      %884 = llvm.load %883 : !llvm.ptr -> !llvm.ptr
      %885 = llvm.load %879 : !llvm.ptr -> i32
      %886 = arith.addi %876, %885 : i32
      %887 = arith.extsi %886 : i32 to i64
      %888 = llvm.getelementptr %884[%887] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %882 = llvm.load %888 : !llvm.ptr -> i32
      %889 = llvm.mlir.addressof @perm_buf : !llvm.ptr
      %890 = llvm.load %889 : !llvm.ptr -> !llvm.ptr
      %891 = llvm.load %879 : !llvm.ptr -> i32
      %892 = arith.extsi %891 : i32 to i64
      %893 = llvm.getelementptr %890[%892] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %882, %893 : i32, !llvm.ptr
      %894 = llvm.load %879 : !llvm.ptr -> i32
      %895 = arith.constant 1 : i32
      %896 = arith.addi %894, %895 : i32
      llvm.store %896, %879 : i32, !llvm.ptr
      cf.br ^bb111
    ^bb113:
    func.return
  }
  // Module static: token_off
  llvm.mlir.global internal @token_off() {addr_space = 0 : i32} : !llvm.ptr {
    %897 = llvm.mlir.zero : !llvm.ptr
    llvm.return %897 : !llvm.ptr
  }
  // Module static: token_len
  llvm.mlir.global internal @token_len() {addr_space = 0 : i32} : !llvm.ptr {
    %898 = llvm.mlir.zero : !llvm.ptr
    llvm.return %898 : !llvm.ptr
  }
  func.func @split_tokens(%arg0: !llvm.ptr, %arg1: i32) -> i32 {
    %899 = llvm.mlir.addressof @token_off : !llvm.ptr
    %900 = llvm.load %899 : !llvm.ptr -> !llvm.ptr
    %901 = arith.constant 0 : i32
    %902 = llvm.inttoptr %901 : i32 to !llvm.ptr
    %903 = llvm.icmp "eq" %900, %902 : !llvm.ptr
    cf.cond_br %903, ^bb114, ^bb115
    ^bb114:
      %905 = arith.constant 200 : i32
      %906 = arith.constant 4 : i32
      %907 = arith.extsi %905 : i32 to i64
      %908 = arith.extsi %906 : i32 to i64
      %904 = func.call @calloc(%907, %908) : (i64, i64) -> !llvm.ptr
      %909 = llvm.mlir.addressof @token_off : !llvm.ptr
      llvm.store %904, %909 : !llvm.ptr, !llvm.ptr
      %911 = arith.constant 200 : i32
      %912 = arith.constant 4 : i32
      %913 = arith.extsi %911 : i32 to i64
      %914 = arith.extsi %912 : i32 to i64
      %910 = func.call @calloc(%913, %914) : (i64, i64) -> !llvm.ptr
      %915 = llvm.mlir.addressof @token_len : !llvm.ptr
      llvm.store %910, %915 : !llvm.ptr, !llvm.ptr
      cf.br ^bb116
    ^bb115:
      cf.br ^bb116
    ^bb116:
    %916 = arith.constant 0 : i32
    %917 = llvm.mlir.constant(1 : i64) : i64
    %918 = llvm.alloca %917 x i32 : (i64) -> !llvm.ptr
    llvm.store %916, %918 : i32, !llvm.ptr
    %919 = arith.constant 0 : i32
    %920 = llvm.mlir.constant(1 : i64) : i64
    %921 = llvm.alloca %920 x i32 : (i64) -> !llvm.ptr
    llvm.store %919, %921 : i32, !llvm.ptr
    %922 = arith.constant 0 : i32
    %923 = llvm.mlir.constant(1 : i64) : i64
    %924 = llvm.alloca %923 x i32 : (i64) -> !llvm.ptr
    llvm.store %922, %924 : i32, !llvm.ptr
    %925 = arith.constant 0 : i32
    %926 = llvm.mlir.constant(1 : i64) : i64
    %927 = llvm.alloca %926 x i32 : (i64) -> !llvm.ptr
    llvm.store %925, %927 : i32, !llvm.ptr
    cf.br ^bb117
    ^bb117:
    %928 = llvm.load %927 : !llvm.ptr -> i32
    %929 = arith.cmpi slt, %928, %arg1 : i32
    cf.cond_br %929, ^bb118, ^bb119
    ^bb118:
      %931 = llvm.load %927 : !llvm.ptr -> i32
      %932 = arith.extsi %931 : i32 to i64
      %933 = llvm.getelementptr %arg0[%932] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %930 = llvm.load %933 : !llvm.ptr -> i8
      %934 = arith.constant 44 : i32
      %936 = arith.extsi %930 : i8 to i32
      %935 = arith.cmpi eq, %936, %934 : i32
      %937 = scf.if %935 -> (i1) {
        %938 = llvm.load %924 : !llvm.ptr -> i32
        %939 = arith.constant 0 : i32
        %940 = arith.cmpi eq, %938, %939 : i32
        scf.yield %940 : i1
      } else {
        %941 = arith.constant false
        scf.yield %941 : i1
      }
      cf.cond_br %937, ^bb120, ^bb121
      ^bb120:
        %942 = llvm.load %921 : !llvm.ptr -> i32
        %943 = llvm.mlir.addressof @token_off : !llvm.ptr
        %944 = llvm.load %943 : !llvm.ptr -> !llvm.ptr
        %945 = llvm.load %918 : !llvm.ptr -> i32
        %946 = arith.extsi %945 : i32 to i64
        %947 = llvm.getelementptr %944[%946] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %942, %947 : i32, !llvm.ptr
        %948 = llvm.load %927 : !llvm.ptr -> i32
        %949 = llvm.load %921 : !llvm.ptr -> i32
        %950 = arith.subi %948, %949 : i32
        %951 = llvm.mlir.addressof @token_len : !llvm.ptr
        %952 = llvm.load %951 : !llvm.ptr -> !llvm.ptr
        %953 = llvm.load %918 : !llvm.ptr -> i32
        %954 = arith.extsi %953 : i32 to i64
        %955 = llvm.getelementptr %952[%954] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %950, %955 : i32, !llvm.ptr
        %956 = llvm.load %918 : !llvm.ptr -> i32
        %957 = arith.constant 1 : i32
        %958 = arith.addi %956, %957 : i32
        llvm.store %958, %918 : i32, !llvm.ptr
        %959 = llvm.load %927 : !llvm.ptr -> i32
        %960 = arith.constant 1 : i32
        %961 = arith.addi %959, %960 : i32
        llvm.store %961, %921 : i32, !llvm.ptr
        cf.br ^bb122
      ^bb121:
        %962 = arith.constant 40 : i32
        %964 = arith.extsi %930 : i8 to i32
        %963 = arith.cmpi eq, %964, %962 : i32
        cf.cond_br %963, ^bb123, ^bb124
        ^bb123:
          %965 = llvm.load %924 : !llvm.ptr -> i32
          %966 = arith.constant 1 : i32
          %967 = arith.addi %965, %966 : i32
          llvm.store %967, %924 : i32, !llvm.ptr
          cf.br ^bb125
        ^bb124:
          %968 = arith.constant 41 : i32
          %970 = arith.extsi %930 : i8 to i32
          %969 = arith.cmpi eq, %970, %968 : i32
          cf.cond_br %969, ^bb126, ^bb127
          ^bb126:
            %971 = llvm.load %924 : !llvm.ptr -> i32
            %972 = arith.constant 1 : i32
            %973 = arith.subi %971, %972 : i32
            llvm.store %973, %924 : i32, !llvm.ptr
            cf.br ^bb128
          ^bb127:
            cf.br ^bb128
          ^bb128:
          cf.br ^bb125
        ^bb125:
        cf.br ^bb122
      ^bb122:
      %974 = llvm.load %927 : !llvm.ptr -> i32
      %975 = arith.constant 1 : i32
      %976 = arith.addi %974, %975 : i32
      llvm.store %976, %927 : i32, !llvm.ptr
      cf.br ^bb117
    ^bb119:
    %977 = llvm.load %921 : !llvm.ptr -> i32
    %978 = llvm.mlir.addressof @token_off : !llvm.ptr
    %979 = llvm.load %978 : !llvm.ptr -> !llvm.ptr
    %980 = llvm.load %918 : !llvm.ptr -> i32
    %981 = arith.extsi %980 : i32 to i64
    %982 = llvm.getelementptr %979[%981] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %977, %982 : i32, !llvm.ptr
    %983 = llvm.load %921 : !llvm.ptr -> i32
    %984 = arith.subi %arg1, %983 : i32
    %985 = llvm.mlir.addressof @token_len : !llvm.ptr
    %986 = llvm.load %985 : !llvm.ptr -> !llvm.ptr
    %987 = llvm.load %918 : !llvm.ptr -> i32
    %988 = arith.extsi %987 : i32 to i64
    %989 = llvm.getelementptr %986[%988] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %984, %989 : i32, !llvm.ptr
    %990 = llvm.load %918 : !llvm.ptr -> i32
    %991 = arith.constant 1 : i32
    %992 = arith.addi %990, %991 : i32
    llvm.store %992, %918 : i32, !llvm.ptr
    %993 = llvm.load %918 : !llvm.ptr -> i32
    func.return %993 : i32
  }
  func.func @parse_int(%arg0: !llvm.ptr, %arg1: i32, %arg2: i32) -> i32 {
    %994 = arith.constant 0 : i32
    %995 = llvm.mlir.constant(1 : i64) : i64
    %996 = llvm.alloca %995 x i32 : (i64) -> !llvm.ptr
    llvm.store %994, %996 : i32, !llvm.ptr
    %997 = arith.constant 0 : i32
    %998 = llvm.mlir.constant(1 : i64) : i64
    %999 = llvm.alloca %998 x i32 : (i64) -> !llvm.ptr
    llvm.store %997, %999 : i32, !llvm.ptr
    cf.br ^bb129
    ^bb129:
    %1000 = llvm.load %999 : !llvm.ptr -> i32
    %1001 = arith.cmpi slt, %1000, %arg2 : i32
    cf.cond_br %1001, ^bb130, ^bb131
    ^bb130:
      %1003 = llvm.load %999 : !llvm.ptr -> i32
      %1004 = arith.addi %arg1, %1003 : i32
      %1005 = arith.extsi %1004 : i32 to i64
      %1006 = llvm.getelementptr %arg0[%1005] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %1002 = llvm.load %1006 : !llvm.ptr -> i8
      %1007 = arith.constant 48 : i32
      %1009 = arith.extsi %1002 : i8 to i32
      %1008 = arith.cmpi sge, %1009, %1007 : i32
      %1010 = scf.if %1008 -> (i1) {
        %1011 = arith.constant 57 : i32
        %1013 = arith.extsi %1002 : i8 to i32
        %1012 = arith.cmpi sle, %1013, %1011 : i32
        scf.yield %1012 : i1
      } else {
        %1014 = arith.constant false
        scf.yield %1014 : i1
      }
      cf.cond_br %1010, ^bb132, ^bb133
      ^bb132:
        %1015 = llvm.load %996 : !llvm.ptr -> i32
        %1016 = arith.constant 10 : i32
        %1017 = arith.muli %1015, %1016 : i32
        %1018 = arith.extsi %1002 : i8 to i32
        %1019 = arith.constant 48 : i32
        %1020 = arith.subi %1018, %1019 : i32
        %1021 = arith.addi %1017, %1020 : i32
        llvm.store %1021, %996 : i32, !llvm.ptr
        cf.br ^bb134
      ^bb133:
        cf.br ^bb134
      ^bb134:
      %1022 = llvm.load %999 : !llvm.ptr -> i32
      %1023 = arith.constant 1 : i32
      %1024 = arith.addi %1022, %1023 : i32
      llvm.store %1024, %999 : i32, !llvm.ptr
      cf.br ^bb129
    ^bb131:
    %1025 = llvm.load %996 : !llvm.ptr -> i32
    func.return %1025 : i32
  }
  // Module static: puzzle_n
  llvm.mlir.global internal @puzzle_n(0 : i32) : i32
  // Module static: puzzle_ngrid
  llvm.mlir.global internal @puzzle_ngrid(0 : i32) : i32
  func.func @parse_puzzle(%arg0: !llvm.ptr, %arg1: i32) -> () {
    %1026 = func.call @split_tokens(%arg0, %arg1) : (!llvm.ptr, i32) -> i32
    %1029 = llvm.mlir.addressof @token_off : !llvm.ptr
    %1030 = llvm.load %1029 : !llvm.ptr -> !llvm.ptr
    %1031 = arith.constant 0 : i32
    %1032 = arith.extsi %1031 : i32 to i64
    %1033 = llvm.getelementptr %1030[%1032] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %1028 = llvm.load %1033 : !llvm.ptr -> i32
    %1035 = llvm.mlir.addressof @token_len : !llvm.ptr
    %1036 = llvm.load %1035 : !llvm.ptr -> !llvm.ptr
    %1037 = arith.constant 0 : i32
    %1038 = arith.extsi %1037 : i32 to i64
    %1039 = llvm.getelementptr %1036[%1038] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %1034 = llvm.load %1039 : !llvm.ptr -> i32
    %1027 = func.call @parse_int(%arg0, %1028, %1034) : (!llvm.ptr, i32, i32) -> i32
    %1040 = llvm.mlir.addressof @puzzle_n : !llvm.ptr
    llvm.store %1027, %1040 : i32, !llvm.ptr
    %1041 = llvm.mlir.addressof @puzzle_n : !llvm.ptr
    %1042 = llvm.load %1041 : !llvm.ptr -> i32
    %1043 = arith.muli %1042, %1042 : i32
    %1044 = llvm.mlir.addressof @puzzle_ngrid : !llvm.ptr
    llvm.store %1043, %1044 : i32, !llvm.ptr
    %1045 = arith.constant 0 : i32
    %1046 = llvm.mlir.constant(1 : i64) : i64
    %1047 = llvm.alloca %1046 x i32 : (i64) -> !llvm.ptr
    llvm.store %1045, %1047 : i32, !llvm.ptr
    cf.br ^bb135
    ^bb135:
    %1048 = llvm.load %1047 : !llvm.ptr -> i32
    %1049 = arith.muli %1042, %1042 : i32
    %1050 = arith.cmpi slt, %1048, %1049 : i32
    cf.cond_br %1050, ^bb136, ^bb137
    ^bb136:
      %1051 = llvm.mlir.addressof @CT_X : !llvm.ptr
      %1052 = llvm.load %1051 : !llvm.ptr -> i32
      %1053 = llvm.mlir.addressof @g_type : !llvm.ptr
      %1054 = llvm.load %1053 : !llvm.ptr -> !llvm.ptr
      %1055 = llvm.load %1047 : !llvm.ptr -> i32
      %1056 = arith.extsi %1055 : i32 to i64
      %1057 = llvm.getelementptr %1054[%1056] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1052, %1057 : i32, !llvm.ptr
      %1058 = arith.constant 0 : i32
      %1059 = llvm.mlir.addressof @g_letter : !llvm.ptr
      %1060 = llvm.load %1059 : !llvm.ptr -> !llvm.ptr
      %1061 = llvm.load %1047 : !llvm.ptr -> i32
      %1062 = arith.extsi %1061 : i32 to i64
      %1063 = llvm.getelementptr %1060[%1062] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1058, %1063 : i32, !llvm.ptr
      %1064 = arith.constant 0 : i32
      %1065 = llvm.mlir.addressof @g_h_len : !llvm.ptr
      %1066 = llvm.load %1065 : !llvm.ptr -> !llvm.ptr
      %1067 = llvm.load %1047 : !llvm.ptr -> i32
      %1068 = arith.extsi %1067 : i32 to i64
      %1069 = llvm.getelementptr %1066[%1068] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1064, %1069 : i32, !llvm.ptr
      %1070 = arith.constant 0 : i32
      %1071 = llvm.mlir.addressof @g_v_len : !llvm.ptr
      %1072 = llvm.load %1071 : !llvm.ptr -> !llvm.ptr
      %1073 = llvm.load %1047 : !llvm.ptr -> i32
      %1074 = arith.extsi %1073 : i32 to i64
      %1075 = llvm.getelementptr %1072[%1074] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1070, %1075 : i32, !llvm.ptr
      %1076 = llvm.load %1047 : !llvm.ptr -> i32
      %1077 = arith.constant 1 : i32
      %1078 = arith.addi %1076, %1077 : i32
      llvm.store %1078, %1047 : i32, !llvm.ptr
      cf.br ^bb135
    ^bb137:
    %1079 = arith.constant 1 : i32
    %1080 = llvm.mlir.constant(1 : i64) : i64
    %1081 = llvm.alloca %1080 x i32 : (i64) -> !llvm.ptr
    llvm.store %1079, %1081 : i32, !llvm.ptr
    %1082 = arith.constant 0 : i32
    %1083 = llvm.mlir.constant(1 : i64) : i64
    %1084 = llvm.alloca %1083 x i32 : (i64) -> !llvm.ptr
    llvm.store %1082, %1084 : i32, !llvm.ptr
    cf.br ^bb138
    ^bb138:
    %1085 = llvm.load %1081 : !llvm.ptr -> i32
    %1086 = arith.cmpi slt, %1085, %1026 : i32
    cf.cond_br %1086, ^bb139, ^bb140
    ^bb139:
      %1088 = llvm.mlir.addressof @token_off : !llvm.ptr
      %1089 = llvm.load %1088 : !llvm.ptr -> !llvm.ptr
      %1090 = llvm.load %1081 : !llvm.ptr -> i32
      %1091 = arith.extsi %1090 : i32 to i64
      %1092 = llvm.getelementptr %1089[%1091] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1087 = llvm.load %1092 : !llvm.ptr -> i32
      %1094 = llvm.mlir.addressof @token_len : !llvm.ptr
      %1095 = llvm.load %1094 : !llvm.ptr -> !llvm.ptr
      %1096 = llvm.load %1081 : !llvm.ptr -> i32
      %1097 = arith.extsi %1096 : i32 to i64
      %1098 = llvm.getelementptr %1095[%1097] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1093 = llvm.load %1098 : !llvm.ptr -> i32
      %1099 = arith.constant 1 : i32
      %1100 = arith.cmpi eq, %1093, %1099 : i32
      cf.cond_br %1100, ^bb141, ^bb142
      ^bb141:
        %1102 = arith.extsi %1087 : i32 to i64
        %1103 = llvm.getelementptr %arg0[%1102] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1101 = llvm.load %1103 : !llvm.ptr -> i8
        %1104 = arith.constant 88 : i32
        %1106 = arith.extsi %1101 : i8 to i32
        %1105 = arith.cmpi eq, %1106, %1104 : i32
        cf.cond_br %1105, ^bb144, ^bb145
        ^bb144:
          %1107 = llvm.mlir.addressof @CT_X : !llvm.ptr
          %1108 = llvm.load %1107 : !llvm.ptr -> i32
          %1109 = llvm.mlir.addressof @g_type : !llvm.ptr
          %1110 = llvm.load %1109 : !llvm.ptr -> !llvm.ptr
          %1111 = llvm.load %1084 : !llvm.ptr -> i32
          %1112 = arith.extsi %1111 : i32 to i64
          %1113 = llvm.getelementptr %1110[%1112] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %1108, %1113 : i32, !llvm.ptr
          cf.br ^bb146
        ^bb145:
          %1114 = arith.constant 79 : i32
          %1116 = arith.extsi %1101 : i8 to i32
          %1115 = arith.cmpi eq, %1116, %1114 : i32
          cf.cond_br %1115, ^bb147, ^bb148
          ^bb147:
            %1117 = llvm.mlir.addressof @CT_O : !llvm.ptr
            %1118 = llvm.load %1117 : !llvm.ptr -> i32
            %1119 = llvm.mlir.addressof @g_type : !llvm.ptr
            %1120 = llvm.load %1119 : !llvm.ptr -> !llvm.ptr
            %1121 = llvm.load %1084 : !llvm.ptr -> i32
            %1122 = arith.extsi %1121 : i32 to i64
            %1123 = llvm.getelementptr %1120[%1122] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %1118, %1123 : i32, !llvm.ptr
            cf.br ^bb149
          ^bb148:
            %1124 = arith.constant 65 : i32
            %1126 = arith.extsi %1101 : i8 to i32
            %1125 = arith.cmpi sge, %1126, %1124 : i32
            %1127 = scf.if %1125 -> (i1) {
              %1128 = arith.constant 74 : i32
              %1130 = arith.extsi %1101 : i8 to i32
              %1129 = arith.cmpi sle, %1130, %1128 : i32
              scf.yield %1129 : i1
            } else {
              %1131 = arith.constant false
              scf.yield %1131 : i1
            }
            cf.cond_br %1127, ^bb150, ^bb151
            ^bb150:
              %1132 = llvm.mlir.addressof @CT_L : !llvm.ptr
              %1133 = llvm.load %1132 : !llvm.ptr -> i32
              %1134 = llvm.mlir.addressof @g_type : !llvm.ptr
              %1135 = llvm.load %1134 : !llvm.ptr -> !llvm.ptr
              %1136 = llvm.load %1084 : !llvm.ptr -> i32
              %1137 = arith.extsi %1136 : i32 to i64
              %1138 = llvm.getelementptr %1135[%1137] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %1133, %1138 : i32, !llvm.ptr
              %1139 = arith.extsi %1101 : i8 to i32
              %1140 = arith.constant 65 : i32
              %1141 = arith.subi %1139, %1140 : i32
              %1142 = llvm.mlir.addressof @g_letter : !llvm.ptr
              %1143 = llvm.load %1142 : !llvm.ptr -> !llvm.ptr
              %1144 = llvm.load %1084 : !llvm.ptr -> i32
              %1145 = arith.extsi %1144 : i32 to i64
              %1146 = llvm.getelementptr %1143[%1145] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %1141, %1146 : i32, !llvm.ptr
              cf.br ^bb152
            ^bb151:
              cf.br ^bb152
            ^bb152:
            cf.br ^bb149
          ^bb149:
          cf.br ^bb146
        ^bb146:
        cf.br ^bb143
      ^bb142:
        %1147 = arith.constant 0 : i32
        %1148 = arith.cmpi sgt, %1093, %1147 : i32
        cf.cond_br %1148, ^bb153, ^bb154
        ^bb153:
          %1150 = arith.extsi %1087 : i32 to i64
          %1151 = llvm.getelementptr %arg0[%1150] : (!llvm.ptr, i64) -> !llvm.ptr, i8
          %1149 = llvm.load %1151 : !llvm.ptr -> i8
          %1152 = arith.constant 40 : i32
          %1154 = arith.extsi %1149 : i8 to i32
          %1153 = arith.cmpi eq, %1154, %1152 : i32
          cf.cond_br %1153, ^bb156, ^bb157
          ^bb156:
            %1155 = llvm.mlir.addressof @CT_C : !llvm.ptr
            %1156 = llvm.load %1155 : !llvm.ptr -> i32
            %1157 = llvm.mlir.addressof @g_type : !llvm.ptr
            %1158 = llvm.load %1157 : !llvm.ptr -> !llvm.ptr
            %1159 = llvm.load %1084 : !llvm.ptr -> i32
            %1160 = arith.extsi %1159 : i32 to i64
            %1161 = llvm.getelementptr %1158[%1160] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %1156, %1161 : i32, !llvm.ptr
            %1162 = arith.constant 1 : i32
            %1163 = arith.addi %1087, %1162 : i32
            %1164 = arith.constant 2 : i32
            %1165 = arith.subi %1093, %1164 : i32
            %1166 = arith.constant 0 : i32
            %1167 = llvm.mlir.constant(1 : i64) : i64
            %1168 = llvm.alloca %1167 x i32 : (i64) -> !llvm.ptr
            llvm.store %1166, %1168 : i32, !llvm.ptr
            cf.br ^bb159
            ^bb159:
            %1169 = llvm.load %1168 : !llvm.ptr -> i32
            %1170 = arith.cmpi slt, %1169, %1165 : i32
            cf.cond_br %1170, ^bb160, ^bb161
            ^bb160:
              %1171 = arith.constant 1 : i32
              %1173 = arith.constant 0 : i32
              %1172 = arith.subi %1173, %1171 : i32
              %1174 = llvm.mlir.constant(1 : i64) : i64
              %1175 = llvm.alloca %1174 x i32 : (i64) -> !llvm.ptr
              llvm.store %1172, %1175 : i32, !llvm.ptr
              %1176 = llvm.load %1168 : !llvm.ptr -> i32
              %1177 = llvm.mlir.constant(1 : i64) : i64
              %1178 = llvm.alloca %1177 x i32 : (i64) -> !llvm.ptr
              llvm.store %1176, %1178 : i32, !llvm.ptr
              cf.br ^bb162
              ^bb162:
              %1179 = llvm.load %1178 : !llvm.ptr -> i32
              %1180 = arith.cmpi slt, %1179, %1165 : i32
              cf.cond_br %1180, ^bb163, ^bb164
              ^bb163:
                %1182 = llvm.load %1178 : !llvm.ptr -> i32
                %1183 = arith.addi %1163, %1182 : i32
                %1184 = arith.extsi %1183 : i32 to i64
                %1185 = llvm.getelementptr %arg0[%1184] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                %1181 = llvm.load %1185 : !llvm.ptr -> i8
                %1186 = arith.constant 44 : i32
                %1188 = arith.extsi %1181 : i8 to i32
                %1187 = arith.cmpi eq, %1188, %1186 : i32
                cf.cond_br %1187, ^bb165, ^bb166
                ^bb165:
                  %1189 = llvm.load %1178 : !llvm.ptr -> i32
                  llvm.store %1189, %1175 : i32, !llvm.ptr
                  cf.br ^bb164
                ^bb166:
                  cf.br ^bb167
                ^bb167:
                %1190 = llvm.load %1178 : !llvm.ptr -> i32
                %1191 = arith.constant 1 : i32
                %1192 = arith.addi %1190, %1191 : i32
                llvm.store %1192, %1178 : i32, !llvm.ptr
                cf.br ^bb162
              ^bb164:
              %1193 = arith.constant 0 : i32
              %1194 = llvm.load %1175 : !llvm.ptr -> i32
              %1195 = arith.constant 0 : i32
              %1196 = arith.cmpi slt, %1194, %1195 : i32
              %1197 = scf.if %1196 -> (i32) {
                %1198 = llvm.load %1168 : !llvm.ptr -> i32
                %1199 = arith.subi %1165, %1198 : i32
                scf.yield %1199 : i32
              } else {
                %1200 = llvm.load %1175 : !llvm.ptr -> i32
                %1201 = llvm.load %1168 : !llvm.ptr -> i32
                %1202 = arith.subi %1200, %1201 : i32
                scf.yield %1202 : i32
              }
              %1203 = arith.constant 0 : i32
              %1204 = arith.cmpi sgt, %1197, %1203 : i32
              cf.cond_br %1204, ^bb168, ^bb169
              ^bb168:
                %1206 = llvm.load %1168 : !llvm.ptr -> i32
                %1207 = arith.addi %1163, %1206 : i32
                %1208 = arith.extsi %1207 : i32 to i64
                %1209 = llvm.getelementptr %arg0[%1208] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                %1205 = llvm.load %1209 : !llvm.ptr -> i8
                %1210 = arith.constant 104 : i32
                %1212 = arith.extsi %1205 : i8 to i32
                %1211 = arith.cmpi eq, %1212, %1210 : i32
                cf.cond_br %1211, ^bb171, ^bb172
                ^bb171:
                  %1213 = arith.constant 1 : i32
                  %1214 = arith.subi %1197, %1213 : i32
                  %1215 = llvm.mlir.addressof @g_h_len : !llvm.ptr
                  %1216 = llvm.load %1215 : !llvm.ptr -> !llvm.ptr
                  %1217 = llvm.load %1084 : !llvm.ptr -> i32
                  %1218 = arith.extsi %1217 : i32 to i64
                  %1219 = llvm.getelementptr %1216[%1218] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                  llvm.store %1214, %1219 : i32, !llvm.ptr
                  %1220 = arith.constant 0 : i32
                  %1221 = llvm.mlir.constant(1 : i64) : i64
                  %1222 = llvm.alloca %1221 x i32 : (i64) -> !llvm.ptr
                  llvm.store %1220, %1222 : i32, !llvm.ptr
                  cf.br ^bb174
                  ^bb174:
                  %1223 = llvm.load %1222 : !llvm.ptr -> i32
                  %1224 = arith.constant 1 : i32
                  %1225 = arith.subi %1197, %1224 : i32
                  %1226 = arith.cmpi slt, %1223, %1225 : i32
                  cf.cond_br %1226, ^bb175, ^bb176
                  ^bb175:
                    %1228 = llvm.load %1168 : !llvm.ptr -> i32
                    %1229 = arith.addi %1163, %1228 : i32
                    %1230 = arith.constant 1 : i32
                    %1231 = arith.addi %1229, %1230 : i32
                    %1232 = llvm.load %1222 : !llvm.ptr -> i32
                    %1233 = arith.addi %1231, %1232 : i32
                    %1234 = arith.extsi %1233 : i32 to i64
                    %1235 = llvm.getelementptr %arg0[%1234] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                    %1227 = llvm.load %1235 : !llvm.ptr -> i8
                    %1236 = llvm.mlir.addressof @g_h_data : !llvm.ptr
                    %1237 = llvm.load %1236 : !llvm.ptr -> !llvm.ptr
                    %1238 = llvm.load %1084 : !llvm.ptr -> i32
                    %1239 = arith.constant 4 : i32
                    %1240 = arith.muli %1238, %1239 : i32
                    %1241 = llvm.load %1222 : !llvm.ptr -> i32
                    %1242 = arith.addi %1240, %1241 : i32
                    %1243 = arith.extsi %1242 : i32 to i64
                    %1244 = llvm.getelementptr %1237[%1243] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                    llvm.store %1227, %1244 : i8, !llvm.ptr
                    %1245 = llvm.load %1222 : !llvm.ptr -> i32
                    %1246 = arith.constant 1 : i32
                    %1247 = arith.addi %1245, %1246 : i32
                    llvm.store %1247, %1222 : i32, !llvm.ptr
                    cf.br ^bb174
                  ^bb176:
                  cf.br ^bb173
                ^bb172:
                  %1248 = arith.constant 118 : i32
                  %1250 = arith.extsi %1205 : i8 to i32
                  %1249 = arith.cmpi eq, %1250, %1248 : i32
                  cf.cond_br %1249, ^bb177, ^bb178
                  ^bb177:
                    %1251 = arith.constant 1 : i32
                    %1252 = arith.subi %1197, %1251 : i32
                    %1253 = llvm.mlir.addressof @g_v_len : !llvm.ptr
                    %1254 = llvm.load %1253 : !llvm.ptr -> !llvm.ptr
                    %1255 = llvm.load %1084 : !llvm.ptr -> i32
                    %1256 = arith.extsi %1255 : i32 to i64
                    %1257 = llvm.getelementptr %1254[%1256] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    llvm.store %1252, %1257 : i32, !llvm.ptr
                    %1258 = arith.constant 0 : i32
                    %1259 = llvm.mlir.constant(1 : i64) : i64
                    %1260 = llvm.alloca %1259 x i32 : (i64) -> !llvm.ptr
                    llvm.store %1258, %1260 : i32, !llvm.ptr
                    cf.br ^bb180
                    ^bb180:
                    %1261 = llvm.load %1260 : !llvm.ptr -> i32
                    %1262 = arith.constant 1 : i32
                    %1263 = arith.subi %1197, %1262 : i32
                    %1264 = arith.cmpi slt, %1261, %1263 : i32
                    cf.cond_br %1264, ^bb181, ^bb182
                    ^bb181:
                      %1266 = llvm.load %1168 : !llvm.ptr -> i32
                      %1267 = arith.addi %1163, %1266 : i32
                      %1268 = arith.constant 1 : i32
                      %1269 = arith.addi %1267, %1268 : i32
                      %1270 = llvm.load %1260 : !llvm.ptr -> i32
                      %1271 = arith.addi %1269, %1270 : i32
                      %1272 = arith.extsi %1271 : i32 to i64
                      %1273 = llvm.getelementptr %arg0[%1272] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                      %1265 = llvm.load %1273 : !llvm.ptr -> i8
                      %1274 = llvm.mlir.addressof @g_v_data : !llvm.ptr
                      %1275 = llvm.load %1274 : !llvm.ptr -> !llvm.ptr
                      %1276 = llvm.load %1084 : !llvm.ptr -> i32
                      %1277 = arith.constant 4 : i32
                      %1278 = arith.muli %1276, %1277 : i32
                      %1279 = llvm.load %1260 : !llvm.ptr -> i32
                      %1280 = arith.addi %1278, %1279 : i32
                      %1281 = arith.extsi %1280 : i32 to i64
                      %1282 = llvm.getelementptr %1275[%1281] : (!llvm.ptr, i64) -> !llvm.ptr, i8
                      llvm.store %1265, %1282 : i8, !llvm.ptr
                      %1283 = llvm.load %1260 : !llvm.ptr -> i32
                      %1284 = arith.constant 1 : i32
                      %1285 = arith.addi %1283, %1284 : i32
                      llvm.store %1285, %1260 : i32, !llvm.ptr
                      cf.br ^bb180
                    ^bb182:
                    cf.br ^bb179
                  ^bb178:
                    cf.br ^bb179
                  ^bb179:
                  cf.br ^bb173
                ^bb173:
                cf.br ^bb170
              ^bb169:
                cf.br ^bb170
              ^bb170:
              %1286 = llvm.load %1175 : !llvm.ptr -> i32
              %1287 = arith.constant 0 : i32
              %1288 = arith.cmpi slt, %1286, %1287 : i32
              cf.cond_br %1288, ^bb183, ^bb184
              ^bb183:
                cf.br ^bb161
              ^bb184:
                cf.br ^bb185
              ^bb185:
              %1289 = llvm.load %1175 : !llvm.ptr -> i32
              %1290 = arith.constant 1 : i32
              %1291 = arith.addi %1289, %1290 : i32
              llvm.store %1291, %1168 : i32, !llvm.ptr
              cf.br ^bb159
            ^bb161:
            cf.br ^bb158
          ^bb157:
            cf.br ^bb158
          ^bb158:
          cf.br ^bb155
        ^bb154:
          cf.br ^bb155
        ^bb155:
        cf.br ^bb143
      ^bb143:
      %1292 = llvm.load %1084 : !llvm.ptr -> i32
      %1293 = arith.constant 1 : i32
      %1294 = arith.addi %1292, %1293 : i32
      llvm.store %1294, %1084 : i32, !llvm.ptr
      %1295 = llvm.load %1081 : !llvm.ptr -> i32
      %1296 = arith.constant 1 : i32
      %1297 = arith.addi %1295, %1296 : i32
      llvm.store %1297, %1081 : i32, !llvm.ptr
      cf.br ^bb138
    ^bb140:
    func.return
  }
  func.func @build_csp() -> () {
    func.call @init_perms() : () -> ()
    %1299 = llvm.mlir.addressof @puzzle_n : !llvm.ptr
    %1300 = llvm.load %1299 : !llvm.ptr -> i32
    %1301 = arith.muli %1300, %1300 : i32
    %1302 = arith.constant 0 : i32
    %1303 = llvm.mlir.constant(1 : i64) : i64
    %1304 = llvm.alloca %1303 x i32 : (i64) -> !llvm.ptr
    llvm.store %1302, %1304 : i32, !llvm.ptr
    cf.br ^bb186
    ^bb186:
    %1305 = llvm.load %1304 : !llvm.ptr -> i32
    %1306 = arith.constant 10 : i32
    %1307 = arith.cmpi slt, %1305, %1306 : i32
    cf.cond_br %1307, ^bb187, ^bb188
    ^bb187:
      %1308 = llvm.mlir.addressof @ALL10 : !llvm.ptr
      %1309 = llvm.load %1308 : !llvm.ptr -> i32
      %1310 = llvm.mlir.addressof @csp_domains : !llvm.ptr
      %1311 = llvm.load %1310 : !llvm.ptr -> !llvm.ptr
      %1312 = llvm.load %1304 : !llvm.ptr -> i32
      %1313 = arith.extsi %1312 : i32 to i64
      %1314 = llvm.getelementptr %1311[%1313] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1309, %1314 : i32, !llvm.ptr
      %1315 = llvm.load %1304 : !llvm.ptr -> i32
      %1316 = arith.constant 1 : i32
      %1317 = arith.addi %1315, %1316 : i32
      llvm.store %1317, %1304 : i32, !llvm.ptr
      cf.br ^bb186
    ^bb188:
    %1318 = arith.constant 0 : i32
    %1319 = llvm.mlir.constant(1 : i64) : i64
    %1320 = llvm.alloca %1319 x i32 : (i64) -> !llvm.ptr
    llvm.store %1318, %1320 : i32, !llvm.ptr
    cf.br ^bb189
    ^bb189:
    %1321 = llvm.load %1320 : !llvm.ptr -> i32
    %1322 = arith.cmpi slt, %1321, %1301 : i32
    cf.cond_br %1322, ^bb190, ^bb191
    ^bb190:
      %1324 = llvm.mlir.addressof @g_type : !llvm.ptr
      %1325 = llvm.load %1324 : !llvm.ptr -> !llvm.ptr
      %1326 = llvm.load %1320 : !llvm.ptr -> i32
      %1327 = arith.extsi %1326 : i32 to i64
      %1328 = llvm.getelementptr %1325[%1327] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1323 = llvm.load %1328 : !llvm.ptr -> i32
      %1329 = llvm.mlir.addressof @CT_L : !llvm.ptr
      %1330 = llvm.load %1329 : !llvm.ptr -> i32
      %1331 = arith.cmpi eq, %1323, %1330 : i32
      cf.cond_br %1331, ^bb192, ^bb193
      ^bb192:
        %1333 = llvm.mlir.addressof @csp_domains : !llvm.ptr
        %1334 = llvm.load %1333 : !llvm.ptr -> !llvm.ptr
        %1336 = llvm.mlir.addressof @g_letter : !llvm.ptr
        %1337 = llvm.load %1336 : !llvm.ptr -> !llvm.ptr
        %1338 = llvm.load %1320 : !llvm.ptr -> i32
        %1339 = arith.extsi %1338 : i32 to i64
        %1340 = llvm.getelementptr %1337[%1339] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1335 = llvm.load %1340 : !llvm.ptr -> i32
        %1341 = arith.extsi %1335 : i32 to i64
        %1342 = llvm.getelementptr %1334[%1341] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1332 = llvm.load %1342 : !llvm.ptr -> i32
        %1343 = llvm.mlir.addressof @DIGITS_19 : !llvm.ptr
        %1344 = llvm.load %1343 : !llvm.ptr -> i32
        %1345 = arith.andi %1332, %1344 : i32
        %1346 = llvm.mlir.addressof @csp_domains : !llvm.ptr
        %1347 = llvm.load %1346 : !llvm.ptr -> !llvm.ptr
        %1349 = llvm.mlir.addressof @g_letter : !llvm.ptr
        %1350 = llvm.load %1349 : !llvm.ptr -> !llvm.ptr
        %1351 = llvm.load %1320 : !llvm.ptr -> i32
        %1352 = arith.extsi %1351 : i32 to i64
        %1353 = llvm.getelementptr %1350[%1352] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1348 = llvm.load %1353 : !llvm.ptr -> i32
        %1354 = arith.extsi %1348 : i32 to i64
        %1355 = llvm.getelementptr %1347[%1354] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1345, %1355 : i32, !llvm.ptr
        cf.br ^bb194
      ^bb193:
        cf.br ^bb194
      ^bb194:
      %1356 = llvm.load %1320 : !llvm.ptr -> i32
      %1357 = arith.constant 1 : i32
      %1358 = arith.addi %1356, %1357 : i32
      llvm.store %1358, %1320 : i32, !llvm.ptr
      cf.br ^bb189
    ^bb191:
    %1359 = arith.constant 0 : i32
    %1360 = llvm.mlir.constant(1 : i64) : i64
    %1361 = llvm.alloca %1360 x i32 : (i64) -> !llvm.ptr
    llvm.store %1359, %1361 : i32, !llvm.ptr
    %1362 = arith.constant 0 : i32
    %1363 = llvm.mlir.constant(1 : i64) : i64
    %1364 = llvm.alloca %1363 x i32 : (i64) -> !llvm.ptr
    llvm.store %1362, %1364 : i32, !llvm.ptr
    cf.br ^bb195
    ^bb195:
    %1365 = llvm.load %1364 : !llvm.ptr -> i32
    %1366 = arith.cmpi slt, %1365, %1301 : i32
    cf.cond_br %1366, ^bb196, ^bb197
    ^bb196:
      %1367 = arith.constant 1 : i32
      %1369 = arith.constant 0 : i32
      %1368 = arith.subi %1369, %1367 : i32
      %1370 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
      %1371 = llvm.load %1370 : !llvm.ptr -> !llvm.ptr
      %1372 = llvm.load %1364 : !llvm.ptr -> i32
      %1373 = arith.extsi %1372 : i32 to i64
      %1374 = llvm.getelementptr %1371[%1373] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1368, %1374 : i32, !llvm.ptr
      %1375 = llvm.load %1364 : !llvm.ptr -> i32
      %1376 = arith.constant 1 : i32
      %1377 = arith.addi %1375, %1376 : i32
      llvm.store %1377, %1364 : i32, !llvm.ptr
      cf.br ^bb195
    ^bb197:
    %1378 = arith.constant 0 : i32
    %1379 = llvm.mlir.constant(1 : i64) : i64
    %1380 = llvm.alloca %1379 x i32 : (i64) -> !llvm.ptr
    llvm.store %1378, %1380 : i32, !llvm.ptr
    cf.br ^bb198
    ^bb198:
    %1381 = llvm.load %1380 : !llvm.ptr -> i32
    %1382 = arith.cmpi slt, %1381, %1300 : i32
    cf.cond_br %1382, ^bb199, ^bb200
    ^bb199:
      %1383 = arith.constant 0 : i32
      %1384 = llvm.mlir.constant(1 : i64) : i64
      %1385 = llvm.alloca %1384 x i32 : (i64) -> !llvm.ptr
      llvm.store %1383, %1385 : i32, !llvm.ptr
      cf.br ^bb201
      ^bb201:
      %1386 = llvm.load %1385 : !llvm.ptr -> i32
      %1387 = arith.cmpi slt, %1386, %1300 : i32
      cf.cond_br %1387, ^bb202, ^bb203
      ^bb202:
        %1388 = llvm.load %1380 : !llvm.ptr -> i32
        %1389 = arith.muli %1388, %1300 : i32
        %1390 = llvm.load %1385 : !llvm.ptr -> i32
        %1391 = arith.addi %1389, %1390 : i32
        %1393 = llvm.mlir.addressof @g_type : !llvm.ptr
        %1394 = llvm.load %1393 : !llvm.ptr -> !llvm.ptr
        %1395 = arith.extsi %1391 : i32 to i64
        %1396 = llvm.getelementptr %1394[%1395] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1392 = llvm.load %1396 : !llvm.ptr -> i32
        %1397 = llvm.mlir.addressof @CT_O : !llvm.ptr
        %1398 = llvm.load %1397 : !llvm.ptr -> i32
        %1399 = arith.cmpi eq, %1392, %1398 : i32
        cf.cond_br %1399, ^bb204, ^bb205
        ^bb204:
          %1400 = arith.constant 10 : i32
          %1401 = llvm.load %1361 : !llvm.ptr -> i32
          %1402 = arith.addi %1400, %1401 : i32
          %1403 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
          %1404 = llvm.load %1403 : !llvm.ptr -> !llvm.ptr
          %1405 = arith.extsi %1391 : i32 to i64
          %1406 = llvm.getelementptr %1404[%1405] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %1402, %1406 : i32, !llvm.ptr
          %1407 = llvm.load %1361 : !llvm.ptr -> i32
          %1408 = arith.constant 1 : i32
          %1409 = arith.addi %1407, %1408 : i32
          llvm.store %1409, %1361 : i32, !llvm.ptr
          cf.br ^bb206
        ^bb205:
          %1411 = llvm.mlir.addressof @g_type : !llvm.ptr
          %1412 = llvm.load %1411 : !llvm.ptr -> !llvm.ptr
          %1413 = arith.extsi %1391 : i32 to i64
          %1414 = llvm.getelementptr %1412[%1413] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1410 = llvm.load %1414 : !llvm.ptr -> i32
          %1415 = llvm.mlir.addressof @CT_L : !llvm.ptr
          %1416 = llvm.load %1415 : !llvm.ptr -> i32
          %1417 = arith.cmpi eq, %1410, %1416 : i32
          cf.cond_br %1417, ^bb207, ^bb208
          ^bb207:
            %1419 = llvm.mlir.addressof @g_letter : !llvm.ptr
            %1420 = llvm.load %1419 : !llvm.ptr -> !llvm.ptr
            %1421 = arith.extsi %1391 : i32 to i64
            %1422 = llvm.getelementptr %1420[%1421] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %1418 = llvm.load %1422 : !llvm.ptr -> i32
            %1423 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
            %1424 = llvm.load %1423 : !llvm.ptr -> !llvm.ptr
            %1425 = arith.extsi %1391 : i32 to i64
            %1426 = llvm.getelementptr %1424[%1425] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %1418, %1426 : i32, !llvm.ptr
            cf.br ^bb209
          ^bb208:
            cf.br ^bb209
          ^bb209:
          cf.br ^bb206
        ^bb206:
        %1427 = llvm.load %1385 : !llvm.ptr -> i32
        %1428 = arith.constant 1 : i32
        %1429 = arith.addi %1427, %1428 : i32
        llvm.store %1429, %1385 : i32, !llvm.ptr
        cf.br ^bb201
      ^bb203:
      %1430 = llvm.load %1380 : !llvm.ptr -> i32
      %1431 = arith.constant 1 : i32
      %1432 = arith.addi %1430, %1431 : i32
      llvm.store %1432, %1380 : i32, !llvm.ptr
      cf.br ^bb198
    ^bb200:
    %1433 = arith.constant 0 : i32
    %1434 = llvm.mlir.constant(1 : i64) : i64
    %1435 = llvm.alloca %1434 x i32 : (i64) -> !llvm.ptr
    llvm.store %1433, %1435 : i32, !llvm.ptr
    cf.br ^bb210
    ^bb210:
    %1436 = llvm.load %1435 : !llvm.ptr -> i32
    %1437 = llvm.load %1361 : !llvm.ptr -> i32
    %1438 = arith.cmpi slt, %1436, %1437 : i32
    cf.cond_br %1438, ^bb211, ^bb212
    ^bb211:
      %1439 = llvm.mlir.addressof @DIGITS_19 : !llvm.ptr
      %1440 = llvm.load %1439 : !llvm.ptr -> i32
      %1441 = llvm.mlir.addressof @csp_domains : !llvm.ptr
      %1442 = llvm.load %1441 : !llvm.ptr -> !llvm.ptr
      %1443 = arith.constant 10 : i32
      %1444 = llvm.load %1435 : !llvm.ptr -> i32
      %1445 = arith.addi %1443, %1444 : i32
      %1446 = arith.extsi %1445 : i32 to i64
      %1447 = llvm.getelementptr %1442[%1446] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1440, %1447 : i32, !llvm.ptr
      %1448 = llvm.load %1435 : !llvm.ptr -> i32
      %1449 = arith.constant 1 : i32
      %1450 = arith.addi %1448, %1449 : i32
      llvm.store %1450, %1435 : i32, !llvm.ptr
      cf.br ^bb210
    ^bb212:
    %1451 = arith.constant 10 : i32
    %1452 = llvm.load %1361 : !llvm.ptr -> i32
    %1453 = arith.addi %1451, %1452 : i32
    %1454 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
    llvm.store %1453, %1454 : i32, !llvm.ptr
    %1455 = arith.constant 0 : i32
    %1456 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    llvm.store %1455, %1456 : i32, !llvm.ptr
    %1457 = arith.constant 0 : i32
    %1458 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
    llvm.store %1457, %1458 : i32, !llvm.ptr
    %1459 = arith.constant 0 : i32
    %1460 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
    llvm.store %1459, %1460 : i32, !llvm.ptr
    %1461 = arith.constant 0 : i32
    %1462 = llvm.mlir.addressof @inv_idx_pool_next : !llvm.ptr
    llvm.store %1461, %1462 : i32, !llvm.ptr
    %1463 = arith.constant 0 : i32
    %1464 = llvm.mlir.addressof @sums_pool_next : !llvm.ptr
    llvm.store %1463, %1464 : i32, !llvm.ptr
    %1465 = arith.constant 0 : i32
    %1466 = llvm.mlir.constant(1 : i64) : i64
    %1467 = llvm.alloca %1466 x i32 : (i64) -> !llvm.ptr
    llvm.store %1465, %1467 : i32, !llvm.ptr
    cf.br ^bb213
    ^bb213:
    %1468 = llvm.load %1467 : !llvm.ptr -> i32
    %1469 = arith.cmpi slt, %1468, %1300 : i32
    cf.cond_br %1469, ^bb214, ^bb215
    ^bb214:
      %1470 = arith.constant 0 : i32
      %1471 = llvm.mlir.constant(1 : i64) : i64
      %1472 = llvm.alloca %1471 x i32 : (i64) -> !llvm.ptr
      llvm.store %1470, %1472 : i32, !llvm.ptr
      cf.br ^bb216
      ^bb216:
      %1473 = llvm.load %1472 : !llvm.ptr -> i32
      %1474 = arith.cmpi slt, %1473, %1300 : i32
      cf.cond_br %1474, ^bb217, ^bb218
      ^bb217:
        %1475 = llvm.load %1467 : !llvm.ptr -> i32
        %1476 = arith.muli %1475, %1300 : i32
        %1477 = llvm.load %1472 : !llvm.ptr -> i32
        %1478 = arith.addi %1476, %1477 : i32
        %1480 = llvm.mlir.addressof @g_type : !llvm.ptr
        %1481 = llvm.load %1480 : !llvm.ptr -> !llvm.ptr
        %1482 = arith.extsi %1478 : i32 to i64
        %1483 = llvm.getelementptr %1481[%1482] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1479 = llvm.load %1483 : !llvm.ptr -> i32
        %1484 = llvm.mlir.addressof @CT_C : !llvm.ptr
        %1485 = llvm.load %1484 : !llvm.ptr -> i32
        %1486 = arith.cmpi eq, %1479, %1485 : i32
        cf.cond_br %1486, ^bb219, ^bb220
        ^bb219:
          %1488 = llvm.mlir.addressof @g_h_len : !llvm.ptr
          %1489 = llvm.load %1488 : !llvm.ptr -> !llvm.ptr
          %1490 = arith.extsi %1478 : i32 to i64
          %1491 = llvm.getelementptr %1489[%1490] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1487 = llvm.load %1491 : !llvm.ptr -> i32
          %1492 = arith.constant 0 : i32
          %1493 = arith.cmpi sgt, %1487, %1492 : i32
          cf.cond_br %1493, ^bb222, ^bb223
          ^bb222:
            %1494 = arith.constant 0 : i32
            %1495 = llvm.mlir.constant(1 : i64) : i64
            %1496 = llvm.alloca %1495 x i32 : (i64) -> !llvm.ptr
            llvm.store %1494, %1496 : i32, !llvm.ptr
            %1497 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
            %1498 = llvm.load %1497 : !llvm.ptr -> i32
            %1499 = llvm.load %1472 : !llvm.ptr -> i32
            %1500 = arith.constant 1 : i32
            %1501 = arith.addi %1499, %1500 : i32
            %1502 = llvm.mlir.constant(1 : i64) : i64
            %1503 = llvm.alloca %1502 x i32 : (i64) -> !llvm.ptr
            llvm.store %1501, %1503 : i32, !llvm.ptr
            cf.br ^bb225
            ^bb225:
            %1504 = llvm.load %1503 : !llvm.ptr -> i32
            %1505 = arith.cmpi slt, %1504, %1300 : i32
            cf.cond_br %1505, ^bb226, ^bb227
            ^bb226:
              %1506 = llvm.load %1467 : !llvm.ptr -> i32
              %1507 = arith.muli %1506, %1300 : i32
              %1508 = llvm.load %1503 : !llvm.ptr -> i32
              %1509 = arith.addi %1507, %1508 : i32
              %1511 = llvm.mlir.addressof @g_type : !llvm.ptr
              %1512 = llvm.load %1511 : !llvm.ptr -> !llvm.ptr
              %1513 = arith.extsi %1509 : i32 to i64
              %1514 = llvm.getelementptr %1512[%1513] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %1510 = llvm.load %1514 : !llvm.ptr -> i32
              %1515 = llvm.mlir.addressof @CT_O : !llvm.ptr
              %1516 = llvm.load %1515 : !llvm.ptr -> i32
              %1517 = arith.cmpi ne, %1510, %1516 : i32
              %1518 = scf.if %1517 -> (i1) {
                %1520 = llvm.mlir.addressof @g_type : !llvm.ptr
                %1521 = llvm.load %1520 : !llvm.ptr -> !llvm.ptr
                %1522 = arith.extsi %1509 : i32 to i64
                %1523 = llvm.getelementptr %1521[%1522] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %1519 = llvm.load %1523 : !llvm.ptr -> i32
                %1524 = llvm.mlir.addressof @CT_L : !llvm.ptr
                %1525 = llvm.load %1524 : !llvm.ptr -> i32
                %1526 = arith.cmpi ne, %1519, %1525 : i32
                scf.yield %1526 : i1
              } else {
                %1527 = arith.constant false
                scf.yield %1527 : i1
              }
              cf.cond_br %1518, ^bb228, ^bb229
              ^bb228:
                cf.br ^bb227
              ^bb229:
                cf.br ^bb230
              ^bb230:
              %1529 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
              %1530 = llvm.load %1529 : !llvm.ptr -> !llvm.ptr
              %1531 = arith.extsi %1509 : i32 to i64
              %1532 = llvm.getelementptr %1530[%1531] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %1528 = llvm.load %1532 : !llvm.ptr -> i32
              %1533 = llvm.mlir.addressof @cv_pool : !llvm.ptr
              %1534 = llvm.load %1533 : !llvm.ptr -> !llvm.ptr
              %1535 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              %1536 = llvm.load %1535 : !llvm.ptr -> i32
              %1537 = arith.extsi %1536 : i32 to i64
              %1538 = llvm.getelementptr %1534[%1537] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %1528, %1538 : i32, !llvm.ptr
              %1539 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              %1540 = llvm.load %1539 : !llvm.ptr -> i32
              %1541 = arith.constant 1 : i32
              %1542 = arith.addi %1540, %1541 : i32
              %1543 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              llvm.store %1542, %1543 : i32, !llvm.ptr
              %1544 = llvm.load %1496 : !llvm.ptr -> i32
              %1545 = arith.constant 1 : i32
              %1546 = arith.addi %1544, %1545 : i32
              llvm.store %1546, %1496 : i32, !llvm.ptr
              %1547 = llvm.load %1503 : !llvm.ptr -> i32
              %1548 = arith.constant 1 : i32
              %1549 = arith.addi %1547, %1548 : i32
              llvm.store %1549, %1503 : i32, !llvm.ptr
              cf.br ^bb225
            ^bb227:
            %1550 = llvm.load %1496 : !llvm.ptr -> i32
            %1551 = arith.constant 0 : i32
            %1552 = arith.cmpi sgt, %1550, %1551 : i32
            cf.cond_br %1552, ^bb231, ^bb232
            ^bb231:
              %1554 = arith.constant 0 : i32
              %1555 = llvm.load %1496 : !llvm.ptr -> i32
              func.call @add_run(%1478, %1554, %1498, %1555) : (i32, i32, i32, i32) -> ()
              cf.br ^bb233
            ^bb232:
              cf.br ^bb233
            ^bb233:
            cf.br ^bb224
          ^bb223:
            cf.br ^bb224
          ^bb224:
          %1557 = llvm.mlir.addressof @g_v_len : !llvm.ptr
          %1558 = llvm.load %1557 : !llvm.ptr -> !llvm.ptr
          %1559 = arith.extsi %1478 : i32 to i64
          %1560 = llvm.getelementptr %1558[%1559] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %1556 = llvm.load %1560 : !llvm.ptr -> i32
          %1561 = arith.constant 0 : i32
          %1562 = arith.cmpi sgt, %1556, %1561 : i32
          cf.cond_br %1562, ^bb234, ^bb235
          ^bb234:
            %1563 = arith.constant 0 : i32
            %1564 = llvm.mlir.constant(1 : i64) : i64
            %1565 = llvm.alloca %1564 x i32 : (i64) -> !llvm.ptr
            llvm.store %1563, %1565 : i32, !llvm.ptr
            %1566 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
            %1567 = llvm.load %1566 : !llvm.ptr -> i32
            %1568 = llvm.load %1467 : !llvm.ptr -> i32
            %1569 = arith.constant 1 : i32
            %1570 = arith.addi %1568, %1569 : i32
            %1571 = llvm.mlir.constant(1 : i64) : i64
            %1572 = llvm.alloca %1571 x i32 : (i64) -> !llvm.ptr
            llvm.store %1570, %1572 : i32, !llvm.ptr
            cf.br ^bb237
            ^bb237:
            %1573 = llvm.load %1572 : !llvm.ptr -> i32
            %1574 = arith.cmpi slt, %1573, %1300 : i32
            cf.cond_br %1574, ^bb238, ^bb239
            ^bb238:
              %1575 = llvm.load %1572 : !llvm.ptr -> i32
              %1576 = arith.muli %1575, %1300 : i32
              %1577 = llvm.load %1472 : !llvm.ptr -> i32
              %1578 = arith.addi %1576, %1577 : i32
              %1580 = llvm.mlir.addressof @g_type : !llvm.ptr
              %1581 = llvm.load %1580 : !llvm.ptr -> !llvm.ptr
              %1582 = arith.extsi %1578 : i32 to i64
              %1583 = llvm.getelementptr %1581[%1582] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %1579 = llvm.load %1583 : !llvm.ptr -> i32
              %1584 = llvm.mlir.addressof @CT_O : !llvm.ptr
              %1585 = llvm.load %1584 : !llvm.ptr -> i32
              %1586 = arith.cmpi ne, %1579, %1585 : i32
              %1587 = scf.if %1586 -> (i1) {
                %1589 = llvm.mlir.addressof @g_type : !llvm.ptr
                %1590 = llvm.load %1589 : !llvm.ptr -> !llvm.ptr
                %1591 = arith.extsi %1578 : i32 to i64
                %1592 = llvm.getelementptr %1590[%1591] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %1588 = llvm.load %1592 : !llvm.ptr -> i32
                %1593 = llvm.mlir.addressof @CT_L : !llvm.ptr
                %1594 = llvm.load %1593 : !llvm.ptr -> i32
                %1595 = arith.cmpi ne, %1588, %1594 : i32
                scf.yield %1595 : i1
              } else {
                %1596 = arith.constant false
                scf.yield %1596 : i1
              }
              cf.cond_br %1587, ^bb240, ^bb241
              ^bb240:
                cf.br ^bb239
              ^bb241:
                cf.br ^bb242
              ^bb242:
              %1598 = llvm.mlir.addressof @cell_to_var : !llvm.ptr
              %1599 = llvm.load %1598 : !llvm.ptr -> !llvm.ptr
              %1600 = arith.extsi %1578 : i32 to i64
              %1601 = llvm.getelementptr %1599[%1600] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              %1597 = llvm.load %1601 : !llvm.ptr -> i32
              %1602 = llvm.mlir.addressof @cv_pool : !llvm.ptr
              %1603 = llvm.load %1602 : !llvm.ptr -> !llvm.ptr
              %1604 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              %1605 = llvm.load %1604 : !llvm.ptr -> i32
              %1606 = arith.extsi %1605 : i32 to i64
              %1607 = llvm.getelementptr %1603[%1606] : (!llvm.ptr, i64) -> !llvm.ptr, i32
              llvm.store %1597, %1607 : i32, !llvm.ptr
              %1608 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              %1609 = llvm.load %1608 : !llvm.ptr -> i32
              %1610 = arith.constant 1 : i32
              %1611 = arith.addi %1609, %1610 : i32
              %1612 = llvm.mlir.addressof @cv_pool_next : !llvm.ptr
              llvm.store %1611, %1612 : i32, !llvm.ptr
              %1613 = llvm.load %1565 : !llvm.ptr -> i32
              %1614 = arith.constant 1 : i32
              %1615 = arith.addi %1613, %1614 : i32
              llvm.store %1615, %1565 : i32, !llvm.ptr
              %1616 = llvm.load %1572 : !llvm.ptr -> i32
              %1617 = arith.constant 1 : i32
              %1618 = arith.addi %1616, %1617 : i32
              llvm.store %1618, %1572 : i32, !llvm.ptr
              cf.br ^bb237
            ^bb239:
            %1619 = llvm.load %1565 : !llvm.ptr -> i32
            %1620 = arith.constant 0 : i32
            %1621 = arith.cmpi sgt, %1619, %1620 : i32
            cf.cond_br %1621, ^bb243, ^bb244
            ^bb243:
              %1623 = arith.constant 1 : i32
              %1624 = llvm.load %1565 : !llvm.ptr -> i32
              func.call @add_run(%1478, %1623, %1567, %1624) : (i32, i32, i32, i32) -> ()
              cf.br ^bb245
            ^bb244:
              cf.br ^bb245
            ^bb245:
            cf.br ^bb236
          ^bb235:
            cf.br ^bb236
          ^bb236:
          cf.br ^bb221
        ^bb220:
          cf.br ^bb221
        ^bb221:
        %1625 = llvm.load %1472 : !llvm.ptr -> i32
        %1626 = arith.constant 1 : i32
        %1627 = arith.addi %1625, %1626 : i32
        llvm.store %1627, %1472 : i32, !llvm.ptr
        cf.br ^bb216
      ^bb218:
      %1628 = llvm.load %1467 : !llvm.ptr -> i32
      %1629 = arith.constant 1 : i32
      %1630 = arith.addi %1628, %1629 : i32
      llvm.store %1630, %1467 : i32, !llvm.ptr
      cf.br ^bb213
    ^bb215:
    %1631 = arith.constant 0 : i32
    %1632 = llvm.mlir.constant(1 : i64) : i64
    %1633 = llvm.alloca %1632 x i32 : (i64) -> !llvm.ptr
    llvm.store %1631, %1633 : i32, !llvm.ptr
    cf.br ^bb246
    ^bb246:
    %1634 = llvm.load %1633 : !llvm.ptr -> i32
    %1635 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
    %1636 = llvm.load %1635 : !llvm.ptr -> i32
    %1637 = arith.cmpi slt, %1634, %1636 : i32
    cf.cond_br %1637, ^bb247, ^bb248
    ^bb247:
      %1638 = arith.constant 0 : i32
      %1639 = llvm.mlir.addressof @v2r_count : !llvm.ptr
      %1640 = llvm.load %1639 : !llvm.ptr -> !llvm.ptr
      %1641 = llvm.load %1633 : !llvm.ptr -> i32
      %1642 = arith.extsi %1641 : i32 to i64
      %1643 = llvm.getelementptr %1640[%1642] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1638, %1643 : i32, !llvm.ptr
      %1644 = llvm.load %1633 : !llvm.ptr -> i32
      %1645 = arith.constant 1 : i32
      %1646 = arith.addi %1644, %1645 : i32
      llvm.store %1646, %1633 : i32, !llvm.ptr
      cf.br ^bb246
    ^bb248:
    %1647 = arith.constant 0 : i32
    %1648 = llvm.mlir.constant(1 : i64) : i64
    %1649 = llvm.alloca %1648 x i32 : (i64) -> !llvm.ptr
    llvm.store %1647, %1649 : i32, !llvm.ptr
    cf.br ^bb249
    ^bb249:
    %1650 = llvm.load %1649 : !llvm.ptr -> i32
    %1651 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    %1652 = llvm.load %1651 : !llvm.ptr -> i32
    %1653 = arith.cmpi slt, %1650, %1652 : i32
    cf.cond_br %1653, ^bb250, ^bb251
    ^bb250:
      %1655 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
      %1656 = llvm.load %1655 : !llvm.ptr -> !llvm.ptr
      %1657 = llvm.load %1649 : !llvm.ptr -> i32
      %1658 = arith.extsi %1657 : i32 to i64
      %1659 = llvm.getelementptr %1656[%1658] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1654 = llvm.load %1659 : !llvm.ptr -> i32
      %1661 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
      %1662 = llvm.load %1661 : !llvm.ptr -> !llvm.ptr
      %1663 = llvm.load %1649 : !llvm.ptr -> i32
      %1664 = arith.extsi %1663 : i32 to i64
      %1665 = llvm.getelementptr %1662[%1664] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1660 = llvm.load %1665 : !llvm.ptr -> i32
      %1666 = arith.constant 0 : i32
      %1667 = llvm.mlir.constant(1 : i64) : i64
      %1668 = llvm.alloca %1667 x i32 : (i64) -> !llvm.ptr
      llvm.store %1666, %1668 : i32, !llvm.ptr
      cf.br ^bb252
      ^bb252:
      %1669 = llvm.load %1668 : !llvm.ptr -> i32
      %1670 = arith.cmpi slt, %1669, %1660 : i32
      cf.cond_br %1670, ^bb253, ^bb254
      ^bb253:
        %1672 = llvm.mlir.addressof @inv_pool : !llvm.ptr
        %1673 = llvm.load %1672 : !llvm.ptr -> !llvm.ptr
        %1674 = llvm.load %1668 : !llvm.ptr -> i32
        %1675 = arith.addi %1654, %1674 : i32
        %1676 = arith.extsi %1675 : i32 to i64
        %1677 = llvm.getelementptr %1673[%1676] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1671 = llvm.load %1677 : !llvm.ptr -> i32
        %1679 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %1680 = llvm.load %1679 : !llvm.ptr -> !llvm.ptr
        %1681 = arith.extsi %1671 : i32 to i64
        %1682 = llvm.getelementptr %1680[%1681] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1678 = llvm.load %1682 : !llvm.ptr -> i32
        %1683 = arith.constant 1 : i32
        %1684 = arith.addi %1678, %1683 : i32
        %1685 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %1686 = llvm.load %1685 : !llvm.ptr -> !llvm.ptr
        %1687 = arith.extsi %1671 : i32 to i64
        %1688 = llvm.getelementptr %1686[%1687] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1684, %1688 : i32, !llvm.ptr
        %1689 = llvm.load %1668 : !llvm.ptr -> i32
        %1690 = arith.constant 1 : i32
        %1691 = arith.addi %1689, %1690 : i32
        llvm.store %1691, %1668 : i32, !llvm.ptr
        cf.br ^bb252
      ^bb254:
      %1692 = llvm.load %1649 : !llvm.ptr -> i32
      %1693 = arith.constant 1 : i32
      %1694 = arith.addi %1692, %1693 : i32
      llvm.store %1694, %1649 : i32, !llvm.ptr
      cf.br ^bb249
    ^bb251:
    %1695 = arith.constant 0 : i32
    %1696 = llvm.mlir.constant(1 : i64) : i64
    %1697 = llvm.alloca %1696 x i32 : (i64) -> !llvm.ptr
    llvm.store %1695, %1697 : i32, !llvm.ptr
    %1698 = arith.constant 0 : i32
    %1699 = llvm.mlir.constant(1 : i64) : i64
    %1700 = llvm.alloca %1699 x i32 : (i64) -> !llvm.ptr
    llvm.store %1698, %1700 : i32, !llvm.ptr
    cf.br ^bb255
    ^bb255:
    %1701 = llvm.load %1700 : !llvm.ptr -> i32
    %1702 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
    %1703 = llvm.load %1702 : !llvm.ptr -> i32
    %1704 = arith.cmpi slt, %1701, %1703 : i32
    cf.cond_br %1704, ^bb256, ^bb257
    ^bb256:
      %1705 = llvm.load %1697 : !llvm.ptr -> i32
      %1706 = llvm.mlir.addressof @v2r_off : !llvm.ptr
      %1707 = llvm.load %1706 : !llvm.ptr -> !llvm.ptr
      %1708 = llvm.load %1700 : !llvm.ptr -> i32
      %1709 = arith.extsi %1708 : i32 to i64
      %1710 = llvm.getelementptr %1707[%1709] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1705, %1710 : i32, !llvm.ptr
      %1711 = llvm.load %1697 : !llvm.ptr -> i32
      %1713 = llvm.mlir.addressof @v2r_count : !llvm.ptr
      %1714 = llvm.load %1713 : !llvm.ptr -> !llvm.ptr
      %1715 = llvm.load %1700 : !llvm.ptr -> i32
      %1716 = arith.extsi %1715 : i32 to i64
      %1717 = llvm.getelementptr %1714[%1716] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1712 = llvm.load %1717 : !llvm.ptr -> i32
      %1718 = arith.addi %1711, %1712 : i32
      llvm.store %1718, %1697 : i32, !llvm.ptr
      %1719 = arith.constant 0 : i32
      %1720 = llvm.mlir.addressof @v2r_count : !llvm.ptr
      %1721 = llvm.load %1720 : !llvm.ptr -> !llvm.ptr
      %1722 = llvm.load %1700 : !llvm.ptr -> i32
      %1723 = arith.extsi %1722 : i32 to i64
      %1724 = llvm.getelementptr %1721[%1723] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1719, %1724 : i32, !llvm.ptr
      %1725 = llvm.load %1700 : !llvm.ptr -> i32
      %1726 = arith.constant 1 : i32
      %1727 = arith.addi %1725, %1726 : i32
      llvm.store %1727, %1700 : i32, !llvm.ptr
      cf.br ^bb255
    ^bb257:
    %1728 = arith.constant 0 : i32
    %1729 = llvm.mlir.constant(1 : i64) : i64
    %1730 = llvm.alloca %1729 x i32 : (i64) -> !llvm.ptr
    llvm.store %1728, %1730 : i32, !llvm.ptr
    cf.br ^bb258
    ^bb258:
    %1731 = llvm.load %1730 : !llvm.ptr -> i32
    %1732 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    %1733 = llvm.load %1732 : !llvm.ptr -> i32
    %1734 = arith.cmpi slt, %1731, %1733 : i32
    cf.cond_br %1734, ^bb259, ^bb260
    ^bb259:
      %1736 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
      %1737 = llvm.load %1736 : !llvm.ptr -> !llvm.ptr
      %1738 = llvm.load %1730 : !llvm.ptr -> i32
      %1739 = arith.extsi %1738 : i32 to i64
      %1740 = llvm.getelementptr %1737[%1739] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1735 = llvm.load %1740 : !llvm.ptr -> i32
      %1742 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
      %1743 = llvm.load %1742 : !llvm.ptr -> !llvm.ptr
      %1744 = llvm.load %1730 : !llvm.ptr -> i32
      %1745 = arith.extsi %1744 : i32 to i64
      %1746 = llvm.getelementptr %1743[%1745] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1741 = llvm.load %1746 : !llvm.ptr -> i32
      %1747 = arith.constant 0 : i32
      %1748 = llvm.mlir.constant(1 : i64) : i64
      %1749 = llvm.alloca %1748 x i32 : (i64) -> !llvm.ptr
      llvm.store %1747, %1749 : i32, !llvm.ptr
      cf.br ^bb261
      ^bb261:
      %1750 = llvm.load %1749 : !llvm.ptr -> i32
      %1751 = arith.cmpi slt, %1750, %1741 : i32
      cf.cond_br %1751, ^bb262, ^bb263
      ^bb262:
        %1753 = llvm.mlir.addressof @inv_pool : !llvm.ptr
        %1754 = llvm.load %1753 : !llvm.ptr -> !llvm.ptr
        %1755 = llvm.load %1749 : !llvm.ptr -> i32
        %1756 = arith.addi %1735, %1755 : i32
        %1757 = arith.extsi %1756 : i32 to i64
        %1758 = llvm.getelementptr %1754[%1757] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1752 = llvm.load %1758 : !llvm.ptr -> i32
        %1759 = llvm.load %1730 : !llvm.ptr -> i32
        %1760 = llvm.mlir.addressof @v2r_data : !llvm.ptr
        %1761 = llvm.load %1760 : !llvm.ptr -> !llvm.ptr
        %1763 = llvm.mlir.addressof @v2r_off : !llvm.ptr
        %1764 = llvm.load %1763 : !llvm.ptr -> !llvm.ptr
        %1765 = arith.extsi %1752 : i32 to i64
        %1766 = llvm.getelementptr %1764[%1765] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1762 = llvm.load %1766 : !llvm.ptr -> i32
        %1768 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %1769 = llvm.load %1768 : !llvm.ptr -> !llvm.ptr
        %1770 = arith.extsi %1752 : i32 to i64
        %1771 = llvm.getelementptr %1769[%1770] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1767 = llvm.load %1771 : !llvm.ptr -> i32
        %1772 = arith.addi %1762, %1767 : i32
        %1773 = arith.extsi %1772 : i32 to i64
        %1774 = llvm.getelementptr %1761[%1773] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1759, %1774 : i32, !llvm.ptr
        %1776 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %1777 = llvm.load %1776 : !llvm.ptr -> !llvm.ptr
        %1778 = arith.extsi %1752 : i32 to i64
        %1779 = llvm.getelementptr %1777[%1778] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %1775 = llvm.load %1779 : !llvm.ptr -> i32
        %1780 = arith.constant 1 : i32
        %1781 = arith.addi %1775, %1780 : i32
        %1782 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %1783 = llvm.load %1782 : !llvm.ptr -> !llvm.ptr
        %1784 = arith.extsi %1752 : i32 to i64
        %1785 = llvm.getelementptr %1783[%1784] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1781, %1785 : i32, !llvm.ptr
        %1786 = llvm.load %1749 : !llvm.ptr -> i32
        %1787 = arith.constant 1 : i32
        %1788 = arith.addi %1786, %1787 : i32
        llvm.store %1788, %1749 : i32, !llvm.ptr
        cf.br ^bb261
      ^bb263:
      %1789 = llvm.load %1730 : !llvm.ptr -> i32
      %1790 = arith.constant 1 : i32
      %1791 = arith.addi %1789, %1790 : i32
      llvm.store %1791, %1730 : i32, !llvm.ptr
      cf.br ^bb258
    ^bb260:
    func.return
  }
  func.func @add_run(%arg0: i32, %arg1: i32, %arg2: i32, %arg3: i32) -> () {
    %1792 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    %1793 = llvm.load %1792 : !llvm.ptr -> i32
    %1794 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    %1795 = llvm.load %1794 : !llvm.ptr -> i32
    %1796 = arith.constant 1 : i32
    %1797 = arith.addi %1795, %1796 : i32
    %1798 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    llvm.store %1797, %1798 : i32, !llvm.ptr
    %1799 = llvm.mlir.addressof @run_cv_off : !llvm.ptr
    %1800 = llvm.load %1799 : !llvm.ptr -> !llvm.ptr
    %1801 = arith.extsi %1793 : i32 to i64
    %1802 = llvm.getelementptr %1800[%1801] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg2, %1802 : i32, !llvm.ptr
    %1803 = llvm.mlir.addressof @run_cv_count : !llvm.ptr
    %1804 = llvm.load %1803 : !llvm.ptr -> !llvm.ptr
    %1805 = arith.extsi %1793 : i32 to i64
    %1806 = llvm.getelementptr %1804[%1805] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg3, %1806 : i32, !llvm.ptr
    %1807 = llvm.mlir.addressof @run_length : !llvm.ptr
    %1808 = llvm.load %1807 : !llvm.ptr -> !llvm.ptr
    %1809 = arith.extsi %1793 : i32 to i64
    %1810 = llvm.getelementptr %1808[%1809] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %arg3, %1810 : i32, !llvm.ptr
    %1811 = arith.constant 0 : i32
    %1812 = arith.constant 0 : i32
    %1813 = arith.constant 0 : i32
    %1814 = arith.cmpi eq, %arg1, %1813 : i32
    %1815, %1816 = scf.if %1814 -> (i32, i32) {
      %1818 = llvm.mlir.addressof @g_h_len : !llvm.ptr
      %1819 = llvm.load %1818 : !llvm.ptr -> !llvm.ptr
      %1820 = arith.extsi %arg0 : i32 to i64
      %1821 = llvm.getelementptr %1819[%1820] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1817 = llvm.load %1821 : !llvm.ptr -> i32
      %1822 = arith.constant 4 : i32
      %1823 = arith.muli %arg0, %1822 : i32
      scf.yield %1817, %1823 : i32, i32
    } else {
      %1825 = llvm.mlir.addressof @g_v_len : !llvm.ptr
      %1826 = llvm.load %1825 : !llvm.ptr -> !llvm.ptr
      %1827 = arith.extsi %arg0 : i32 to i64
      %1828 = llvm.getelementptr %1826[%1827] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1824 = llvm.load %1828 : !llvm.ptr -> i32
      %1829 = arith.constant 4 : i32
      %1830 = arith.muli %arg0, %1829 : i32
      scf.yield %1824, %1830 : i32, i32
    }
    %1831 = arith.constant 1 : i32
    %1832 = arith.cmpi eq, %1815, %1831 : i32
    cf.cond_br %1832, ^bb264, ^bb265
    ^bb264:
      %1833 = arith.constant 1 : i32
      %1834 = llvm.mlir.addressof @run_nsl : !llvm.ptr
      %1835 = llvm.load %1834 : !llvm.ptr -> !llvm.ptr
      %1836 = arith.extsi %1793 : i32 to i64
      %1837 = llvm.getelementptr %1835[%1836] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1833, %1837 : i32, !llvm.ptr
      %1839 = llvm.mlir.addressof @g_h_data : !llvm.ptr
      %1840 = llvm.load %1839 : !llvm.ptr -> !llvm.ptr
      %1841 = arith.extsi %1816 : i32 to i64
      %1842 = llvm.getelementptr %1840[%1841] : (!llvm.ptr, i64) -> !llvm.ptr, i8
      %1838 = llvm.load %1842 : !llvm.ptr -> i8
      %1843 = arith.extsi %1838 : i8 to i32
      %1844 = arith.constant 65 : i32
      %1845 = arith.subi %1843, %1844 : i32
      %1846 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
      %1847 = llvm.load %1846 : !llvm.ptr -> !llvm.ptr
      %1848 = arith.extsi %1793 : i32 to i64
      %1849 = llvm.getelementptr %1847[%1848] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1845, %1849 : i32, !llvm.ptr
      %1850 = arith.constant 1 : i32
      %1851 = arith.cmpi eq, %arg1, %1850 : i32
      cf.cond_br %1851, ^bb267, ^bb268
      ^bb267:
        %1853 = llvm.mlir.addressof @g_v_data : !llvm.ptr
        %1854 = llvm.load %1853 : !llvm.ptr -> !llvm.ptr
        %1855 = arith.extsi %1816 : i32 to i64
        %1856 = llvm.getelementptr %1854[%1855] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1852 = llvm.load %1856 : !llvm.ptr -> i8
        %1857 = arith.extsi %1852 : i8 to i32
        %1858 = arith.constant 65 : i32
        %1859 = arith.subi %1857, %1858 : i32
        %1860 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
        %1861 = llvm.load %1860 : !llvm.ptr -> !llvm.ptr
        %1862 = arith.extsi %1793 : i32 to i64
        %1863 = llvm.getelementptr %1861[%1862] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1859, %1863 : i32, !llvm.ptr
        cf.br ^bb269
      ^bb268:
        cf.br ^bb269
      ^bb269:
      %1864 = arith.constant 0 : i32
      %1865 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
      %1866 = llvm.load %1865 : !llvm.ptr -> !llvm.ptr
      %1867 = arith.extsi %1793 : i32 to i64
      %1868 = llvm.getelementptr %1866[%1867] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1864, %1868 : i32, !llvm.ptr
      cf.br ^bb266
    ^bb265:
      %1869 = arith.constant 2 : i32
      %1870 = llvm.mlir.addressof @run_nsl : !llvm.ptr
      %1871 = llvm.load %1870 : !llvm.ptr -> !llvm.ptr
      %1872 = arith.extsi %1793 : i32 to i64
      %1873 = llvm.getelementptr %1871[%1872] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1869, %1873 : i32, !llvm.ptr
      %1874 = arith.constant 0 : i32
      %1875 = arith.cmpi eq, %arg1, %1874 : i32
      cf.cond_br %1875, ^bb270, ^bb271
      ^bb270:
        %1877 = llvm.mlir.addressof @g_h_data : !llvm.ptr
        %1878 = llvm.load %1877 : !llvm.ptr -> !llvm.ptr
        %1879 = arith.extsi %1816 : i32 to i64
        %1880 = llvm.getelementptr %1878[%1879] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1876 = llvm.load %1880 : !llvm.ptr -> i8
        %1881 = arith.extsi %1876 : i8 to i32
        %1882 = arith.constant 65 : i32
        %1883 = arith.subi %1881, %1882 : i32
        %1884 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
        %1885 = llvm.load %1884 : !llvm.ptr -> !llvm.ptr
        %1886 = arith.extsi %1793 : i32 to i64
        %1887 = llvm.getelementptr %1885[%1886] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1883, %1887 : i32, !llvm.ptr
        %1889 = llvm.mlir.addressof @g_h_data : !llvm.ptr
        %1890 = llvm.load %1889 : !llvm.ptr -> !llvm.ptr
        %1891 = arith.constant 1 : i32
        %1892 = arith.addi %1816, %1891 : i32
        %1893 = arith.extsi %1892 : i32 to i64
        %1894 = llvm.getelementptr %1890[%1893] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1888 = llvm.load %1894 : !llvm.ptr -> i8
        %1895 = arith.extsi %1888 : i8 to i32
        %1896 = arith.constant 65 : i32
        %1897 = arith.subi %1895, %1896 : i32
        %1898 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
        %1899 = llvm.load %1898 : !llvm.ptr -> !llvm.ptr
        %1900 = arith.extsi %1793 : i32 to i64
        %1901 = llvm.getelementptr %1899[%1900] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1897, %1901 : i32, !llvm.ptr
        cf.br ^bb272
      ^bb271:
        %1903 = llvm.mlir.addressof @g_v_data : !llvm.ptr
        %1904 = llvm.load %1903 : !llvm.ptr -> !llvm.ptr
        %1905 = arith.extsi %1816 : i32 to i64
        %1906 = llvm.getelementptr %1904[%1905] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1902 = llvm.load %1906 : !llvm.ptr -> i8
        %1907 = arith.extsi %1902 : i8 to i32
        %1908 = arith.constant 65 : i32
        %1909 = arith.subi %1907, %1908 : i32
        %1910 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
        %1911 = llvm.load %1910 : !llvm.ptr -> !llvm.ptr
        %1912 = arith.extsi %1793 : i32 to i64
        %1913 = llvm.getelementptr %1911[%1912] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1909, %1913 : i32, !llvm.ptr
        %1915 = llvm.mlir.addressof @g_v_data : !llvm.ptr
        %1916 = llvm.load %1915 : !llvm.ptr -> !llvm.ptr
        %1917 = arith.constant 1 : i32
        %1918 = arith.addi %1816, %1917 : i32
        %1919 = arith.extsi %1918 : i32 to i64
        %1920 = llvm.getelementptr %1916[%1919] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %1914 = llvm.load %1920 : !llvm.ptr -> i8
        %1921 = arith.extsi %1914 : i8 to i32
        %1922 = arith.constant 65 : i32
        %1923 = arith.subi %1921, %1922 : i32
        %1924 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
        %1925 = llvm.load %1924 : !llvm.ptr -> !llvm.ptr
        %1926 = arith.extsi %1793 : i32 to i64
        %1927 = llvm.getelementptr %1925[%1926] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1923, %1927 : i32, !llvm.ptr
        cf.br ^bb272
      ^bb272:
      cf.br ^bb266
    ^bb266:
    %1928 = llvm.mlir.addressof @sums_pool_next : !llvm.ptr
    %1929 = llvm.load %1928 : !llvm.ptr -> i32
    %1930 = arith.constant 0 : i32
    %1931 = llvm.mlir.constant(1 : i64) : i64
    %1932 = llvm.alloca %1931 x i32 : (i64) -> !llvm.ptr
    llvm.store %1930, %1932 : i32, !llvm.ptr
    %1934 = llvm.mlir.addressof @run_length : !llvm.ptr
    %1935 = llvm.load %1934 : !llvm.ptr -> !llvm.ptr
    %1936 = arith.extsi %1793 : i32 to i64
    %1937 = llvm.getelementptr %1935[%1936] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %1933 = llvm.load %1937 : !llvm.ptr -> i32
    %1938 = arith.constant 1 : i32
    %1939 = llvm.mlir.constant(1 : i64) : i64
    %1940 = llvm.alloca %1939 x i32 : (i64) -> !llvm.ptr
    llvm.store %1938, %1940 : i32, !llvm.ptr
    cf.br ^bb273
    ^bb273:
    %1941 = llvm.load %1940 : !llvm.ptr -> i32
    %1942 = arith.constant 45 : i32
    %1943 = arith.cmpi sle, %1941, %1942 : i32
    cf.cond_br %1943, ^bb274, ^bb275
    ^bb274:
      %1944 = arith.constant 46 : i32
      %1945 = arith.muli %1933, %1944 : i32
      %1946 = llvm.load %1940 : !llvm.ptr -> i32
      %1947 = arith.addi %1945, %1946 : i32
      %1949 = llvm.mlir.addressof @perms_count : !llvm.ptr
      %1950 = llvm.load %1949 : !llvm.ptr -> !llvm.ptr
      %1951 = arith.extsi %1947 : i32 to i64
      %1952 = llvm.getelementptr %1950[%1951] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1948 = llvm.load %1952 : !llvm.ptr -> i32
      %1953 = arith.constant 0 : i32
      %1954 = arith.cmpi sgt, %1948, %1953 : i32
      cf.cond_br %1954, ^bb276, ^bb277
      ^bb276:
        %1955 = llvm.load %1940 : !llvm.ptr -> i32
        %1956 = llvm.mlir.addressof @sums_pool : !llvm.ptr
        %1957 = llvm.load %1956 : !llvm.ptr -> !llvm.ptr
        %1958 = llvm.mlir.addressof @sums_pool_next : !llvm.ptr
        %1959 = llvm.load %1958 : !llvm.ptr -> i32
        %1960 = arith.extsi %1959 : i32 to i64
        %1961 = llvm.getelementptr %1957[%1960] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %1955, %1961 : i32, !llvm.ptr
        %1962 = llvm.mlir.addressof @sums_pool_next : !llvm.ptr
        %1963 = llvm.load %1962 : !llvm.ptr -> i32
        %1964 = arith.constant 1 : i32
        %1965 = arith.addi %1963, %1964 : i32
        %1966 = llvm.mlir.addressof @sums_pool_next : !llvm.ptr
        llvm.store %1965, %1966 : i32, !llvm.ptr
        %1967 = llvm.load %1932 : !llvm.ptr -> i32
        %1968 = arith.constant 1 : i32
        %1969 = arith.addi %1967, %1968 : i32
        llvm.store %1969, %1932 : i32, !llvm.ptr
        cf.br ^bb278
      ^bb277:
        cf.br ^bb278
      ^bb278:
      %1970 = llvm.load %1940 : !llvm.ptr -> i32
      %1971 = arith.constant 1 : i32
      %1972 = arith.addi %1970, %1971 : i32
      llvm.store %1972, %1940 : i32, !llvm.ptr
      cf.br ^bb273
    ^bb275:
    %1973 = llvm.mlir.addressof @run_sums_off : !llvm.ptr
    %1974 = llvm.load %1973 : !llvm.ptr -> !llvm.ptr
    %1975 = arith.extsi %1793 : i32 to i64
    %1976 = llvm.getelementptr %1974[%1975] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1929, %1976 : i32, !llvm.ptr
    %1977 = llvm.load %1932 : !llvm.ptr -> i32
    %1978 = llvm.mlir.addressof @run_sums_count : !llvm.ptr
    %1979 = llvm.load %1978 : !llvm.ptr -> !llvm.ptr
    %1980 = arith.extsi %1793 : i32 to i64
    %1981 = llvm.getelementptr %1979[%1980] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1977, %1981 : i32, !llvm.ptr
    %1982 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
    %1983 = llvm.load %1982 : !llvm.ptr -> i32
    %1984 = arith.constant 0 : i32
    %1985 = llvm.mlir.constant(1 : i64) : i64
    %1986 = llvm.alloca %1985 x i32 : (i64) -> !llvm.ptr
    llvm.store %1984, %1986 : i32, !llvm.ptr
    %1987 = arith.constant 0 : i32
    %1988 = llvm.mlir.constant(1 : i64) : i64
    %1989 = llvm.alloca %1988 x i32 : (i64) -> !llvm.ptr
    llvm.store %1987, %1989 : i32, !llvm.ptr
    cf.br ^bb279
    ^bb279:
    %1990 = llvm.load %1989 : !llvm.ptr -> i32
    %1991 = arith.cmpi slt, %1990, %arg3 : i32
    cf.cond_br %1991, ^bb280, ^bb281
    ^bb280:
      %1993 = llvm.mlir.addressof @cv_pool : !llvm.ptr
      %1994 = llvm.load %1993 : !llvm.ptr -> !llvm.ptr
      %1995 = llvm.load %1989 : !llvm.ptr -> i32
      %1996 = arith.addi %arg2, %1995 : i32
      %1997 = arith.extsi %1996 : i32 to i64
      %1998 = llvm.getelementptr %1994[%1997] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %1992 = llvm.load %1998 : !llvm.ptr -> i32
      %1999 = llvm.mlir.addressof @inv_pool : !llvm.ptr
      %2000 = llvm.load %1999 : !llvm.ptr -> !llvm.ptr
      %2001 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      %2002 = llvm.load %2001 : !llvm.ptr -> i32
      %2003 = arith.extsi %2002 : i32 to i64
      %2004 = llvm.getelementptr %2000[%2003] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %1992, %2004 : i32, !llvm.ptr
      %2005 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      %2006 = llvm.load %2005 : !llvm.ptr -> i32
      %2007 = arith.constant 1 : i32
      %2008 = arith.addi %2006, %2007 : i32
      %2009 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      llvm.store %2008, %2009 : i32, !llvm.ptr
      %2010 = llvm.load %1986 : !llvm.ptr -> i32
      %2011 = arith.constant 1 : i32
      %2012 = arith.addi %2010, %2011 : i32
      llvm.store %2012, %1986 : i32, !llvm.ptr
      %2013 = llvm.load %1989 : !llvm.ptr -> i32
      %2014 = arith.constant 1 : i32
      %2015 = arith.addi %2013, %2014 : i32
      llvm.store %2015, %1989 : i32, !llvm.ptr
      cf.br ^bb279
    ^bb281:
    %2017 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
    %2018 = llvm.load %2017 : !llvm.ptr -> !llvm.ptr
    %2019 = arith.extsi %1793 : i32 to i64
    %2020 = llvm.getelementptr %2018[%2019] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2016 = llvm.load %2020 : !llvm.ptr -> i32
    %2021 = llvm.mlir.addressof @inv_pool : !llvm.ptr
    %2022 = llvm.load %2021 : !llvm.ptr -> !llvm.ptr
    %2023 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
    %2024 = llvm.load %2023 : !llvm.ptr -> i32
    %2025 = arith.extsi %2024 : i32 to i64
    %2026 = llvm.getelementptr %2022[%2025] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %2016, %2026 : i32, !llvm.ptr
    %2027 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
    %2028 = llvm.load %2027 : !llvm.ptr -> i32
    %2029 = arith.constant 1 : i32
    %2030 = arith.addi %2028, %2029 : i32
    %2031 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
    llvm.store %2030, %2031 : i32, !llvm.ptr
    %2032 = llvm.load %1986 : !llvm.ptr -> i32
    %2033 = arith.constant 1 : i32
    %2034 = arith.addi %2032, %2033 : i32
    llvm.store %2034, %1986 : i32, !llvm.ptr
    %2036 = llvm.mlir.addressof @run_nsl : !llvm.ptr
    %2037 = llvm.load %2036 : !llvm.ptr -> !llvm.ptr
    %2038 = arith.extsi %1793 : i32 to i64
    %2039 = llvm.getelementptr %2037[%2038] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2035 = llvm.load %2039 : !llvm.ptr -> i32
    %2040 = arith.constant 2 : i32
    %2041 = arith.cmpi eq, %2035, %2040 : i32
    cf.cond_br %2041, ^bb282, ^bb283
    ^bb282:
      %2043 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
      %2044 = llvm.load %2043 : !llvm.ptr -> !llvm.ptr
      %2045 = arith.extsi %1793 : i32 to i64
      %2046 = llvm.getelementptr %2044[%2045] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2042 = llvm.load %2046 : !llvm.ptr -> i32
      %2047 = llvm.mlir.addressof @inv_pool : !llvm.ptr
      %2048 = llvm.load %2047 : !llvm.ptr -> !llvm.ptr
      %2049 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      %2050 = llvm.load %2049 : !llvm.ptr -> i32
      %2051 = arith.extsi %2050 : i32 to i64
      %2052 = llvm.getelementptr %2048[%2051] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2042, %2052 : i32, !llvm.ptr
      %2053 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      %2054 = llvm.load %2053 : !llvm.ptr -> i32
      %2055 = arith.constant 1 : i32
      %2056 = arith.addi %2054, %2055 : i32
      %2057 = llvm.mlir.addressof @inv_pool_next : !llvm.ptr
      llvm.store %2056, %2057 : i32, !llvm.ptr
      %2058 = llvm.load %1986 : !llvm.ptr -> i32
      %2059 = arith.constant 1 : i32
      %2060 = arith.addi %2058, %2059 : i32
      llvm.store %2060, %1986 : i32, !llvm.ptr
      cf.br ^bb284
    ^bb283:
      cf.br ^bb284
    ^bb284:
    # String concatenation: !llvm.ptr + i32
    %2063 = llvm.load %1986 : !llvm.ptr -> i32
    func.call @sort_i32(%2062, %2063) : (!llvm.ptr, i32) -> ()
    # String concatenation: !llvm.ptr + i32
    %2066 = llvm.load %1986 : !llvm.ptr -> i32
    %2064 = func.call @unique_i32(%2065, %2066) : (!llvm.ptr, i32) -> i32
    llvm.store %2064, %1986 : i32, !llvm.ptr
    %2067 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
    %2068 = llvm.load %2067 : !llvm.ptr -> !llvm.ptr
    %2069 = arith.extsi %1793 : i32 to i64
    %2070 = llvm.getelementptr %2068[%2069] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %1983, %2070 : i32, !llvm.ptr
    %2071 = llvm.load %1986 : !llvm.ptr -> i32
    %2072 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
    %2073 = llvm.load %2072 : !llvm.ptr -> !llvm.ptr
    %2074 = arith.extsi %1793 : i32 to i64
    %2075 = llvm.getelementptr %2073[%2074] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %2071, %2075 : i32, !llvm.ptr
    %2076 = llvm.mlir.addressof @inv_idx_pool_next : !llvm.ptr
    %2077 = llvm.load %2076 : !llvm.ptr -> i32
    %2078 = arith.constant 0 : i32
    %2079 = llvm.mlir.constant(1 : i64) : i64
    %2080 = llvm.alloca %2079 x i32 : (i64) -> !llvm.ptr
    llvm.store %2078, %2080 : i32, !llvm.ptr
    cf.br ^bb285
    ^bb285:
    %2081 = llvm.load %2080 : !llvm.ptr -> i32
    %2082 = llvm.load %1986 : !llvm.ptr -> i32
    %2083 = arith.cmpi slt, %2081, %2082 : i32
    cf.cond_br %2083, ^bb286, ^bb287
    ^bb286:
      %2084 = llvm.load %2080 : !llvm.ptr -> i32
      %2085 = llvm.mlir.addressof @inv_idx_pool : !llvm.ptr
      %2086 = llvm.load %2085 : !llvm.ptr -> !llvm.ptr
      %2087 = llvm.mlir.addressof @inv_idx_pool_next : !llvm.ptr
      %2088 = llvm.load %2087 : !llvm.ptr -> i32
      %2089 = arith.extsi %2088 : i32 to i64
      %2090 = llvm.getelementptr %2086[%2089] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2084, %2090 : i32, !llvm.ptr
      %2091 = llvm.mlir.addressof @inv_idx_pool_next : !llvm.ptr
      %2092 = llvm.load %2091 : !llvm.ptr -> i32
      %2093 = arith.constant 1 : i32
      %2094 = arith.addi %2092, %2093 : i32
      %2095 = llvm.mlir.addressof @inv_idx_pool_next : !llvm.ptr
      llvm.store %2094, %2095 : i32, !llvm.ptr
      %2096 = llvm.load %2080 : !llvm.ptr -> i32
      %2097 = arith.constant 1 : i32
      %2098 = arith.addi %2096, %2097 : i32
      llvm.store %2098, %2080 : i32, !llvm.ptr
      cf.br ^bb285
    ^bb287:
    %2099 = llvm.mlir.addressof @run_inv_index : !llvm.ptr
    %2100 = llvm.load %2099 : !llvm.ptr -> !llvm.ptr
    %2101 = arith.extsi %1793 : i32 to i64
    %2102 = llvm.getelementptr %2100[%2101] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %2077, %2102 : i32, !llvm.ptr
    %2104 = arith.constant 4 : i32
    %2105 = arith.extsi %arg3 : i32 to i64
    %2106 = arith.extsi %2104 : i32 to i64
    %2103 = func.call @calloc(%2105, %2106) : (i64, i64) -> !llvm.ptr
    %2107 = llvm.mlir.constant(1 : i64) : i64
    %2108 = llvm.alloca %2107 x !llvm.ptr : (i64) -> !llvm.ptr
    llvm.store %2103, %2108 : !llvm.ptr, !llvm.ptr
    %2109 = arith.constant 0 : i32
    %2110 = llvm.mlir.constant(1 : i64) : i64
    %2111 = llvm.alloca %2110 x i32 : (i64) -> !llvm.ptr
    llvm.store %2109, %2111 : i32, !llvm.ptr
    cf.br ^bb288
    ^bb288:
    %2112 = llvm.load %2111 : !llvm.ptr -> i32
    %2113 = arith.cmpi slt, %2112, %arg3 : i32
    cf.cond_br %2113, ^bb289, ^bb290
    ^bb289:
      %2115 = llvm.mlir.addressof @cv_pool : !llvm.ptr
      %2116 = llvm.load %2115 : !llvm.ptr -> !llvm.ptr
      %2117 = llvm.load %2111 : !llvm.ptr -> i32
      %2118 = arith.addi %arg2, %2117 : i32
      %2119 = arith.extsi %2118 : i32 to i64
      %2120 = llvm.getelementptr %2116[%2119] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2114 = llvm.load %2120 : !llvm.ptr -> i32
      %2121 = llvm.load %2108 : !llvm.ptr -> !llvm.ptr
      %2122 = llvm.load %2111 : !llvm.ptr -> i32
      %2123 = arith.extsi %2122 : i32 to i64
      %2124 = llvm.getelementptr %2121[%2123] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2114, %2124 : i32, !llvm.ptr
      %2125 = llvm.load %2111 : !llvm.ptr -> i32
      %2126 = arith.constant 1 : i32
      %2127 = arith.addi %2125, %2126 : i32
      llvm.store %2127, %2111 : i32, !llvm.ptr
      cf.br ^bb288
    ^bb290:
    %2129 = llvm.load %2108 : !llvm.ptr -> !llvm.ptr
    func.call @sort_i32(%2129, %arg3) : (!llvm.ptr, i32) -> ()
    %2130 = arith.constant 0 : i32
    %2131 = llvm.mlir.constant(1 : i64) : i64
    %2132 = llvm.alloca %2131 x i32 : (i64) -> !llvm.ptr
    llvm.store %2130, %2132 : i32, !llvm.ptr
    %2133 = arith.constant 1 : i32
    %2134 = llvm.mlir.constant(1 : i64) : i64
    %2135 = llvm.alloca %2134 x i32 : (i64) -> !llvm.ptr
    llvm.store %2133, %2135 : i32, !llvm.ptr
    cf.br ^bb291
    ^bb291:
    %2136 = llvm.load %2135 : !llvm.ptr -> i32
    %2137 = arith.cmpi slt, %2136, %arg3 : i32
    cf.cond_br %2137, ^bb292, ^bb293
    ^bb292:
      %2139 = llvm.load %2108 : !llvm.ptr -> !llvm.ptr
      %2140 = llvm.load %2135 : !llvm.ptr -> i32
      %2141 = arith.extsi %2140 : i32 to i64
      %2142 = llvm.getelementptr %2139[%2141] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2138 = llvm.load %2142 : !llvm.ptr -> i32
      %2144 = llvm.load %2108 : !llvm.ptr -> !llvm.ptr
      %2145 = llvm.load %2135 : !llvm.ptr -> i32
      %2146 = arith.constant 1 : i32
      %2147 = arith.subi %2145, %2146 : i32
      %2148 = arith.extsi %2147 : i32 to i64
      %2149 = llvm.getelementptr %2144[%2148] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2143 = llvm.load %2149 : !llvm.ptr -> i32
      %2150 = arith.cmpi eq, %2138, %2143 : i32
      cf.cond_br %2150, ^bb294, ^bb295
      ^bb294:
        %2151 = arith.constant 1 : i32
        llvm.store %2151, %2132 : i32, !llvm.ptr
        cf.br ^bb293
      ^bb295:
        cf.br ^bb296
      ^bb296:
      %2152 = llvm.load %2135 : !llvm.ptr -> i32
      %2153 = arith.constant 1 : i32
      %2154 = arith.addi %2152, %2153 : i32
      llvm.store %2154, %2135 : i32, !llvm.ptr
      cf.br ^bb291
    ^bb293:
    %2155 = llvm.load %2132 : !llvm.ptr -> i32
    %2156 = llvm.mlir.addressof @run_dup : !llvm.ptr
    %2157 = llvm.load %2156 : !llvm.ptr -> !llvm.ptr
    %2158 = arith.extsi %1793 : i32 to i64
    %2159 = llvm.getelementptr %2157[%2158] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    llvm.store %2155, %2159 : i32, !llvm.ptr
    %2161 = llvm.load %2108 : !llvm.ptr -> !llvm.ptr
    func.call @free(%2161) : (!llvm.ptr) -> ()
    %2163 = llvm.mlir.addressof @run_nsl : !llvm.ptr
    %2164 = llvm.load %2163 : !llvm.ptr -> !llvm.ptr
    %2165 = arith.extsi %1793 : i32 to i64
    %2166 = llvm.getelementptr %2164[%2165] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2162 = llvm.load %2166 : !llvm.ptr -> i32
    %2167 = arith.constant 2 : i32
    %2168 = arith.cmpi eq, %2162, %2167 : i32
    %2169 = scf.if %2168 -> (i1) {
      %2171 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
      %2172 = llvm.load %2171 : !llvm.ptr -> !llvm.ptr
      %2173 = arith.extsi %1793 : i32 to i64
      %2174 = llvm.getelementptr %2172[%2173] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2170 = llvm.load %2174 : !llvm.ptr -> i32
      %2176 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
      %2177 = llvm.load %2176 : !llvm.ptr -> !llvm.ptr
      %2178 = arith.extsi %1793 : i32 to i64
      %2179 = llvm.getelementptr %2177[%2178] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2175 = llvm.load %2179 : !llvm.ptr -> i32
      %2180 = arith.cmpi eq, %2170, %2175 : i32
      scf.yield %2180 : i1
    } else {
      %2181 = arith.constant false
      scf.yield %2181 : i1
    }
    cf.cond_br %2169, ^bb297, ^bb298
    ^bb297:
      %2182 = arith.constant 1 : i32
      %2183 = llvm.mlir.addressof @run_ssame : !llvm.ptr
      %2184 = llvm.load %2183 : !llvm.ptr -> !llvm.ptr
      %2185 = arith.extsi %1793 : i32 to i64
      %2186 = llvm.getelementptr %2184[%2185] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2182, %2186 : i32, !llvm.ptr
      cf.br ^bb299
    ^bb298:
      %2187 = arith.constant 0 : i32
      %2188 = llvm.mlir.addressof @run_ssame : !llvm.ptr
      %2189 = llvm.load %2188 : !llvm.ptr -> !llvm.ptr
      %2190 = arith.extsi %1793 : i32 to i64
      %2191 = llvm.getelementptr %2189[%2190] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2187, %2191 : i32, !llvm.ptr
      cf.br ^bb299
    ^bb299:
    func.return
  }
  func.func @inv_index_lookup(%arg0: i32, %arg1: i32) -> i32 {
    %2193 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
    %2194 = llvm.load %2193 : !llvm.ptr -> !llvm.ptr
    %2195 = arith.extsi %arg0 : i32 to i64
    %2196 = llvm.getelementptr %2194[%2195] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2192 = llvm.load %2196 : !llvm.ptr -> i32
    %2198 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
    %2199 = llvm.load %2198 : !llvm.ptr -> !llvm.ptr
    %2200 = arith.extsi %arg0 : i32 to i64
    %2201 = llvm.getelementptr %2199[%2200] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2197 = llvm.load %2201 : !llvm.ptr -> i32
    %2202 = arith.constant 0 : i32
    %2203 = llvm.mlir.constant(1 : i64) : i64
    %2204 = llvm.alloca %2203 x i32 : (i64) -> !llvm.ptr
    llvm.store %2202, %2204 : i32, !llvm.ptr
    %2205 = arith.constant 1 : i32
    %2206 = arith.subi %2197, %2205 : i32
    %2207 = llvm.mlir.constant(1 : i64) : i64
    %2208 = llvm.alloca %2207 x i32 : (i64) -> !llvm.ptr
    llvm.store %2206, %2208 : i32, !llvm.ptr
    cf.br ^bb300
    ^bb300:
    %2209 = llvm.load %2204 : !llvm.ptr -> i32
    %2210 = llvm.load %2208 : !llvm.ptr -> i32
    %2211 = arith.cmpi sle, %2209, %2210 : i32
    cf.cond_br %2211, ^bb301, ^bb302
    ^bb301:
      %2212 = llvm.load %2204 : !llvm.ptr -> i32
      %2213 = llvm.load %2208 : !llvm.ptr -> i32
      %2214 = arith.addi %2212, %2213 : i32
      %2215 = arith.constant 2 : i32
      %2216 = arith.divsi %2214, %2215 : i32
      %2218 = llvm.mlir.addressof @inv_pool : !llvm.ptr
      %2219 = llvm.load %2218 : !llvm.ptr -> !llvm.ptr
      %2220 = arith.addi %2192, %2216 : i32
      %2221 = arith.extsi %2220 : i32 to i64
      %2222 = llvm.getelementptr %2219[%2221] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2217 = llvm.load %2222 : !llvm.ptr -> i32
      %2223 = arith.cmpi eq, %2217, %arg1 : i32
      cf.cond_br %2223, ^bb303, ^bb304
      ^bb303:
        func.return %2216 : i32
      ^bb304:
        cf.br ^bb305
      ^bb305:
      %2224 = arith.cmpi slt, %2217, %arg1 : i32
      cf.cond_br %2224, ^bb306, ^bb307
      ^bb306:
        %2225 = arith.constant 1 : i32
        %2226 = arith.addi %2216, %2225 : i32
        llvm.store %2226, %2204 : i32, !llvm.ptr
        cf.br ^bb308
      ^bb307:
        %2227 = arith.constant 1 : i32
        %2228 = arith.subi %2216, %2227 : i32
        llvm.store %2228, %2208 : i32, !llvm.ptr
        cf.br ^bb308
      ^bb308:
      cf.br ^bb300
    ^bb302:
    %2229 = arith.constant 1 : i32
    %2231 = arith.constant 0 : i32
    %2230 = arith.subi %2231, %2229 : i32
    func.return %2230 : i32
  }
  // Module static: ad_changed
  llvm.mlir.global internal @ad_changed() {addr_space = 0 : i32} : !llvm.ptr {
    %2232 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2232 : !llvm.ptr
  }
  // Module static: ad_changed_n
  llvm.mlir.global internal @ad_changed_n(0 : i32) : i32
  // Module static: ad_seen
  llvm.mlir.global internal @ad_seen() {addr_space = 0 : i32} : !llvm.ptr {
    %2233 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2233 : !llvm.ptr
  }
  func.func @enforce_all_diff(%arg0: !llvm.ptr) -> i32 {
    %2234 = arith.constant 0 : i32
    %2235 = llvm.mlir.constant(1 : i64) : i64
    %2236 = llvm.alloca %2235 x i32 : (i64) -> !llvm.ptr
    llvm.store %2234, %2236 : i32, !llvm.ptr
    %2237 = llvm.mlir.addressof @ad_seen : !llvm.ptr
    %2238 = llvm.load %2237 : !llvm.ptr -> !llvm.ptr
    %2239 = arith.constant 0 : i32
    %2240 = llvm.inttoptr %2239 : i32 to !llvm.ptr
    %2241 = llvm.icmp "eq" %2238, %2240 : !llvm.ptr
    cf.cond_br %2241, ^bb309, ^bb310
    ^bb309:
      %2243 = arith.constant 10 : i32
      %2244 = arith.constant 4 : i32
      %2245 = arith.extsi %2243 : i32 to i64
      %2246 = arith.extsi %2244 : i32 to i64
      %2242 = func.call @calloc(%2245, %2246) : (i64, i64) -> !llvm.ptr
      %2247 = llvm.mlir.addressof @ad_seen : !llvm.ptr
      llvm.store %2242, %2247 : !llvm.ptr, !llvm.ptr
      cf.br ^bb311
    ^bb310:
      cf.br ^bb311
    ^bb311:
    %2248 = arith.constant 0 : i32
    %2249 = llvm.mlir.constant(1 : i64) : i64
    %2250 = llvm.alloca %2249 x i32 : (i64) -> !llvm.ptr
    llvm.store %2248, %2250 : i32, !llvm.ptr
    cf.br ^bb312
    ^bb312:
    %2251 = llvm.load %2250 : !llvm.ptr -> i32
    %2252 = arith.constant 10 : i32
    %2253 = arith.cmpi slt, %2251, %2252 : i32
    cf.cond_br %2253, ^bb313, ^bb314
    ^bb313:
      %2254 = arith.constant 0 : i32
      %2255 = llvm.mlir.addressof @ad_seen : !llvm.ptr
      %2256 = llvm.load %2255 : !llvm.ptr -> !llvm.ptr
      %2257 = llvm.load %2250 : !llvm.ptr -> i32
      %2258 = arith.extsi %2257 : i32 to i64
      %2259 = llvm.getelementptr %2256[%2258] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2254, %2259 : i32, !llvm.ptr
      %2260 = llvm.load %2250 : !llvm.ptr -> i32
      %2261 = arith.constant 1 : i32
      %2262 = arith.addi %2260, %2261 : i32
      llvm.store %2262, %2250 : i32, !llvm.ptr
      cf.br ^bb312
    ^bb314:
    %2263 = arith.constant 0 : i32
    llvm.store %2263, %2250 : i32, !llvm.ptr
    cf.br ^bb315
    ^bb315:
    %2264 = llvm.load %2250 : !llvm.ptr -> i32
    %2265 = arith.constant 10 : i32
    %2266 = arith.cmpi slt, %2264, %2265 : i32
    cf.cond_br %2266, ^bb316, ^bb317
    ^bb316:
      %2269 = llvm.load %2250 : !llvm.ptr -> i32
      %2270 = arith.extsi %2269 : i32 to i64
      %2271 = llvm.getelementptr %arg0[%2270] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2268 = llvm.load %2271 : !llvm.ptr -> i32
      %2267 = func.call @popcount(%2268) : (i32) -> i32
      %2272 = arith.constant 1 : i32
      %2273 = arith.cmpi eq, %2267, %2272 : i32
      cf.cond_br %2273, ^bb318, ^bb319
      ^bb318:
        %2276 = llvm.load %2250 : !llvm.ptr -> i32
        %2277 = arith.extsi %2276 : i32 to i64
        %2278 = llvm.getelementptr %arg0[%2277] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2275 = llvm.load %2278 : !llvm.ptr -> i32
        %2274 = func.call @ctz(%2275) : (i32) -> i32
        %2280 = llvm.mlir.addressof @ad_seen : !llvm.ptr
        %2281 = llvm.load %2280 : !llvm.ptr -> !llvm.ptr
        %2282 = arith.extsi %2274 : i32 to i64
        %2283 = llvm.getelementptr %2281[%2282] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2279 = llvm.load %2283 : !llvm.ptr -> i32
        %2284 = arith.constant 1 : i32
        %2285 = arith.cmpi eq, %2279, %2284 : i32
        cf.cond_br %2285, ^bb321, ^bb322
        ^bb321:
          %2286 = arith.constant 1 : i32
          func.return %2286 : i32
        ^bb322:
          cf.br ^bb323
        ^bb323:
        %2287 = arith.constant 1 : i32
        %2288 = llvm.mlir.addressof @ad_seen : !llvm.ptr
        %2289 = llvm.load %2288 : !llvm.ptr -> !llvm.ptr
        %2290 = arith.extsi %2274 : i32 to i64
        %2291 = llvm.getelementptr %2289[%2290] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %2287, %2291 : i32, !llvm.ptr
        %2292 = llvm.load %2236 : !llvm.ptr -> i32
        %2293 = arith.constant 1 : i32
        %2294 = arith.shli %2293, %2274 : i32
        %2295 = arith.ori %2292, %2294 : i32
        llvm.store %2295, %2236 : i32, !llvm.ptr
        cf.br ^bb320
      ^bb319:
        cf.br ^bb320
      ^bb320:
      %2296 = llvm.load %2250 : !llvm.ptr -> i32
      %2297 = arith.constant 1 : i32
      %2298 = arith.addi %2296, %2297 : i32
      llvm.store %2298, %2250 : i32, !llvm.ptr
      cf.br ^bb315
    ^bb317:
    %2299 = llvm.mlir.addressof @ad_changed : !llvm.ptr
    %2300 = llvm.load %2299 : !llvm.ptr -> !llvm.ptr
    %2301 = arith.constant 0 : i32
    %2302 = llvm.inttoptr %2301 : i32 to !llvm.ptr
    %2303 = llvm.icmp "eq" %2300, %2302 : !llvm.ptr
    cf.cond_br %2303, ^bb324, ^bb325
    ^bb324:
      %2305 = arith.constant 20 : i32
      %2306 = arith.constant 4 : i32
      %2307 = arith.extsi %2305 : i32 to i64
      %2308 = arith.extsi %2306 : i32 to i64
      %2304 = func.call @calloc(%2307, %2308) : (i64, i64) -> !llvm.ptr
      %2309 = llvm.mlir.addressof @ad_changed : !llvm.ptr
      llvm.store %2304, %2309 : !llvm.ptr, !llvm.ptr
      cf.br ^bb326
    ^bb325:
      cf.br ^bb326
    ^bb326:
    %2310 = arith.constant 0 : i32
    %2311 = llvm.mlir.addressof @ad_changed_n : !llvm.ptr
    llvm.store %2310, %2311 : i32, !llvm.ptr
    %2312 = arith.constant 0 : i32
    llvm.store %2312, %2250 : i32, !llvm.ptr
    cf.br ^bb327
    ^bb327:
    %2313 = llvm.load %2250 : !llvm.ptr -> i32
    %2314 = arith.constant 10 : i32
    %2315 = arith.cmpi slt, %2313, %2314 : i32
    cf.cond_br %2315, ^bb328, ^bb329
    ^bb328:
      %2318 = llvm.load %2250 : !llvm.ptr -> i32
      %2319 = arith.extsi %2318 : i32 to i64
      %2320 = llvm.getelementptr %arg0[%2319] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2317 = llvm.load %2320 : !llvm.ptr -> i32
      %2316 = func.call @popcount(%2317) : (i32) -> i32
      %2321 = arith.constant 1 : i32
      %2322 = arith.cmpi sgt, %2316, %2321 : i32
      cf.cond_br %2322, ^bb330, ^bb331
      ^bb330:
        %2324 = llvm.load %2250 : !llvm.ptr -> i32
        %2325 = arith.extsi %2324 : i32 to i64
        %2326 = llvm.getelementptr %arg0[%2325] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2323 = llvm.load %2326 : !llvm.ptr -> i32
        %2327 = arith.constant 0 : i32
        %2328 = arith.constant 1 : i32
        %2329 = arith.subi %2327, %2328 : i32
        %2330 = llvm.load %2236 : !llvm.ptr -> i32
        %2331 = arith.subi %2329, %2330 : i32
        %2332 = arith.andi %2323, %2331 : i32
        %2333 = arith.constant 0 : i32
        %2334 = arith.cmpi eq, %2332, %2333 : i32
        cf.cond_br %2334, ^bb333, ^bb334
        ^bb333:
          %2335 = arith.constant 1 : i32
          func.return %2335 : i32
        ^bb334:
          cf.br ^bb335
        ^bb335:
        %2337 = llvm.load %2250 : !llvm.ptr -> i32
        %2338 = arith.extsi %2337 : i32 to i64
        %2339 = llvm.getelementptr %arg0[%2338] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2336 = llvm.load %2339 : !llvm.ptr -> i32
        %2340 = arith.cmpi ne, %2332, %2336 : i32
        cf.cond_br %2340, ^bb336, ^bb337
        ^bb336:
          %2341 = llvm.load %2250 : !llvm.ptr -> i32
          %2342 = arith.extsi %2341 : i32 to i64
          %2343 = llvm.getelementptr %arg0[%2342] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %2332, %2343 : i32, !llvm.ptr
          %2344 = llvm.load %2250 : !llvm.ptr -> i32
          %2345 = llvm.mlir.addressof @ad_changed : !llvm.ptr
          %2346 = llvm.load %2345 : !llvm.ptr -> !llvm.ptr
          %2347 = llvm.mlir.addressof @ad_changed_n : !llvm.ptr
          %2348 = llvm.load %2347 : !llvm.ptr -> i32
          %2349 = arith.extsi %2348 : i32 to i64
          %2350 = llvm.getelementptr %2346[%2349] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %2344, %2350 : i32, !llvm.ptr
          %2351 = llvm.mlir.addressof @ad_changed_n : !llvm.ptr
          %2352 = llvm.load %2351 : !llvm.ptr -> i32
          %2353 = arith.constant 1 : i32
          %2354 = arith.addi %2352, %2353 : i32
          %2355 = llvm.mlir.addressof @ad_changed_n : !llvm.ptr
          llvm.store %2354, %2355 : i32, !llvm.ptr
          cf.br ^bb338
        ^bb337:
          cf.br ^bb338
        ^bb338:
        cf.br ^bb332
      ^bb331:
        cf.br ^bb332
      ^bb332:
      %2356 = llvm.load %2250 : !llvm.ptr -> i32
      %2357 = arith.constant 1 : i32
      %2358 = arith.addi %2356, %2357 : i32
      llvm.store %2358, %2250 : i32, !llvm.ptr
      cf.br ^bb327
    ^bb329:
    %2359 = arith.constant 0 : i32
    func.return %2359 : i32
  }
  // Module static: pr_changed
  llvm.mlir.global internal @pr_changed() {addr_space = 0 : i32} : !llvm.ptr {
    %2360 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2360 : !llvm.ptr
  }
  // Module static: pr_changed_n
  llvm.mlir.global internal @pr_changed_n(0 : i32) : i32
  // Module static: pr_support
  llvm.mlir.global internal @pr_support() {addr_space = 0 : i32} : !llvm.ptr {
    %2361 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2361 : !llvm.ptr
  }
  func.func @process_run(%arg0: i32, %arg1: !llvm.ptr) -> i32 {
    %2363 = llvm.mlir.addressof @run_dup : !llvm.ptr
    %2364 = llvm.load %2363 : !llvm.ptr -> !llvm.ptr
    %2365 = arith.extsi %arg0 : i32 to i64
    %2366 = llvm.getelementptr %2364[%2365] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2362 = llvm.load %2366 : !llvm.ptr -> i32
    %2367 = arith.constant 1 : i32
    %2368 = arith.cmpi eq, %2362, %2367 : i32
    cf.cond_br %2368, ^bb339, ^bb340
    ^bb339:
      %2369 = arith.constant 1 : i32
      func.return %2369 : i32
    ^bb340:
      cf.br ^bb341
    ^bb341:
    %2371 = llvm.mlir.addressof @run_inv_count : !llvm.ptr
    %2372 = llvm.load %2371 : !llvm.ptr -> !llvm.ptr
    %2373 = arith.extsi %arg0 : i32 to i64
    %2374 = llvm.getelementptr %2372[%2373] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2370 = llvm.load %2374 : !llvm.ptr -> i32
    %2375 = llvm.mlir.addressof @pr_support : !llvm.ptr
    %2376 = llvm.load %2375 : !llvm.ptr -> !llvm.ptr
    %2377 = arith.constant 0 : i32
    %2378 = llvm.inttoptr %2377 : i32 to !llvm.ptr
    %2379 = llvm.icmp "eq" %2376, %2378 : !llvm.ptr
    cf.cond_br %2379, ^bb342, ^bb343
    ^bb342:
      %2381 = arith.constant 40 : i32
      %2382 = arith.constant 4 : i32
      %2383 = arith.extsi %2381 : i32 to i64
      %2384 = arith.extsi %2382 : i32 to i64
      %2380 = func.call @calloc(%2383, %2384) : (i64, i64) -> !llvm.ptr
      %2385 = llvm.mlir.addressof @pr_support : !llvm.ptr
      llvm.store %2380, %2385 : !llvm.ptr, !llvm.ptr
      cf.br ^bb344
    ^bb343:
      cf.br ^bb344
    ^bb344:
    %2386 = llvm.mlir.addressof @pr_changed : !llvm.ptr
    %2387 = llvm.load %2386 : !llvm.ptr -> !llvm.ptr
    %2388 = arith.constant 0 : i32
    %2389 = llvm.inttoptr %2388 : i32 to !llvm.ptr
    %2390 = llvm.icmp "eq" %2387, %2389 : !llvm.ptr
    cf.cond_br %2390, ^bb345, ^bb346
    ^bb345:
      %2392 = arith.constant 40 : i32
      %2393 = arith.constant 4 : i32
      %2394 = arith.extsi %2392 : i32 to i64
      %2395 = arith.extsi %2393 : i32 to i64
      %2391 = func.call @calloc(%2394, %2395) : (i64, i64) -> !llvm.ptr
      %2396 = llvm.mlir.addressof @pr_changed : !llvm.ptr
      llvm.store %2391, %2396 : !llvm.ptr, !llvm.ptr
      cf.br ^bb347
    ^bb346:
      cf.br ^bb347
    ^bb347:
    %2397 = arith.constant 0 : i32
    %2398 = llvm.mlir.constant(1 : i64) : i64
    %2399 = llvm.alloca %2398 x i32 : (i64) -> !llvm.ptr
    llvm.store %2397, %2399 : i32, !llvm.ptr
    cf.br ^bb348
    ^bb348:
    %2400 = llvm.load %2399 : !llvm.ptr -> i32
    %2401 = arith.cmpi slt, %2400, %2370 : i32
    cf.cond_br %2401, ^bb349, ^bb350
    ^bb349:
      %2402 = arith.constant 0 : i32
      %2403 = llvm.mlir.addressof @pr_support : !llvm.ptr
      %2404 = llvm.load %2403 : !llvm.ptr -> !llvm.ptr
      %2405 = llvm.load %2399 : !llvm.ptr -> i32
      %2406 = arith.extsi %2405 : i32 to i64
      %2407 = llvm.getelementptr %2404[%2406] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %2402, %2407 : i32, !llvm.ptr
      %2408 = llvm.load %2399 : !llvm.ptr -> i32
      %2409 = arith.constant 1 : i32
      %2410 = arith.addi %2408, %2409 : i32
      llvm.store %2410, %2399 : i32, !llvm.ptr
      cf.br ^bb348
    ^bb350:
    %2412 = llvm.mlir.addressof @run_length : !llvm.ptr
    %2413 = llvm.load %2412 : !llvm.ptr -> !llvm.ptr
    %2414 = arith.extsi %arg0 : i32 to i64
    %2415 = llvm.getelementptr %2413[%2414] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2411 = llvm.load %2415 : !llvm.ptr -> i32
    %2417 = llvm.mlir.addressof @run_cv_off : !llvm.ptr
    %2418 = llvm.load %2417 : !llvm.ptr -> !llvm.ptr
    %2419 = arith.extsi %arg0 : i32 to i64
    %2420 = llvm.getelementptr %2418[%2419] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2416 = llvm.load %2420 : !llvm.ptr -> i32
    %2422 = llvm.mlir.addressof @run_sums_off : !llvm.ptr
    %2423 = llvm.load %2422 : !llvm.ptr -> !llvm.ptr
    %2424 = arith.extsi %arg0 : i32 to i64
    %2425 = llvm.getelementptr %2423[%2424] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2421 = llvm.load %2425 : !llvm.ptr -> i32
    %2427 = llvm.mlir.addressof @run_sums_count : !llvm.ptr
    %2428 = llvm.load %2427 : !llvm.ptr -> !llvm.ptr
    %2429 = arith.extsi %arg0 : i32 to i64
    %2430 = llvm.getelementptr %2428[%2429] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2426 = llvm.load %2430 : !llvm.ptr -> i32
    %2432 = llvm.mlir.addressof @run_nsl : !llvm.ptr
    %2433 = llvm.load %2432 : !llvm.ptr -> !llvm.ptr
    %2434 = arith.extsi %arg0 : i32 to i64
    %2435 = llvm.getelementptr %2433[%2434] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %2431 = llvm.load %2435 : !llvm.ptr -> i32
    %2436 = arith.constant 1 : i32
    %2437 = arith.cmpi eq, %2431, %2436 : i32
    cf.cond_br %2437, ^bb351, ^bb352
    ^bb351:
      %2439 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
      %2440 = llvm.load %2439 : !llvm.ptr -> !llvm.ptr
      %2441 = arith.extsi %arg0 : i32 to i64
      %2442 = llvm.getelementptr %2440[%2441] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2438 = llvm.load %2442 : !llvm.ptr -> i32
      %2443 = func.call @inv_index_lookup(%arg0, %2438) : (i32, i32) -> i32
      %2445 = arith.extsi %2438 : i32 to i64
      %2446 = llvm.getelementptr %arg1[%2445] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2444 = llvm.load %2446 : !llvm.ptr -> i32
      %2447 = arith.constant 0 : i32
      %2448 = llvm.mlir.constant(1 : i64) : i64
      %2449 = llvm.alloca %2448 x i32 : (i64) -> !llvm.ptr
      llvm.store %2447, %2449 : i32, !llvm.ptr
      cf.br ^bb354
      ^bb354:
      %2450 = llvm.load %2449 : !llvm.ptr -> i32
      %2451 = arith.cmpi slt, %2450, %2426 : i32
      cf.cond_br %2451, ^bb355, ^bb356
      ^bb355:
        %2453 = llvm.mlir.addressof @sums_pool : !llvm.ptr
        %2454 = llvm.load %2453 : !llvm.ptr -> !llvm.ptr
        %2455 = llvm.load %2449 : !llvm.ptr -> i32
        %2456 = arith.addi %2421, %2455 : i32
        %2457 = arith.extsi %2456 : i32 to i64
        %2458 = llvm.getelementptr %2454[%2457] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2452 = llvm.load %2458 : !llvm.ptr -> i32
        %2459 = arith.constant 9 : i32
        %2460 = arith.cmpi sle, %2452, %2459 : i32
        cf.cond_br %2460, ^bb357, ^bb358
        ^bb357:
          %2461 = arith.constant 1 : i32
          %2462 = arith.shli %2461, %2452 : i32
          %2463 = arith.andi %2444, %2462 : i32
          %2464 = arith.constant 0 : i32
          %2465 = arith.cmpi ne, %2463, %2464 : i32
          cf.cond_br %2465, ^bb360, ^bb361
          ^bb360:
            %2466 = arith.constant 46 : i32
            %2467 = arith.muli %2411, %2466 : i32
            %2468 = arith.addi %2467, %2452 : i32
            %2469 = arith.constant 0 : i32
            %2470 = llvm.mlir.constant(1 : i64) : i64
            %2471 = llvm.alloca %2470 x i32 : (i64) -> !llvm.ptr
            llvm.store %2469, %2471 : i32, !llvm.ptr
            cf.br ^bb363
            ^bb363:
            %2472 = llvm.load %2471 : !llvm.ptr -> i32
            %2474 = llvm.mlir.addressof @perms_count : !llvm.ptr
            %2475 = llvm.load %2474 : !llvm.ptr -> !llvm.ptr
            %2476 = arith.extsi %2468 : i32 to i64
            %2477 = llvm.getelementptr %2475[%2476] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            %2473 = llvm.load %2477 : !llvm.ptr -> i32
            %2478 = arith.cmpi slt, %2472, %2473 : i32
            cf.cond_br %2478, ^bb364, ^bb365
            ^bb364:
              %2480 = llvm.load %2471 : !llvm.ptr -> i32
              func.call @get_perm(%2411, %2452, %2480) : (i32, i32, i32) -> ()
              %2481 = arith.constant 1 : i32
              %2482 = llvm.mlir.constant(1 : i64) : i64
              %2483 = llvm.alloca %2482 x i32 : (i64) -> !llvm.ptr
              llvm.store %2481, %2483 : i32, !llvm.ptr
              %2484 = arith.constant 0 : i32
              %2485 = llvm.mlir.constant(1 : i64) : i64
              %2486 = llvm.alloca %2485 x i32 : (i64) -> !llvm.ptr
              llvm.store %2484, %2486 : i32, !llvm.ptr
              cf.br ^bb366
              ^bb366:
              %2487 = llvm.load %2486 : !llvm.ptr -> i32
              %2488 = arith.cmpi slt, %2487, %2411 : i32
              cf.cond_br %2488, ^bb367, ^bb368
              ^bb367:
                %2490 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                %2491 = llvm.load %2490 : !llvm.ptr -> !llvm.ptr
                %2492 = llvm.load %2486 : !llvm.ptr -> i32
                %2493 = arith.addi %2416, %2492 : i32
                %2494 = arith.extsi %2493 : i32 to i64
                %2495 = llvm.getelementptr %2491[%2494] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2489 = llvm.load %2495 : !llvm.ptr -> i32
                %2497 = arith.extsi %2489 : i32 to i64
                %2498 = llvm.getelementptr %arg1[%2497] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2496 = llvm.load %2498 : !llvm.ptr -> i32
                %2499 = arith.constant 1 : i32
                %2501 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                %2502 = llvm.load %2501 : !llvm.ptr -> !llvm.ptr
                %2503 = llvm.load %2486 : !llvm.ptr -> i32
                %2504 = arith.extsi %2503 : i32 to i64
                %2505 = llvm.getelementptr %2502[%2504] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2500 = llvm.load %2505 : !llvm.ptr -> i32
                %2506 = arith.shli %2499, %2500 : i32
                %2507 = arith.andi %2496, %2506 : i32
                %2508 = arith.constant 0 : i32
                %2509 = arith.cmpi eq, %2507, %2508 : i32
                cf.cond_br %2509, ^bb369, ^bb370
                ^bb369:
                  %2510 = arith.constant 0 : i32
                  llvm.store %2510, %2483 : i32, !llvm.ptr
                  cf.br ^bb368
                ^bb370:
                  cf.br ^bb371
                ^bb371:
                %2511 = llvm.load %2486 : !llvm.ptr -> i32
                %2512 = arith.constant 1 : i32
                %2513 = arith.addi %2511, %2512 : i32
                llvm.store %2513, %2486 : i32, !llvm.ptr
                cf.br ^bb366
              ^bb368:
              %2514 = llvm.load %2483 : !llvm.ptr -> i32
              %2515 = arith.constant 1 : i32
              %2516 = arith.cmpi eq, %2514, %2515 : i32
              cf.cond_br %2516, ^bb372, ^bb373
              ^bb372:
                %2517 = arith.constant 0 : i32
                %2518 = llvm.mlir.constant(1 : i64) : i64
                %2519 = llvm.alloca %2518 x i32 : (i64) -> !llvm.ptr
                llvm.store %2517, %2519 : i32, !llvm.ptr
                cf.br ^bb375
                ^bb375:
                %2520 = llvm.load %2519 : !llvm.ptr -> i32
                %2521 = arith.cmpi slt, %2520, %2411 : i32
                cf.cond_br %2521, ^bb376, ^bb377
                ^bb376:
                  %2523 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                  %2524 = llvm.load %2523 : !llvm.ptr -> !llvm.ptr
                  %2525 = llvm.load %2519 : !llvm.ptr -> i32
                  %2526 = arith.addi %2416, %2525 : i32
                  %2527 = arith.extsi %2526 : i32 to i64
                  %2528 = llvm.getelementptr %2524[%2527] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                  %2522 = llvm.load %2528 : !llvm.ptr -> i32
                  %2529 = func.call @inv_index_lookup(%arg0, %2522) : (i32, i32) -> i32
                  %2531 = llvm.mlir.addressof @pr_support : !llvm.ptr
                  %2532 = llvm.load %2531 : !llvm.ptr -> !llvm.ptr
                  %2533 = arith.extsi %2529 : i32 to i64
                  %2534 = llvm.getelementptr %2532[%2533] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                  %2530 = llvm.load %2534 : !llvm.ptr -> i32
                  %2535 = arith.constant 1 : i32
                  %2537 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                  %2538 = llvm.load %2537 : !llvm.ptr -> !llvm.ptr
                  %2539 = llvm.load %2519 : !llvm.ptr -> i32
                  %2540 = arith.extsi %2539 : i32 to i64
                  %2541 = llvm.getelementptr %2538[%2540] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                  %2536 = llvm.load %2541 : !llvm.ptr -> i32
                  %2542 = arith.shli %2535, %2536 : i32
                  %2543 = arith.ori %2530, %2542 : i32
                  %2544 = llvm.mlir.addressof @pr_support : !llvm.ptr
                  %2545 = llvm.load %2544 : !llvm.ptr -> !llvm.ptr
                  %2546 = arith.extsi %2529 : i32 to i64
                  %2547 = llvm.getelementptr %2545[%2546] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                  llvm.store %2543, %2547 : i32, !llvm.ptr
                  %2548 = llvm.load %2519 : !llvm.ptr -> i32
                  %2549 = arith.constant 1 : i32
                  %2550 = arith.addi %2548, %2549 : i32
                  llvm.store %2550, %2519 : i32, !llvm.ptr
                  cf.br ^bb375
                ^bb377:
                %2552 = llvm.mlir.addressof @pr_support : !llvm.ptr
                %2553 = llvm.load %2552 : !llvm.ptr -> !llvm.ptr
                %2554 = arith.extsi %2443 : i32 to i64
                %2555 = llvm.getelementptr %2553[%2554] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2551 = llvm.load %2555 : !llvm.ptr -> i32
                %2556 = arith.constant 1 : i32
                %2557 = arith.shli %2556, %2452 : i32
                %2558 = arith.ori %2551, %2557 : i32
                %2559 = llvm.mlir.addressof @pr_support : !llvm.ptr
                %2560 = llvm.load %2559 : !llvm.ptr -> !llvm.ptr
                %2561 = arith.extsi %2443 : i32 to i64
                %2562 = llvm.getelementptr %2560[%2561] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                llvm.store %2558, %2562 : i32, !llvm.ptr
                cf.br ^bb374
              ^bb373:
                cf.br ^bb374
              ^bb374:
              %2563 = llvm.load %2471 : !llvm.ptr -> i32
              %2564 = arith.constant 1 : i32
              %2565 = arith.addi %2563, %2564 : i32
              llvm.store %2565, %2471 : i32, !llvm.ptr
              cf.br ^bb363
            ^bb365:
            cf.br ^bb362
          ^bb361:
            cf.br ^bb362
          ^bb362:
          cf.br ^bb359
        ^bb358:
          cf.br ^bb359
        ^bb359:
        %2566 = llvm.load %2449 : !llvm.ptr -> i32
        %2567 = arith.constant 1 : i32
        %2568 = arith.addi %2566, %2567 : i32
        llvm.store %2568, %2449 : i32, !llvm.ptr
        cf.br ^bb354
      ^bb356:
      cf.br ^bb353
    ^bb352:
      %2570 = llvm.mlir.addressof @run_sl0 : !llvm.ptr
      %2571 = llvm.load %2570 : !llvm.ptr -> !llvm.ptr
      %2572 = arith.extsi %arg0 : i32 to i64
      %2573 = llvm.getelementptr %2571[%2572] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2569 = llvm.load %2573 : !llvm.ptr -> i32
      %2575 = llvm.mlir.addressof @run_sl1 : !llvm.ptr
      %2576 = llvm.load %2575 : !llvm.ptr -> !llvm.ptr
      %2577 = arith.extsi %arg0 : i32 to i64
      %2578 = llvm.getelementptr %2576[%2577] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2574 = llvm.load %2578 : !llvm.ptr -> i32
      %2579 = func.call @inv_index_lookup(%arg0, %2569) : (i32, i32) -> i32
      %2580 = func.call @inv_index_lookup(%arg0, %2574) : (i32, i32) -> i32
      %2582 = llvm.mlir.addressof @run_ssame : !llvm.ptr
      %2583 = llvm.load %2582 : !llvm.ptr -> !llvm.ptr
      %2584 = arith.extsi %arg0 : i32 to i64
      %2585 = llvm.getelementptr %2583[%2584] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2581 = llvm.load %2585 : !llvm.ptr -> i32
      %2586 = arith.constant 1 : i32
      %2587 = arith.cmpi eq, %2581, %2586 : i32
      cf.cond_br %2587, ^bb378, ^bb379
      ^bb378:
        %2589 = arith.extsi %2569 : i32 to i64
        %2590 = llvm.getelementptr %arg1[%2589] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2588 = llvm.load %2590 : !llvm.ptr -> i32
        %2591 = arith.constant 0 : i32
        %2592 = llvm.mlir.constant(1 : i64) : i64
        %2593 = llvm.alloca %2592 x i32 : (i64) -> !llvm.ptr
        llvm.store %2591, %2593 : i32, !llvm.ptr
        cf.br ^bb381
        ^bb381:
        %2594 = llvm.load %2593 : !llvm.ptr -> i32
        %2595 = arith.cmpi slt, %2594, %2426 : i32
        cf.cond_br %2595, ^bb382, ^bb383
        ^bb382:
          %2597 = llvm.mlir.addressof @sums_pool : !llvm.ptr
          %2598 = llvm.load %2597 : !llvm.ptr -> !llvm.ptr
          %2599 = llvm.load %2593 : !llvm.ptr -> i32
          %2600 = arith.addi %2421, %2599 : i32
          %2601 = arith.extsi %2600 : i32 to i64
          %2602 = llvm.getelementptr %2598[%2601] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %2596 = llvm.load %2602 : !llvm.ptr -> i32
          %2603 = arith.constant 10 : i32
          %2604 = arith.cmpi sge, %2596, %2603 : i32
          cf.cond_br %2604, ^bb384, ^bb385
          ^bb384:
            %2605 = arith.constant 10 : i32
            %2606 = arith.divsi %2596, %2605 : i32
            %2607 = arith.constant 10 : i32
            %2608 = arith.remsi %2596, %2607 : i32
            %2609 = arith.cmpi eq, %2606, %2608 : i32
            cf.cond_br %2609, ^bb387, ^bb388
            ^bb387:
              %2610 = arith.constant 1 : i32
              %2611 = arith.shli %2610, %2606 : i32
              %2612 = arith.andi %2588, %2611 : i32
              %2613 = arith.constant 0 : i32
              %2614 = arith.cmpi ne, %2612, %2613 : i32
              cf.cond_br %2614, ^bb390, ^bb391
              ^bb390:
                %2615 = arith.constant 46 : i32
                %2616 = arith.muli %2411, %2615 : i32
                %2617 = arith.addi %2616, %2596 : i32
                %2618 = arith.constant 0 : i32
                %2619 = llvm.mlir.constant(1 : i64) : i64
                %2620 = llvm.alloca %2619 x i32 : (i64) -> !llvm.ptr
                llvm.store %2618, %2620 : i32, !llvm.ptr
                cf.br ^bb393
                ^bb393:
                %2621 = llvm.load %2620 : !llvm.ptr -> i32
                %2623 = llvm.mlir.addressof @perms_count : !llvm.ptr
                %2624 = llvm.load %2623 : !llvm.ptr -> !llvm.ptr
                %2625 = arith.extsi %2617 : i32 to i64
                %2626 = llvm.getelementptr %2624[%2625] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2622 = llvm.load %2626 : !llvm.ptr -> i32
                %2627 = arith.cmpi slt, %2621, %2622 : i32
                cf.cond_br %2627, ^bb394, ^bb395
                ^bb394:
                  %2629 = llvm.load %2620 : !llvm.ptr -> i32
                  func.call @get_perm(%2411, %2596, %2629) : (i32, i32, i32) -> ()
                  %2630 = arith.constant 0 : i32
                  %2631 = arith.cmpi eq, %arg0, %2630 : i32
                  %2632 = scf.if %2631 -> (i1) {
                    %2633 = arith.constant 22 : i32
                    %2634 = arith.cmpi eq, %2596, %2633 : i32
                    scf.yield %2634 : i1
                  } else {
                    %2635 = arith.constant false
                    scf.yield %2635 : i1
                  }
                  %2636 = scf.if %2632 -> (i1) {
                    %2637 = llvm.load %2620 : !llvm.ptr -> i32
                    %2638 = arith.constant 3 : i32
                    %2639 = arith.cmpi slt, %2637, %2638 : i32
                    scf.yield %2639 : i1
                  } else {
                    %2640 = arith.constant false
                    scf.yield %2640 : i1
                  }
                  cf.cond_br %2636, ^bb396, ^bb397
                  ^bb396:
                    %2641 = llvm.mlir.addressof @str_0 : !llvm.ptr
                    %2642 = llvm.load %2620 : !llvm.ptr -> i32
                    %2644 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2645 = llvm.load %2644 : !llvm.ptr -> !llvm.ptr
                    %2646 = arith.constant 0 : i32
                    %2647 = arith.extsi %2646 : i32 to i64
                    %2648 = llvm.getelementptr %2645[%2647] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2643 = llvm.load %2648 : !llvm.ptr -> i32
                    %2650 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2651 = llvm.load %2650 : !llvm.ptr -> !llvm.ptr
                    %2652 = arith.constant 1 : i32
                    %2653 = arith.extsi %2652 : i32 to i64
                    %2654 = llvm.getelementptr %2651[%2653] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2649 = llvm.load %2654 : !llvm.ptr -> i32
                    %2656 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2657 = llvm.load %2656 : !llvm.ptr -> !llvm.ptr
                    %2658 = arith.constant 2 : i32
                    %2659 = arith.extsi %2658 : i32 to i64
                    %2660 = llvm.getelementptr %2657[%2659] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2655 = llvm.load %2660 : !llvm.ptr -> i32
                    %2662 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2663 = llvm.load %2662 : !llvm.ptr -> !llvm.ptr
                    %2664 = arith.constant 3 : i32
                    %2665 = arith.extsi %2664 : i32 to i64
                    %2666 = llvm.getelementptr %2663[%2665] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2661 = llvm.load %2666 : !llvm.ptr -> i32
                    %2667 = llvm.call @printf(%2641, %2642, %2643, %2649, %2655, %2661) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32, i32, i32, i32, i32) -> i32
                    cf.br ^bb398
                  ^bb397:
                    cf.br ^bb398
                  ^bb398:
                  %2668 = arith.constant 1 : i32
                  %2669 = llvm.mlir.constant(1 : i64) : i64
                  %2670 = llvm.alloca %2669 x i32 : (i64) -> !llvm.ptr
                  llvm.store %2668, %2670 : i32, !llvm.ptr
                  %2671 = arith.constant 0 : i32
                  %2672 = llvm.mlir.constant(1 : i64) : i64
                  %2673 = llvm.alloca %2672 x i32 : (i64) -> !llvm.ptr
                  llvm.store %2671, %2673 : i32, !llvm.ptr
                  cf.br ^bb399
                  ^bb399:
                  %2674 = llvm.load %2673 : !llvm.ptr -> i32
                  %2675 = arith.cmpi slt, %2674, %2411 : i32
                  cf.cond_br %2675, ^bb400, ^bb401
                  ^bb400:
                    %2677 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                    %2678 = llvm.load %2677 : !llvm.ptr -> !llvm.ptr
                    %2679 = llvm.load %2673 : !llvm.ptr -> i32
                    %2680 = arith.addi %2416, %2679 : i32
                    %2681 = arith.extsi %2680 : i32 to i64
                    %2682 = llvm.getelementptr %2678[%2681] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2676 = llvm.load %2682 : !llvm.ptr -> i32
                    %2684 = arith.extsi %2676 : i32 to i64
                    %2685 = llvm.getelementptr %arg1[%2684] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2683 = llvm.load %2685 : !llvm.ptr -> i32
                    %2686 = arith.constant 1 : i32
                    %2688 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2689 = llvm.load %2688 : !llvm.ptr -> !llvm.ptr
                    %2690 = llvm.load %2673 : !llvm.ptr -> i32
                    %2691 = arith.extsi %2690 : i32 to i64
                    %2692 = llvm.getelementptr %2689[%2691] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2687 = llvm.load %2692 : !llvm.ptr -> i32
                    %2693 = arith.shli %2686, %2687 : i32
                    %2694 = arith.andi %2683, %2693 : i32
                    %2695 = arith.constant 0 : i32
                    %2696 = arith.cmpi eq, %2694, %2695 : i32
                    cf.cond_br %2696, ^bb402, ^bb403
                    ^bb402:
                      %2697 = arith.constant 0 : i32
                      llvm.store %2697, %2670 : i32, !llvm.ptr
                      cf.br ^bb401
                    ^bb403:
                      cf.br ^bb404
                    ^bb404:
                    %2698 = llvm.load %2673 : !llvm.ptr -> i32
                    %2699 = arith.constant 1 : i32
                    %2700 = arith.addi %2698, %2699 : i32
                    llvm.store %2700, %2673 : i32, !llvm.ptr
                    cf.br ^bb399
                  ^bb401:
                  %2701 = llvm.load %2670 : !llvm.ptr -> i32
                  %2702 = arith.constant 1 : i32
                  %2703 = arith.cmpi eq, %2701, %2702 : i32
                  cf.cond_br %2703, ^bb405, ^bb406
                  ^bb405:
                    %2704 = arith.constant 0 : i32
                    %2705 = llvm.mlir.constant(1 : i64) : i64
                    %2706 = llvm.alloca %2705 x i32 : (i64) -> !llvm.ptr
                    llvm.store %2704, %2706 : i32, !llvm.ptr
                    cf.br ^bb408
                    ^bb408:
                    %2707 = llvm.load %2706 : !llvm.ptr -> i32
                    %2708 = arith.cmpi slt, %2707, %2411 : i32
                    cf.cond_br %2708, ^bb409, ^bb410
                    ^bb409:
                      %2710 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                      %2711 = llvm.load %2710 : !llvm.ptr -> !llvm.ptr
                      %2712 = llvm.load %2706 : !llvm.ptr -> i32
                      %2713 = arith.addi %2416, %2712 : i32
                      %2714 = arith.extsi %2713 : i32 to i64
                      %2715 = llvm.getelementptr %2711[%2714] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2709 = llvm.load %2715 : !llvm.ptr -> i32
                      %2716 = func.call @inv_index_lookup(%arg0, %2709) : (i32, i32) -> i32
                      %2718 = llvm.mlir.addressof @pr_support : !llvm.ptr
                      %2719 = llvm.load %2718 : !llvm.ptr -> !llvm.ptr
                      %2720 = arith.extsi %2716 : i32 to i64
                      %2721 = llvm.getelementptr %2719[%2720] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2717 = llvm.load %2721 : !llvm.ptr -> i32
                      %2722 = arith.constant 1 : i32
                      %2724 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                      %2725 = llvm.load %2724 : !llvm.ptr -> !llvm.ptr
                      %2726 = llvm.load %2706 : !llvm.ptr -> i32
                      %2727 = arith.extsi %2726 : i32 to i64
                      %2728 = llvm.getelementptr %2725[%2727] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2723 = llvm.load %2728 : !llvm.ptr -> i32
                      %2729 = arith.shli %2722, %2723 : i32
                      %2730 = arith.ori %2717, %2729 : i32
                      %2731 = llvm.mlir.addressof @pr_support : !llvm.ptr
                      %2732 = llvm.load %2731 : !llvm.ptr -> !llvm.ptr
                      %2733 = arith.extsi %2716 : i32 to i64
                      %2734 = llvm.getelementptr %2732[%2733] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      llvm.store %2730, %2734 : i32, !llvm.ptr
                      %2735 = llvm.load %2706 : !llvm.ptr -> i32
                      %2736 = arith.constant 1 : i32
                      %2737 = arith.addi %2735, %2736 : i32
                      llvm.store %2737, %2706 : i32, !llvm.ptr
                      cf.br ^bb408
                    ^bb410:
                    %2739 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2740 = llvm.load %2739 : !llvm.ptr -> !llvm.ptr
                    %2741 = arith.extsi %2579 : i32 to i64
                    %2742 = llvm.getelementptr %2740[%2741] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2738 = llvm.load %2742 : !llvm.ptr -> i32
                    %2743 = arith.constant 1 : i32
                    %2744 = arith.shli %2743, %2606 : i32
                    %2745 = arith.ori %2738, %2744 : i32
                    %2746 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2747 = llvm.load %2746 : !llvm.ptr -> !llvm.ptr
                    %2748 = arith.extsi %2579 : i32 to i64
                    %2749 = llvm.getelementptr %2747[%2748] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    llvm.store %2745, %2749 : i32, !llvm.ptr
                    cf.br ^bb407
                  ^bb406:
                    cf.br ^bb407
                  ^bb407:
                  %2750 = llvm.load %2620 : !llvm.ptr -> i32
                  %2751 = arith.constant 1 : i32
                  %2752 = arith.addi %2750, %2751 : i32
                  llvm.store %2752, %2620 : i32, !llvm.ptr
                  cf.br ^bb393
                ^bb395:
                cf.br ^bb392
              ^bb391:
                cf.br ^bb392
              ^bb392:
              cf.br ^bb389
            ^bb388:
              cf.br ^bb389
            ^bb389:
            cf.br ^bb386
          ^bb385:
            cf.br ^bb386
          ^bb386:
          %2753 = llvm.load %2593 : !llvm.ptr -> i32
          %2754 = arith.constant 1 : i32
          %2755 = arith.addi %2753, %2754 : i32
          llvm.store %2755, %2593 : i32, !llvm.ptr
          cf.br ^bb381
        ^bb383:
        cf.br ^bb380
      ^bb379:
        %2757 = arith.extsi %2569 : i32 to i64
        %2758 = llvm.getelementptr %arg1[%2757] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2756 = llvm.load %2758 : !llvm.ptr -> i32
        %2760 = arith.extsi %2574 : i32 to i64
        %2761 = llvm.getelementptr %arg1[%2760] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %2759 = llvm.load %2761 : !llvm.ptr -> i32
        %2762 = arith.constant 0 : i32
        %2763 = llvm.mlir.constant(1 : i64) : i64
        %2764 = llvm.alloca %2763 x i32 : (i64) -> !llvm.ptr
        llvm.store %2762, %2764 : i32, !llvm.ptr
        cf.br ^bb411
        ^bb411:
        %2765 = llvm.load %2764 : !llvm.ptr -> i32
        %2766 = arith.cmpi slt, %2765, %2426 : i32
        cf.cond_br %2766, ^bb412, ^bb413
        ^bb412:
          %2768 = llvm.mlir.addressof @sums_pool : !llvm.ptr
          %2769 = llvm.load %2768 : !llvm.ptr -> !llvm.ptr
          %2770 = llvm.load %2764 : !llvm.ptr -> i32
          %2771 = arith.addi %2421, %2770 : i32
          %2772 = arith.extsi %2771 : i32 to i64
          %2773 = llvm.getelementptr %2769[%2772] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %2767 = llvm.load %2773 : !llvm.ptr -> i32
          %2774 = arith.constant 10 : i32
          %2775 = arith.cmpi sge, %2767, %2774 : i32
          cf.cond_br %2775, ^bb414, ^bb415
          ^bb414:
            %2776 = arith.constant 10 : i32
            %2777 = arith.divsi %2767, %2776 : i32
            %2778 = arith.constant 10 : i32
            %2779 = arith.remsi %2767, %2778 : i32
            %2780 = arith.cmpi ne, %2777, %2779 : i32
            cf.cond_br %2780, ^bb417, ^bb418
            ^bb417:
              %2781 = arith.constant 1 : i32
              %2782 = arith.shli %2781, %2777 : i32
              %2783 = arith.andi %2756, %2782 : i32
              %2784 = arith.constant 0 : i32
              %2785 = arith.cmpi ne, %2783, %2784 : i32
              %2786 = scf.if %2785 -> (i1) {
                %2787 = arith.constant 1 : i32
                %2788 = arith.shli %2787, %2779 : i32
                %2789 = arith.andi %2759, %2788 : i32
                %2790 = arith.constant 0 : i32
                %2791 = arith.cmpi ne, %2789, %2790 : i32
                scf.yield %2791 : i1
              } else {
                %2792 = arith.constant false
                scf.yield %2792 : i1
              }
              cf.cond_br %2786, ^bb420, ^bb421
              ^bb420:
                %2793 = arith.constant 46 : i32
                %2794 = arith.muli %2411, %2793 : i32
                %2795 = arith.addi %2794, %2767 : i32
                %2796 = arith.constant 0 : i32
                %2797 = llvm.mlir.constant(1 : i64) : i64
                %2798 = llvm.alloca %2797 x i32 : (i64) -> !llvm.ptr
                llvm.store %2796, %2798 : i32, !llvm.ptr
                cf.br ^bb423
                ^bb423:
                %2799 = llvm.load %2798 : !llvm.ptr -> i32
                %2801 = llvm.mlir.addressof @perms_count : !llvm.ptr
                %2802 = llvm.load %2801 : !llvm.ptr -> !llvm.ptr
                %2803 = arith.extsi %2795 : i32 to i64
                %2804 = llvm.getelementptr %2802[%2803] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                %2800 = llvm.load %2804 : !llvm.ptr -> i32
                %2805 = arith.cmpi slt, %2799, %2800 : i32
                cf.cond_br %2805, ^bb424, ^bb425
                ^bb424:
                  %2807 = llvm.load %2798 : !llvm.ptr -> i32
                  func.call @get_perm(%2411, %2767, %2807) : (i32, i32, i32) -> ()
                  %2808 = arith.constant 1 : i32
                  %2809 = llvm.mlir.constant(1 : i64) : i64
                  %2810 = llvm.alloca %2809 x i32 : (i64) -> !llvm.ptr
                  llvm.store %2808, %2810 : i32, !llvm.ptr
                  %2811 = arith.constant 0 : i32
                  %2812 = llvm.mlir.constant(1 : i64) : i64
                  %2813 = llvm.alloca %2812 x i32 : (i64) -> !llvm.ptr
                  llvm.store %2811, %2813 : i32, !llvm.ptr
                  cf.br ^bb426
                  ^bb426:
                  %2814 = llvm.load %2813 : !llvm.ptr -> i32
                  %2815 = arith.cmpi slt, %2814, %2411 : i32
                  cf.cond_br %2815, ^bb427, ^bb428
                  ^bb427:
                    %2817 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                    %2818 = llvm.load %2817 : !llvm.ptr -> !llvm.ptr
                    %2819 = llvm.load %2813 : !llvm.ptr -> i32
                    %2820 = arith.addi %2416, %2819 : i32
                    %2821 = arith.extsi %2820 : i32 to i64
                    %2822 = llvm.getelementptr %2818[%2821] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2816 = llvm.load %2822 : !llvm.ptr -> i32
                    %2824 = arith.extsi %2816 : i32 to i64
                    %2825 = llvm.getelementptr %arg1[%2824] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2823 = llvm.load %2825 : !llvm.ptr -> i32
                    %2826 = arith.constant 1 : i32
                    %2828 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                    %2829 = llvm.load %2828 : !llvm.ptr -> !llvm.ptr
                    %2830 = llvm.load %2813 : !llvm.ptr -> i32
                    %2831 = arith.extsi %2830 : i32 to i64
                    %2832 = llvm.getelementptr %2829[%2831] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2827 = llvm.load %2832 : !llvm.ptr -> i32
                    %2833 = arith.shli %2826, %2827 : i32
                    %2834 = arith.andi %2823, %2833 : i32
                    %2835 = arith.constant 0 : i32
                    %2836 = arith.cmpi eq, %2834, %2835 : i32
                    cf.cond_br %2836, ^bb429, ^bb430
                    ^bb429:
                      %2837 = arith.constant 0 : i32
                      llvm.store %2837, %2810 : i32, !llvm.ptr
                      cf.br ^bb428
                    ^bb430:
                      cf.br ^bb431
                    ^bb431:
                    %2838 = llvm.load %2813 : !llvm.ptr -> i32
                    %2839 = arith.constant 1 : i32
                    %2840 = arith.addi %2838, %2839 : i32
                    llvm.store %2840, %2813 : i32, !llvm.ptr
                    cf.br ^bb426
                  ^bb428:
                  %2841 = llvm.load %2810 : !llvm.ptr -> i32
                  %2842 = arith.constant 1 : i32
                  %2843 = arith.cmpi eq, %2841, %2842 : i32
                  cf.cond_br %2843, ^bb432, ^bb433
                  ^bb432:
                    %2844 = arith.constant 0 : i32
                    %2845 = llvm.mlir.constant(1 : i64) : i64
                    %2846 = llvm.alloca %2845 x i32 : (i64) -> !llvm.ptr
                    llvm.store %2844, %2846 : i32, !llvm.ptr
                    cf.br ^bb435
                    ^bb435:
                    %2847 = llvm.load %2846 : !llvm.ptr -> i32
                    %2848 = arith.cmpi slt, %2847, %2411 : i32
                    cf.cond_br %2848, ^bb436, ^bb437
                    ^bb436:
                      %2850 = llvm.mlir.addressof @cv_pool : !llvm.ptr
                      %2851 = llvm.load %2850 : !llvm.ptr -> !llvm.ptr
                      %2852 = llvm.load %2846 : !llvm.ptr -> i32
                      %2853 = arith.addi %2416, %2852 : i32
                      %2854 = arith.extsi %2853 : i32 to i64
                      %2855 = llvm.getelementptr %2851[%2854] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2849 = llvm.load %2855 : !llvm.ptr -> i32
                      %2856 = func.call @inv_index_lookup(%arg0, %2849) : (i32, i32) -> i32
                      %2858 = llvm.mlir.addressof @pr_support : !llvm.ptr
                      %2859 = llvm.load %2858 : !llvm.ptr -> !llvm.ptr
                      %2860 = arith.extsi %2856 : i32 to i64
                      %2861 = llvm.getelementptr %2859[%2860] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2857 = llvm.load %2861 : !llvm.ptr -> i32
                      %2862 = arith.constant 1 : i32
                      %2864 = llvm.mlir.addressof @perm_buf : !llvm.ptr
                      %2865 = llvm.load %2864 : !llvm.ptr -> !llvm.ptr
                      %2866 = llvm.load %2846 : !llvm.ptr -> i32
                      %2867 = arith.extsi %2866 : i32 to i64
                      %2868 = llvm.getelementptr %2865[%2867] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      %2863 = llvm.load %2868 : !llvm.ptr -> i32
                      %2869 = arith.shli %2862, %2863 : i32
                      %2870 = arith.ori %2857, %2869 : i32
                      %2871 = llvm.mlir.addressof @pr_support : !llvm.ptr
                      %2872 = llvm.load %2871 : !llvm.ptr -> !llvm.ptr
                      %2873 = arith.extsi %2856 : i32 to i64
                      %2874 = llvm.getelementptr %2872[%2873] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                      llvm.store %2870, %2874 : i32, !llvm.ptr
                      %2875 = llvm.load %2846 : !llvm.ptr -> i32
                      %2876 = arith.constant 1 : i32
                      %2877 = arith.addi %2875, %2876 : i32
                      llvm.store %2877, %2846 : i32, !llvm.ptr
                      cf.br ^bb435
                    ^bb437:
                    %2879 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2880 = llvm.load %2879 : !llvm.ptr -> !llvm.ptr
                    %2881 = arith.extsi %2579 : i32 to i64
                    %2882 = llvm.getelementptr %2880[%2881] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2878 = llvm.load %2882 : !llvm.ptr -> i32
                    %2883 = arith.constant 1 : i32
                    %2884 = arith.shli %2883, %2777 : i32
                    %2885 = arith.ori %2878, %2884 : i32
                    %2886 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2887 = llvm.load %2886 : !llvm.ptr -> !llvm.ptr
                    %2888 = arith.extsi %2579 : i32 to i64
                    %2889 = llvm.getelementptr %2887[%2888] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    llvm.store %2885, %2889 : i32, !llvm.ptr
                    %2891 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2892 = llvm.load %2891 : !llvm.ptr -> !llvm.ptr
                    %2893 = arith.extsi %2580 : i32 to i64
                    %2894 = llvm.getelementptr %2892[%2893] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    %2890 = llvm.load %2894 : !llvm.ptr -> i32
                    %2895 = arith.constant 1 : i32
                    %2896 = arith.shli %2895, %2779 : i32
                    %2897 = arith.ori %2890, %2896 : i32
                    %2898 = llvm.mlir.addressof @pr_support : !llvm.ptr
                    %2899 = llvm.load %2898 : !llvm.ptr -> !llvm.ptr
                    %2900 = arith.extsi %2580 : i32 to i64
                    %2901 = llvm.getelementptr %2899[%2900] : (!llvm.ptr, i64) -> !llvm.ptr, i32
                    llvm.store %2897, %2901 : i32, !llvm.ptr
                    cf.br ^bb434
                  ^bb433:
                    cf.br ^bb434
                  ^bb434:
                  %2902 = llvm.load %2798 : !llvm.ptr -> i32
                  %2903 = arith.constant 1 : i32
                  %2904 = arith.addi %2902, %2903 : i32
                  llvm.store %2904, %2798 : i32, !llvm.ptr
                  cf.br ^bb423
                ^bb425:
                cf.br ^bb422
              ^bb421:
                cf.br ^bb422
              ^bb422:
              cf.br ^bb419
            ^bb418:
              cf.br ^bb419
            ^bb419:
            cf.br ^bb416
          ^bb415:
            cf.br ^bb416
          ^bb416:
          %2905 = llvm.load %2764 : !llvm.ptr -> i32
          %2906 = arith.constant 1 : i32
          %2907 = arith.addi %2905, %2906 : i32
          llvm.store %2907, %2764 : i32, !llvm.ptr
          cf.br ^bb411
        ^bb413:
        cf.br ^bb380
      ^bb380:
      cf.br ^bb353
    ^bb353:
    %2908 = arith.constant 0 : i32
    %2909 = llvm.mlir.addressof @pr_changed_n : !llvm.ptr
    llvm.store %2908, %2909 : i32, !llvm.ptr
    %2910 = arith.constant 0 : i32
    %2911 = llvm.mlir.constant(1 : i64) : i64
    %2912 = llvm.alloca %2911 x i32 : (i64) -> !llvm.ptr
    llvm.store %2910, %2912 : i32, !llvm.ptr
    cf.br ^bb438
    ^bb438:
    %2913 = llvm.load %2912 : !llvm.ptr -> i32
    %2914 = arith.cmpi slt, %2913, %2370 : i32
    cf.cond_br %2914, ^bb439, ^bb440
    ^bb439:
      %2916 = llvm.mlir.addressof @inv_pool : !llvm.ptr
      %2917 = llvm.load %2916 : !llvm.ptr -> !llvm.ptr
      %2919 = llvm.mlir.addressof @run_inv_off : !llvm.ptr
      %2920 = llvm.load %2919 : !llvm.ptr -> !llvm.ptr
      %2921 = arith.extsi %arg0 : i32 to i64
      %2922 = llvm.getelementptr %2920[%2921] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2918 = llvm.load %2922 : !llvm.ptr -> i32
      %2923 = llvm.load %2912 : !llvm.ptr -> i32
      %2924 = arith.addi %2918, %2923 : i32
      %2925 = arith.extsi %2924 : i32 to i64
      %2926 = llvm.getelementptr %2917[%2925] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2915 = llvm.load %2926 : !llvm.ptr -> i32
      %2928 = llvm.mlir.addressof @pr_support : !llvm.ptr
      %2929 = llvm.load %2928 : !llvm.ptr -> !llvm.ptr
      %2930 = llvm.load %2912 : !llvm.ptr -> i32
      %2931 = arith.extsi %2930 : i32 to i64
      %2932 = llvm.getelementptr %2929[%2931] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2927 = llvm.load %2932 : !llvm.ptr -> i32
      %2933 = arith.constant 0 : i32
      %2934 = arith.cmpi eq, %2927, %2933 : i32
      cf.cond_br %2934, ^bb441, ^bb442
      ^bb441:
        %2935 = arith.constant 1 : i32
        func.return %2935 : i32
      ^bb442:
        cf.br ^bb443
      ^bb443:
      %2937 = arith.extsi %2915 : i32 to i64
      %2938 = llvm.getelementptr %arg1[%2937] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2936 = llvm.load %2938 : !llvm.ptr -> i32
      %2939 = arith.andi %2936, %2927 : i32
      %2940 = arith.constant 0 : i32
      %2941 = arith.cmpi eq, %2939, %2940 : i32
      cf.cond_br %2941, ^bb444, ^bb445
      ^bb444:
        %2942 = arith.constant 1 : i32
        func.return %2942 : i32
      ^bb445:
        cf.br ^bb446
      ^bb446:
      %2944 = arith.extsi %2915 : i32 to i64
      %2945 = llvm.getelementptr %arg1[%2944] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %2943 = llvm.load %2945 : !llvm.ptr -> i32
      %2946 = arith.cmpi ne, %2939, %2943 : i32
      cf.cond_br %2946, ^bb447, ^bb448
      ^bb447:
        %2947 = arith.extsi %2915 : i32 to i64
        %2948 = llvm.getelementptr %arg1[%2947] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %2939, %2948 : i32, !llvm.ptr
        %2949 = llvm.mlir.addressof @pr_changed : !llvm.ptr
        %2950 = llvm.load %2949 : !llvm.ptr -> !llvm.ptr
        %2951 = llvm.mlir.addressof @pr_changed_n : !llvm.ptr
        %2952 = llvm.load %2951 : !llvm.ptr -> i32
        %2953 = arith.extsi %2952 : i32 to i64
        %2954 = llvm.getelementptr %2950[%2953] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %2915, %2954 : i32, !llvm.ptr
        %2955 = llvm.mlir.addressof @pr_changed_n : !llvm.ptr
        %2956 = llvm.load %2955 : !llvm.ptr -> i32
        %2957 = arith.constant 1 : i32
        %2958 = arith.addi %2956, %2957 : i32
        %2959 = llvm.mlir.addressof @pr_changed_n : !llvm.ptr
        llvm.store %2958, %2959 : i32, !llvm.ptr
        cf.br ^bb449
      ^bb448:
        cf.br ^bb449
      ^bb449:
      %2960 = llvm.load %2912 : !llvm.ptr -> i32
      %2961 = arith.constant 1 : i32
      %2962 = arith.addi %2960, %2961 : i32
      llvm.store %2962, %2912 : i32, !llvm.ptr
      cf.br ^bb438
    ^bb440:
    %2963 = arith.constant 0 : i32
    func.return %2963 : i32
  }
  // Module static: prop_q
  llvm.mlir.global internal @prop_q() {addr_space = 0 : i32} : !llvm.ptr {
    %2964 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2964 : !llvm.ptr
  }
  // Module static: prop_inq
  llvm.mlir.global internal @prop_inq() {addr_space = 0 : i32} : !llvm.ptr {
    %2965 = llvm.mlir.zero : !llvm.ptr
    llvm.return %2965 : !llvm.ptr
  }
  func.func @propagate(%arg0: !llvm.ptr) -> i32 {
    %2966 = llvm.mlir.addressof @prop_q : !llvm.ptr
    %2967 = llvm.load %2966 : !llvm.ptr -> !llvm.ptr
    %2968 = arith.constant 0 : i32
    %2969 = llvm.inttoptr %2968 : i32 to !llvm.ptr
    %2970 = llvm.icmp "eq" %2967, %2969 : !llvm.ptr
    cf.cond_br %2970, ^bb450, ^bb451
    ^bb450:
      %2972 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
      %2973 = llvm.load %2972 : !llvm.ptr -> i32
      %2974 = arith.constant 100 : i32
      %2975 = arith.addi %2973, %2974 : i32
      %2976 = arith.constant 4 : i32
      %2977 = arith.extsi %2975 : i32 to i64
      %2978 = arith.extsi %2976 : i32 to i64
      %2971 = func.call @calloc(%2977, %2978) : (i64, i64) -> !llvm.ptr
      %2979 = llvm.mlir.addressof @prop_q : !llvm.ptr
      llvm.store %2971, %2979 : !llvm.ptr, !llvm.ptr
      %2981 = llvm.mlir.addressof @MAX_RUNS : !llvm.ptr
      %2982 = llvm.load %2981 : !llvm.ptr -> i32
      %2983 = arith.constant 100 : i32
      %2984 = arith.addi %2982, %2983 : i32
      %2985 = arith.constant 4 : i32
      %2986 = arith.extsi %2984 : i32 to i64
      %2987 = arith.extsi %2985 : i32 to i64
      %2980 = func.call @calloc(%2986, %2987) : (i64, i64) -> !llvm.ptr
      %2988 = llvm.mlir.addressof @prop_inq : !llvm.ptr
      llvm.store %2980, %2988 : !llvm.ptr, !llvm.ptr
      cf.br ^bb452
    ^bb451:
      cf.br ^bb452
    ^bb452:
    %2989 = arith.constant 0 : i32
    %2990 = llvm.mlir.constant(1 : i64) : i64
    %2991 = llvm.alloca %2990 x i32 : (i64) -> !llvm.ptr
    llvm.store %2989, %2991 : i32, !llvm.ptr
    %2992 = arith.constant 0 : i32
    %2993 = llvm.mlir.constant(1 : i64) : i64
    %2994 = llvm.alloca %2993 x i32 : (i64) -> !llvm.ptr
    llvm.store %2992, %2994 : i32, !llvm.ptr
    %2995 = arith.constant 0 : i32
    %2996 = llvm.mlir.constant(1 : i64) : i64
    %2997 = llvm.alloca %2996 x i32 : (i64) -> !llvm.ptr
    llvm.store %2995, %2997 : i32, !llvm.ptr
    cf.br ^bb453
    ^bb453:
    %2998 = llvm.load %2997 : !llvm.ptr -> i32
    %2999 = llvm.mlir.addressof @csp_nruns : !llvm.ptr
    %3000 = llvm.load %2999 : !llvm.ptr -> i32
    %3001 = arith.cmpi slt, %2998, %3000 : i32
    cf.cond_br %3001, ^bb454, ^bb455
    ^bb454:
      %3002 = arith.constant 1 : i32
      %3003 = llvm.mlir.addressof @prop_inq : !llvm.ptr
      %3004 = llvm.load %3003 : !llvm.ptr -> !llvm.ptr
      %3005 = llvm.load %2997 : !llvm.ptr -> i32
      %3006 = arith.extsi %3005 : i32 to i64
      %3007 = llvm.getelementptr %3004[%3006] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %3002, %3007 : i32, !llvm.ptr
      %3008 = llvm.load %2997 : !llvm.ptr -> i32
      %3009 = llvm.mlir.addressof @prop_q : !llvm.ptr
      %3010 = llvm.load %3009 : !llvm.ptr -> !llvm.ptr
      %3011 = llvm.load %2994 : !llvm.ptr -> i32
      %3012 = arith.extsi %3011 : i32 to i64
      %3013 = llvm.getelementptr %3010[%3012] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %3008, %3013 : i32, !llvm.ptr
      %3014 = llvm.load %2994 : !llvm.ptr -> i32
      %3015 = arith.constant 1 : i32
      %3016 = arith.addi %3014, %3015 : i32
      llvm.store %3016, %2994 : i32, !llvm.ptr
      %3017 = llvm.load %2997 : !llvm.ptr -> i32
      %3018 = arith.constant 1 : i32
      %3019 = arith.addi %3017, %3018 : i32
      llvm.store %3019, %2997 : i32, !llvm.ptr
      cf.br ^bb453
    ^bb455:
    cf.br ^bb456
    ^bb456:
    %3020 = arith.constant 1 : i32
    %3021 = arith.constant 1 : i32
    %3022 = arith.cmpi eq, %3020, %3021 : i32
    cf.cond_br %3022, ^bb457, ^bb458
    ^bb457:
      %3023 = func.call @enforce_all_diff(%arg0) : (!llvm.ptr) -> i32
      %3024 = arith.constant 1 : i32
      %3025 = arith.cmpi eq, %3023, %3024 : i32
      cf.cond_br %3025, ^bb459, ^bb460
      ^bb459:
        %3026 = arith.constant 0 : i32
        func.return %3026 : i32
      ^bb460:
        cf.br ^bb461
      ^bb461:
      %3027 = arith.constant 0 : i32
      %3028 = llvm.mlir.constant(1 : i64) : i64
      %3029 = llvm.alloca %3028 x i32 : (i64) -> !llvm.ptr
      llvm.store %3027, %3029 : i32, !llvm.ptr
      cf.br ^bb462
      ^bb462:
      %3030 = llvm.load %3029 : !llvm.ptr -> i32
      %3031 = llvm.mlir.addressof @ad_changed_n : !llvm.ptr
      %3032 = llvm.load %3031 : !llvm.ptr -> i32
      %3033 = arith.cmpi slt, %3030, %3032 : i32
      cf.cond_br %3033, ^bb463, ^bb464
      ^bb463:
        %3035 = llvm.mlir.addressof @ad_changed : !llvm.ptr
        %3036 = llvm.load %3035 : !llvm.ptr -> !llvm.ptr
        %3037 = llvm.load %3029 : !llvm.ptr -> i32
        %3038 = arith.extsi %3037 : i32 to i64
        %3039 = llvm.getelementptr %3036[%3038] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %3034 = llvm.load %3039 : !llvm.ptr -> i32
        %3040 = arith.constant 0 : i32
        %3041 = llvm.mlir.constant(1 : i64) : i64
        %3042 = llvm.alloca %3041 x i32 : (i64) -> !llvm.ptr
        llvm.store %3040, %3042 : i32, !llvm.ptr
        cf.br ^bb465
        ^bb465:
        %3043 = llvm.load %3042 : !llvm.ptr -> i32
        %3045 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %3046 = llvm.load %3045 : !llvm.ptr -> !llvm.ptr
        %3047 = arith.extsi %3034 : i32 to i64
        %3048 = llvm.getelementptr %3046[%3047] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %3044 = llvm.load %3048 : !llvm.ptr -> i32
        %3049 = arith.cmpi slt, %3043, %3044 : i32
        cf.cond_br %3049, ^bb466, ^bb467
        ^bb466:
          %3051 = llvm.mlir.addressof @v2r_data : !llvm.ptr
          %3052 = llvm.load %3051 : !llvm.ptr -> !llvm.ptr
          %3054 = llvm.mlir.addressof @v2r_off : !llvm.ptr
          %3055 = llvm.load %3054 : !llvm.ptr -> !llvm.ptr
          %3056 = arith.extsi %3034 : i32 to i64
          %3057 = llvm.getelementptr %3055[%3056] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3053 = llvm.load %3057 : !llvm.ptr -> i32
          %3058 = llvm.load %3042 : !llvm.ptr -> i32
          %3059 = arith.addi %3053, %3058 : i32
          %3060 = arith.extsi %3059 : i32 to i64
          %3061 = llvm.getelementptr %3052[%3060] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3050 = llvm.load %3061 : !llvm.ptr -> i32
          %3063 = llvm.mlir.addressof @prop_inq : !llvm.ptr
          %3064 = llvm.load %3063 : !llvm.ptr -> !llvm.ptr
          %3065 = arith.extsi %3050 : i32 to i64
          %3066 = llvm.getelementptr %3064[%3065] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3062 = llvm.load %3066 : !llvm.ptr -> i32
          %3067 = arith.constant 0 : i32
          %3068 = arith.cmpi eq, %3062, %3067 : i32
          cf.cond_br %3068, ^bb468, ^bb469
          ^bb468:
            %3069 = llvm.mlir.addressof @prop_q : !llvm.ptr
            %3070 = llvm.load %3069 : !llvm.ptr -> !llvm.ptr
            %3071 = llvm.load %2994 : !llvm.ptr -> i32
            %3072 = arith.extsi %3071 : i32 to i64
            %3073 = llvm.getelementptr %3070[%3072] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %3050, %3073 : i32, !llvm.ptr
            %3074 = llvm.load %2994 : !llvm.ptr -> i32
            %3075 = arith.constant 1 : i32
            %3076 = arith.addi %3074, %3075 : i32
            llvm.store %3076, %2994 : i32, !llvm.ptr
            %3077 = arith.constant 1 : i32
            %3078 = llvm.mlir.addressof @prop_inq : !llvm.ptr
            %3079 = llvm.load %3078 : !llvm.ptr -> !llvm.ptr
            %3080 = arith.extsi %3050 : i32 to i64
            %3081 = llvm.getelementptr %3079[%3080] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %3077, %3081 : i32, !llvm.ptr
            cf.br ^bb470
          ^bb469:
            cf.br ^bb470
          ^bb470:
          %3082 = llvm.load %3042 : !llvm.ptr -> i32
          %3083 = arith.constant 1 : i32
          %3084 = arith.addi %3082, %3083 : i32
          llvm.store %3084, %3042 : i32, !llvm.ptr
          cf.br ^bb465
        ^bb467:
        %3085 = llvm.load %3029 : !llvm.ptr -> i32
        %3086 = arith.constant 1 : i32
        %3087 = arith.addi %3085, %3086 : i32
        llvm.store %3087, %3029 : i32, !llvm.ptr
        cf.br ^bb462
      ^bb464:
      %3088 = llvm.load %2991 : !llvm.ptr -> i32
      %3089 = llvm.load %2994 : !llvm.ptr -> i32
      %3090 = arith.cmpi sge, %3088, %3089 : i32
      cf.cond_br %3090, ^bb471, ^bb472
      ^bb471:
        %3091 = arith.constant 1 : i32
        func.return %3091 : i32
      ^bb472:
        cf.br ^bb473
      ^bb473:
      %3093 = llvm.mlir.addressof @prop_q : !llvm.ptr
      %3094 = llvm.load %3093 : !llvm.ptr -> !llvm.ptr
      %3095 = llvm.load %2991 : !llvm.ptr -> i32
      %3096 = arith.extsi %3095 : i32 to i64
      %3097 = llvm.getelementptr %3094[%3096] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %3092 = llvm.load %3097 : !llvm.ptr -> i32
      %3098 = llvm.load %2991 : !llvm.ptr -> i32
      %3099 = arith.constant 1 : i32
      %3100 = arith.addi %3098, %3099 : i32
      llvm.store %3100, %2991 : i32, !llvm.ptr
      %3101 = arith.constant 0 : i32
      %3102 = llvm.mlir.addressof @prop_inq : !llvm.ptr
      %3103 = llvm.load %3102 : !llvm.ptr -> !llvm.ptr
      %3104 = arith.extsi %3092 : i32 to i64
      %3105 = llvm.getelementptr %3103[%3104] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      llvm.store %3101, %3105 : i32, !llvm.ptr
      %3106 = func.call @process_run(%3092, %arg0) : (i32, !llvm.ptr) -> i32
      %3107 = arith.constant 1 : i32
      %3108 = arith.cmpi eq, %3106, %3107 : i32
      cf.cond_br %3108, ^bb474, ^bb475
      ^bb474:
        %3109 = arith.constant 0 : i32
        func.return %3109 : i32
      ^bb475:
        cf.br ^bb476
      ^bb476:
      %3110 = arith.constant 0 : i32
      %3111 = llvm.mlir.constant(1 : i64) : i64
      %3112 = llvm.alloca %3111 x i32 : (i64) -> !llvm.ptr
      llvm.store %3110, %3112 : i32, !llvm.ptr
      cf.br ^bb477
      ^bb477:
      %3113 = llvm.load %3112 : !llvm.ptr -> i32
      %3114 = llvm.mlir.addressof @pr_changed_n : !llvm.ptr
      %3115 = llvm.load %3114 : !llvm.ptr -> i32
      %3116 = arith.cmpi slt, %3113, %3115 : i32
      cf.cond_br %3116, ^bb478, ^bb479
      ^bb478:
        %3118 = llvm.mlir.addressof @pr_changed : !llvm.ptr
        %3119 = llvm.load %3118 : !llvm.ptr -> !llvm.ptr
        %3120 = llvm.load %3112 : !llvm.ptr -> i32
        %3121 = arith.extsi %3120 : i32 to i64
        %3122 = llvm.getelementptr %3119[%3121] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %3117 = llvm.load %3122 : !llvm.ptr -> i32
        %3123 = arith.constant 0 : i32
        %3124 = llvm.mlir.constant(1 : i64) : i64
        %3125 = llvm.alloca %3124 x i32 : (i64) -> !llvm.ptr
        llvm.store %3123, %3125 : i32, !llvm.ptr
        cf.br ^bb480
        ^bb480:
        %3126 = llvm.load %3125 : !llvm.ptr -> i32
        %3128 = llvm.mlir.addressof @v2r_count : !llvm.ptr
        %3129 = llvm.load %3128 : !llvm.ptr -> !llvm.ptr
        %3130 = arith.extsi %3117 : i32 to i64
        %3131 = llvm.getelementptr %3129[%3130] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %3127 = llvm.load %3131 : !llvm.ptr -> i32
        %3132 = arith.cmpi slt, %3126, %3127 : i32
        cf.cond_br %3132, ^bb481, ^bb482
        ^bb481:
          %3134 = llvm.mlir.addressof @v2r_data : !llvm.ptr
          %3135 = llvm.load %3134 : !llvm.ptr -> !llvm.ptr
          %3137 = llvm.mlir.addressof @v2r_off : !llvm.ptr
          %3138 = llvm.load %3137 : !llvm.ptr -> !llvm.ptr
          %3139 = arith.extsi %3117 : i32 to i64
          %3140 = llvm.getelementptr %3138[%3139] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3136 = llvm.load %3140 : !llvm.ptr -> i32
          %3141 = llvm.load %3125 : !llvm.ptr -> i32
          %3142 = arith.addi %3136, %3141 : i32
          %3143 = arith.extsi %3142 : i32 to i64
          %3144 = llvm.getelementptr %3135[%3143] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3133 = llvm.load %3144 : !llvm.ptr -> i32
          %3146 = llvm.mlir.addressof @prop_inq : !llvm.ptr
          %3147 = llvm.load %3146 : !llvm.ptr -> !llvm.ptr
          %3148 = arith.extsi %3133 : i32 to i64
          %3149 = llvm.getelementptr %3147[%3148] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3145 = llvm.load %3149 : !llvm.ptr -> i32
          %3150 = arith.constant 0 : i32
          %3151 = arith.cmpi eq, %3145, %3150 : i32
          cf.cond_br %3151, ^bb483, ^bb484
          ^bb483:
            %3152 = llvm.mlir.addressof @prop_q : !llvm.ptr
            %3153 = llvm.load %3152 : !llvm.ptr -> !llvm.ptr
            %3154 = llvm.load %2994 : !llvm.ptr -> i32
            %3155 = arith.extsi %3154 : i32 to i64
            %3156 = llvm.getelementptr %3153[%3155] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %3133, %3156 : i32, !llvm.ptr
            %3157 = llvm.load %2994 : !llvm.ptr -> i32
            %3158 = arith.constant 1 : i32
            %3159 = arith.addi %3157, %3158 : i32
            llvm.store %3159, %2994 : i32, !llvm.ptr
            %3160 = arith.constant 1 : i32
            %3161 = llvm.mlir.addressof @prop_inq : !llvm.ptr
            %3162 = llvm.load %3161 : !llvm.ptr -> !llvm.ptr
            %3163 = arith.extsi %3133 : i32 to i64
            %3164 = llvm.getelementptr %3162[%3163] : (!llvm.ptr, i64) -> !llvm.ptr, i32
            llvm.store %3160, %3164 : i32, !llvm.ptr
            cf.br ^bb485
          ^bb484:
            cf.br ^bb485
          ^bb485:
          %3165 = llvm.load %3125 : !llvm.ptr -> i32
          %3166 = arith.constant 1 : i32
          %3167 = arith.addi %3165, %3166 : i32
          llvm.store %3167, %3125 : i32, !llvm.ptr
          cf.br ^bb480
        ^bb482:
        %3168 = llvm.load %3112 : !llvm.ptr -> i32
        %3169 = arith.constant 1 : i32
        %3170 = arith.addi %3168, %3169 : i32
        llvm.store %3170, %3112 : i32, !llvm.ptr
        cf.br ^bb477
      ^bb479:
      cf.br ^bb456
    ^bb458:
    %3171 = arith.constant 1 : i32
    func.return %3171 : i32
  }
  func.func @select_var(%arg0: !llvm.ptr) -> i32 {
    %3172 = arith.constant 1 : i32
    %3174 = arith.constant 0 : i32
    %3173 = arith.subi %3174, %3172 : i32
    %3175 = llvm.mlir.constant(1 : i64) : i64
    %3176 = llvm.alloca %3175 x i32 : (i64) -> !llvm.ptr
    llvm.store %3173, %3176 : i32, !llvm.ptr
    %3177 = arith.constant 999 : i32
    %3178 = llvm.mlir.constant(1 : i64) : i64
    %3179 = llvm.alloca %3178 x i32 : (i64) -> !llvm.ptr
    llvm.store %3177, %3179 : i32, !llvm.ptr
    %3180 = arith.constant 0 : i32
    %3181 = llvm.mlir.constant(1 : i64) : i64
    %3182 = llvm.alloca %3181 x i32 : (i64) -> !llvm.ptr
    llvm.store %3180, %3182 : i32, !llvm.ptr
    cf.br ^bb486
    ^bb486:
    %3183 = llvm.load %3182 : !llvm.ptr -> i32
    %3184 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
    %3185 = llvm.load %3184 : !llvm.ptr -> i32
    %3186 = arith.cmpi slt, %3183, %3185 : i32
    cf.cond_br %3186, ^bb487, ^bb488
    ^bb487:
      %3189 = llvm.load %3182 : !llvm.ptr -> i32
      %3190 = arith.extsi %3189 : i32 to i64
      %3191 = llvm.getelementptr %arg0[%3190] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %3188 = llvm.load %3191 : !llvm.ptr -> i32
      %3187 = func.call @popcount(%3188) : (i32) -> i32
      %3192 = arith.constant 1 : i32
      %3193 = arith.cmpi sgt, %3187, %3192 : i32
      cf.cond_br %3193, ^bb489, ^bb490
      ^bb489:
        %3194 = llvm.load %3179 : !llvm.ptr -> i32
        %3195 = arith.cmpi slt, %3187, %3194 : i32
        cf.cond_br %3195, ^bb492, ^bb493
        ^bb492:
          llvm.store %3187, %3179 : i32, !llvm.ptr
          %3196 = llvm.load %3182 : !llvm.ptr -> i32
          llvm.store %3196, %3176 : i32, !llvm.ptr
          %3197 = arith.constant 2 : i32
          %3198 = arith.cmpi eq, %3187, %3197 : i32
          cf.cond_br %3198, ^bb495, ^bb496
          ^bb495:
            cf.br ^bb488
          ^bb496:
            cf.br ^bb497
          ^bb497:
          cf.br ^bb494
        ^bb493:
          cf.br ^bb494
        ^bb494:
        cf.br ^bb491
      ^bb490:
        cf.br ^bb491
      ^bb491:
      %3199 = llvm.load %3182 : !llvm.ptr -> i32
      %3200 = arith.constant 1 : i32
      %3201 = arith.addi %3199, %3200 : i32
      llvm.store %3201, %3182 : i32, !llvm.ptr
      cf.br ^bb486
    ^bb488:
    %3202 = llvm.load %3176 : !llvm.ptr -> i32
    func.return %3202 : i32
  }
  // Module static: sol_buf
  llvm.mlir.global internal @sol_buf() {addr_space = 0 : i32} : !llvm.ptr {
    %3203 = llvm.mlir.zero : !llvm.ptr
    llvm.return %3203 : !llvm.ptr
  }
  func.func @solve_rec(%arg0: !llvm.ptr) -> i32 {
    %3204 = func.call @propagate(%arg0) : (!llvm.ptr) -> i32
    %3205 = arith.constant 0 : i32
    %3206 = arith.cmpi eq, %3204, %3205 : i32
    cf.cond_br %3206, ^bb498, ^bb499
    ^bb498:
      %3207 = arith.constant 0 : i32
      func.return %3207 : i32
    ^bb499:
      cf.br ^bb500
    ^bb500:
    %3208 = func.call @select_var(%arg0) : (!llvm.ptr) -> i32
    %3209 = arith.constant 0 : i32
    %3210 = arith.cmpi slt, %3208, %3209 : i32
    cf.cond_br %3210, ^bb501, ^bb502
    ^bb501:
      %3211 = arith.constant 0 : i32
      %3212 = llvm.mlir.constant(1 : i64) : i64
      %3213 = llvm.alloca %3212 x i32 : (i64) -> !llvm.ptr
      llvm.store %3211, %3213 : i32, !llvm.ptr
      cf.br ^bb504
      ^bb504:
      %3214 = llvm.load %3213 : !llvm.ptr -> i32
      %3215 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
      %3216 = llvm.load %3215 : !llvm.ptr -> i32
      %3217 = arith.cmpi slt, %3214, %3216 : i32
      cf.cond_br %3217, ^bb505, ^bb506
      ^bb505:
        %3219 = llvm.load %3213 : !llvm.ptr -> i32
        %3220 = arith.extsi %3219 : i32 to i64
        %3221 = llvm.getelementptr %arg0[%3220] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        %3218 = llvm.load %3221 : !llvm.ptr -> i32
        %3222 = llvm.mlir.addressof @sol_buf : !llvm.ptr
        %3223 = llvm.load %3222 : !llvm.ptr -> !llvm.ptr
        %3224 = llvm.load %3213 : !llvm.ptr -> i32
        %3225 = arith.extsi %3224 : i32 to i64
        %3226 = llvm.getelementptr %3223[%3225] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %3218, %3226 : i32, !llvm.ptr
        %3227 = llvm.load %3213 : !llvm.ptr -> i32
        %3228 = arith.constant 1 : i32
        %3229 = arith.addi %3227, %3228 : i32
        llvm.store %3229, %3213 : i32, !llvm.ptr
        cf.br ^bb504
      ^bb506:
      %3230 = arith.constant 1 : i32
      func.return %3230 : i32
    ^bb502:
      cf.br ^bb503
    ^bb503:
    %3232 = arith.extsi %3208 : i32 to i64
    %3233 = llvm.getelementptr %arg0[%3232] : (!llvm.ptr, i64) -> !llvm.ptr, i32
    %3231 = llvm.load %3233 : !llvm.ptr -> i32
    %3234 = arith.constant 0 : i32
    %3235 = llvm.mlir.constant(1 : i64) : i64
    %3236 = llvm.alloca %3235 x i32 : (i64) -> !llvm.ptr
    llvm.store %3234, %3236 : i32, !llvm.ptr
    cf.br ^bb507
    ^bb507:
    %3237 = llvm.load %3236 : !llvm.ptr -> i32
    %3238 = arith.constant 10 : i32
    %3239 = arith.cmpi slt, %3237, %3238 : i32
    cf.cond_br %3239, ^bb508, ^bb509
    ^bb508:
      %3240 = arith.constant 1 : i32
      %3241 = llvm.load %3236 : !llvm.ptr -> i32
      %3242 = arith.shli %3240, %3241 : i32
      %3243 = arith.andi %3231, %3242 : i32
      %3244 = arith.constant 0 : i32
      %3245 = arith.cmpi ne, %3243, %3244 : i32
      cf.cond_br %3245, ^bb510, ^bb511
      ^bb510:
        %3247 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
        %3248 = llvm.load %3247 : !llvm.ptr -> i32
        %3249 = arith.constant 4 : i32
        %3250 = arith.extsi %3248 : i32 to i64
        %3251 = arith.extsi %3249 : i32 to i64
        %3246 = func.call @calloc(%3250, %3251) : (i64, i64) -> !llvm.ptr
        %3252 = arith.constant 0 : i32
        %3253 = llvm.mlir.constant(1 : i64) : i64
        %3254 = llvm.alloca %3253 x i32 : (i64) -> !llvm.ptr
        llvm.store %3252, %3254 : i32, !llvm.ptr
        cf.br ^bb513
        ^bb513:
        %3255 = llvm.load %3254 : !llvm.ptr -> i32
        %3256 = llvm.mlir.addressof @csp_nvars : !llvm.ptr
        %3257 = llvm.load %3256 : !llvm.ptr -> i32
        %3258 = arith.cmpi slt, %3255, %3257 : i32
        cf.cond_br %3258, ^bb514, ^bb515
        ^bb514:
          %3260 = llvm.load %3254 : !llvm.ptr -> i32
          %3261 = arith.extsi %3260 : i32 to i64
          %3262 = llvm.getelementptr %arg0[%3261] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          %3259 = llvm.load %3262 : !llvm.ptr -> i32
          %3263 = llvm.load %3254 : !llvm.ptr -> i32
          %3264 = arith.extsi %3263 : i32 to i64
          %3265 = llvm.getelementptr %3246[%3264] : (!llvm.ptr, i64) -> !llvm.ptr, i32
          llvm.store %3259, %3265 : i32, !llvm.ptr
          %3266 = llvm.load %3254 : !llvm.ptr -> i32
          %3267 = arith.constant 1 : i32
          %3268 = arith.addi %3266, %3267 : i32
          llvm.store %3268, %3254 : i32, !llvm.ptr
          cf.br ^bb513
        ^bb515:
        %3269 = arith.constant 1 : i32
        %3270 = llvm.load %3236 : !llvm.ptr -> i32
        %3271 = arith.shli %3269, %3270 : i32
        %3272 = arith.extsi %3208 : i32 to i64
        %3273 = llvm.getelementptr %3246[%3272] : (!llvm.ptr, i64) -> !llvm.ptr, i32
        llvm.store %3271, %3273 : i32, !llvm.ptr
        %3274 = func.call @solve_rec(%3246) : (!llvm.ptr) -> i32
        func.call @free(%3246) : (!llvm.ptr) -> ()
        %3276 = arith.constant 1 : i32
        %3277 = arith.cmpi eq, %3274, %3276 : i32
        cf.cond_br %3277, ^bb516, ^bb517
        ^bb516:
          %3278 = arith.constant 1 : i32
          func.return %3278 : i32
        ^bb517:
          cf.br ^bb518
        ^bb518:
        cf.br ^bb512
      ^bb511:
        cf.br ^bb512
      ^bb512:
      %3279 = llvm.load %3236 : !llvm.ptr -> i32
      %3280 = arith.constant 1 : i32
      %3281 = arith.addi %3279, %3280 : i32
      llvm.store %3281, %3236 : i32, !llvm.ptr
      cf.br ^bb507
    ^bb509:
    %3282 = arith.constant 0 : i32
    func.return %3282 : i32
  }
  func.func @mapping_to_number(%arg0: !llvm.ptr) -> i64 {
    %3283 = arith.constant 0 : i32
    %3284 = arith.extsi %3283 : i32 to i64
    %3285 = llvm.mlir.constant(1 : i64) : i64
    %3286 = llvm.alloca %3285 x i64 : (i64) -> !llvm.ptr
    llvm.store %3284, %3286 : i64, !llvm.ptr
    %3287 = arith.constant 0 : i32
    %3288 = llvm.mlir.constant(1 : i64) : i64
    %3289 = llvm.alloca %3288 x i32 : (i64) -> !llvm.ptr
    llvm.store %3287, %3289 : i32, !llvm.ptr
    cf.br ^bb519
    ^bb519:
    %3290 = llvm.load %3289 : !llvm.ptr -> i32
    %3291 = arith.constant 10 : i32
    %3292 = arith.cmpi slt, %3290, %3291 : i32
    cf.cond_br %3292, ^bb520, ^bb521
    ^bb520:
      %3295 = llvm.load %3289 : !llvm.ptr -> i32
      %3296 = arith.extsi %3295 : i32 to i64
      %3297 = llvm.getelementptr %arg0[%3296] : (!llvm.ptr, i64) -> !llvm.ptr, i32
      %3294 = llvm.load %3297 : !llvm.ptr -> i32
      %3293 = func.call @ctz(%3294) : (i32) -> i32
      %3298 = llvm.load %3286 : !llvm.ptr -> i64
      %3299 = arith.constant 10 : i32
      %3301 = arith.extsi %3299 : i32 to i64
      %3300 = arith.muli %3298, %3301 : i64
      %3302 = arith.extsi %3293 : i32 to i64
      %3303 = arith.addi %3300, %3302 : i64
      llvm.store %3303, %3286 : i64, !llvm.ptr
      %3304 = llvm.load %3289 : !llvm.ptr -> i32
      %3305 = arith.constant 1 : i32
      %3306 = arith.addi %3304, %3305 : i32
      llvm.store %3306, %3289 : i32, !llvm.ptr
      cf.br ^bb519
    ^bb521:
    %3307 = llvm.load %3286 : !llvm.ptr -> i64
    func.return %3307 : i64
  }
  func.func @solve_puzzle(%arg0: !llvm.ptr, %arg1: i32) -> i64 {
    func.call @parse_puzzle(%arg0, %arg1) : (!llvm.ptr, i32) -> ()
    func.call @build_csp() : () -> ()
    %3310 = llvm.mlir.addressof @sol_buf : !llvm.ptr
    %3311 = llvm.load %3310 : !llvm.ptr -> !llvm.ptr
    %3312 = arith.constant 0 : i32
    %3313 = llvm.inttoptr %3312 : i32 to !llvm.ptr
    %3314 = llvm.icmp "eq" %3311, %3313 : !llvm.ptr
    cf.cond_br %3314, ^bb522, ^bb523
    ^bb522:
      %3316 = llvm.mlir.addressof @MAX_VARS : !llvm.ptr
      %3317 = llvm.load %3316 : !llvm.ptr -> i32
      %3318 = arith.constant 4 : i32
      %3319 = arith.extsi %3317 : i32 to i64
      %3320 = arith.extsi %3318 : i32 to i64
      %3315 = func.call @calloc(%3319, %3320) : (i64, i64) -> !llvm.ptr
      %3321 = llvm.mlir.addressof @sol_buf : !llvm.ptr
      llvm.store %3315, %3321 : !llvm.ptr, !llvm.ptr
      cf.br ^bb524
    ^bb523:
      cf.br ^bb524
    ^bb524:
    %3323 = llvm.mlir.addressof @csp_domains : !llvm.ptr
    %3324 = llvm.load %3323 : !llvm.ptr -> !llvm.ptr
    %3322 = func.call @solve_rec(%3324) : (!llvm.ptr) -> i32
    %3325 = arith.constant 0 : i32
    %3326 = arith.cmpi eq, %3322, %3325 : i32
    cf.cond_br %3326, ^bb525, ^bb526
    ^bb525:
      func.call @abort() : () -> ()
      cf.br ^bb527
    ^bb526:
      cf.br ^bb527
    ^bb527:
    %3329 = llvm.mlir.addressof @sol_buf : !llvm.ptr
    %3330 = llvm.load %3329 : !llvm.ptr -> !llvm.ptr
    %3328 = func.call @mapping_to_number(%3330) : (!llvm.ptr) -> i64
    func.return %3328 : i64
  }
  func.func @main() -> i32 {
    func.call @init_globals() : () -> ()
    %3333 = llvm.mlir.addressof @str_1 : !llvm.ptr
    %3334 = llvm.mlir.addressof @str_2 : !llvm.ptr
    %3332 = func.call @fopen(%3333, %3334) : (!llvm.ptr, !llvm.ptr) -> !llvm.ptr
    %3335 = arith.constant 0 : i32
    %3336 = llvm.inttoptr %3335 : i32 to !llvm.ptr
    %3337 = llvm.icmp "eq" %3332, %3336 : !llvm.ptr
    cf.cond_br %3337, ^bb528, ^bb529
    ^bb528:
      %3338 = llvm.mlir.addressof @str_3 : !llvm.ptr
      %3339 = llvm.call @printf(%3338) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr) -> i32
      %3340 = arith.constant 1 : i32
      func.return %3340 : i32
    ^bb529:
      cf.br ^bb530
    ^bb530:
    %3341 = arith.constant 0 : i32
    %3342 = arith.extsi %3341 : i32 to i64
    %3343 = llvm.mlir.constant(1 : i64) : i64
    %3344 = llvm.alloca %3343 x i64 : (i64) -> !llvm.ptr
    llvm.store %3342, %3344 : i64, !llvm.ptr
    cf.br ^bb531
    ^bb531:
    %3345 = arith.constant 1 : i32
    %3346 = arith.constant 1 : i32
    %3347 = arith.cmpi eq, %3345, %3346 : i32
    cf.cond_br %3347, ^bb532, ^bb533
    ^bb532:
      %3349 = llvm.mlir.addressof @line_buf : !llvm.ptr
      %3350 = llvm.load %3349 : !llvm.ptr -> !llvm.ptr
      %3351 = llvm.mlir.addressof @MAX_LINE : !llvm.ptr
      %3352 = llvm.load %3351 : !llvm.ptr -> i32
      %3348 = func.call @fgets(%3350, %3352, %3332) : (!llvm.ptr, i32, !llvm.ptr) -> !llvm.ptr
      %3353 = arith.constant 0 : i32
      %3354 = llvm.inttoptr %3353 : i32 to !llvm.ptr
      %3355 = llvm.icmp "eq" %3348, %3354 : !llvm.ptr
      cf.cond_br %3355, ^bb534, ^bb535
      ^bb534:
        cf.br ^bb533
      ^bb535:
        cf.br ^bb536
      ^bb536:
      %3356 = arith.constant 0 : i32
      %3357 = llvm.mlir.constant(1 : i64) : i64
      %3358 = llvm.alloca %3357 x i32 : (i64) -> !llvm.ptr
      llvm.store %3356, %3358 : i32, !llvm.ptr
      cf.br ^bb537
      ^bb537:
      %3359 = llvm.load %3358 : !llvm.ptr -> i32
      %3360 = llvm.mlir.addressof @MAX_LINE : !llvm.ptr
      %3361 = llvm.load %3360 : !llvm.ptr -> i32
      %3362 = arith.cmpi slt, %3359, %3361 : i32
      cf.cond_br %3362, ^bb538, ^bb539
      ^bb538:
        %3364 = llvm.mlir.addressof @line_buf : !llvm.ptr
        %3365 = llvm.load %3364 : !llvm.ptr -> !llvm.ptr
        %3366 = llvm.load %3358 : !llvm.ptr -> i32
        %3367 = arith.extsi %3366 : i32 to i64
        %3368 = llvm.getelementptr %3365[%3367] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %3363 = llvm.load %3368 : !llvm.ptr -> i8
        %3369 = arith.constant 0 : i32
        %3371 = arith.extsi %3363 : i8 to i32
        %3370 = arith.cmpi eq, %3371, %3369 : i32
        cf.cond_br %3370, ^bb540, ^bb541
        ^bb540:
          cf.br ^bb539
        ^bb541:
          cf.br ^bb542
        ^bb542:
        %3372 = arith.constant 10 : i32
        %3374 = arith.extsi %3363 : i8 to i32
        %3373 = arith.cmpi eq, %3374, %3372 : i32
        cf.cond_br %3373, ^bb543, ^bb544
        ^bb543:
          cf.br ^bb539
        ^bb544:
          cf.br ^bb545
        ^bb545:
        %3375 = llvm.load %3358 : !llvm.ptr -> i32
        %3376 = arith.constant 1 : i32
        %3377 = arith.addi %3375, %3376 : i32
        llvm.store %3377, %3358 : i32, !llvm.ptr
        cf.br ^bb537
      ^bb539:
      %3378 = llvm.load %3358 : !llvm.ptr -> i32
      %3379 = arith.constant 0 : i32
      %3380 = arith.cmpi sgt, %3378, %3379 : i32
      cf.cond_br %3380, ^bb546, ^bb547
      ^bb546:
        %3382 = llvm.mlir.addressof @line_buf : !llvm.ptr
        %3383 = llvm.load %3382 : !llvm.ptr -> !llvm.ptr
        %3384 = llvm.load %3358 : !llvm.ptr -> i32
        %3385 = arith.constant 1 : i32
        %3386 = arith.subi %3384, %3385 : i32
        %3387 = arith.extsi %3386 : i32 to i64
        %3388 = llvm.getelementptr %3383[%3387] : (!llvm.ptr, i64) -> !llvm.ptr, i8
        %3381 = llvm.load %3388 : !llvm.ptr -> i8
        %3389 = arith.constant 13 : i32
        %3391 = arith.extsi %3381 : i8 to i32
        %3390 = arith.cmpi eq, %3391, %3389 : i32
        cf.cond_br %3390, ^bb549, ^bb550
        ^bb549:
          %3392 = llvm.load %3358 : !llvm.ptr -> i32
          %3393 = arith.constant 1 : i32
          %3394 = arith.subi %3392, %3393 : i32
          llvm.store %3394, %3358 : i32, !llvm.ptr
          cf.br ^bb551
        ^bb550:
          cf.br ^bb551
        ^bb551:
        cf.br ^bb548
      ^bb547:
        cf.br ^bb548
      ^bb548:
      %3395 = llvm.load %3358 : !llvm.ptr -> i32
      %3396 = arith.constant 0 : i32
      %3397 = arith.cmpi sgt, %3395, %3396 : i32
      cf.cond_br %3397, ^bb552, ^bb553
      ^bb552:
        %3398 = llvm.load %3344 : !llvm.ptr -> i64
        %3400 = llvm.mlir.addressof @line_buf : !llvm.ptr
        %3401 = llvm.load %3400 : !llvm.ptr -> !llvm.ptr
        %3402 = llvm.load %3358 : !llvm.ptr -> i32
        %3399 = func.call @solve_puzzle(%3401, %3402) : (!llvm.ptr, i32) -> i64
        %3403 = arith.addi %3398, %3399 : i64
        llvm.store %3403, %3344 : i64, !llvm.ptr
        cf.br ^bb554
      ^bb553:
        cf.br ^bb554
      ^bb554:
      cf.br ^bb531
    ^bb533:
    %3404 = func.call @fclose(%3332) : (!llvm.ptr) -> i32
    %3405 = llvm.mlir.addressof @str_4 : !llvm.ptr
    %3406 = llvm.load %3344 : !llvm.ptr -> i64
    %3407 = llvm.call @printf(%3405, %3406) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i64) -> i32
    %3408 = arith.constant 0 : i32
    func.return %3408 : i32
  }
}