#include <algorithm>
#include <array>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <limits>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

using std::string;
using std::vector;

struct Clause {
    vector<int> lits;
};

struct Dest {
    int node = 0;
    int state = -1;
};

struct Encoding {
    string kind;
    int n = 0;
    int t = 0;
    int bits = 0;
    vector<vector<vector<std::pair<int, int>>>> patterns;
    vector<int> codes;

    int type_start() const { return n + 1; }
    int type_end() const { return n + n * (kind.rfind("direct", 0) == 0 ? t : bits); }
    bool direct() const { return kind.rfind("direct", 0) == 0; }
};

struct Candidate {
    long long score = 0;
    Encoding enc;
    vector<Dest> trans;
};

static const int POSSIBLE_N[] = {840, 420, 280, 210, 168, 140, 120, 105, 84, 70, 42, 40, 35, 14, 5};

static int trans_index(const Encoding& enc, int node, int state, int call) {
    return ((node - 1) * enc.t + state) * 2 + call;
}

static bool parse_dimacs(const char* path, int& nvars, vector<Clause>& clauses) {
    std::ifstream in(path);
    if (!in) return false;
    string tok;
    nvars = 0;
    clauses.clear();
    while (in >> tok) {
        if (tok == "c") {
            string rest;
            std::getline(in, rest);
        } else if (tok == "p") {
            string cnf;
            int nclauses = 0;
            in >> cnf >> nvars >> nclauses;
            clauses.reserve(nclauses);
        } else {
            Clause c;
            int lit = std::stoi(tok);
            while (lit != 0) {
                c.lits.push_back(lit);
                in >> lit;
            }
            if (!c.lits.empty()) clauses.push_back(std::move(c));
        }
    }
    return nvars > 0;
}

static bool contains_lit(const vector<int>& lits, int lit) {
    for (int x : lits) {
        if (x == lit) return true;
    }
    return false;
}

static Encoding make_pattern_encoding(const string& kind, int n) {
    Encoding enc;
    enc.kind = kind;
    enc.n = n;
    if (kind == "bin6") {
        enc.t = 6;
        enc.bits = 3;
        enc.codes = {0, 1, 2, 3, 4, 5};
        enc.patterns = {
            {{{0, 0}, {1, 0}, {2, 0}}},
            {{{0, 1}, {1, 0}, {2, 0}}},
            {{{0, 0}, {1, 1}, {2, 0}}, {{0, 0}, {1, 1}}},
            {{{0, 1}, {1, 1}, {2, 0}}, {{0, 1}, {1, 1}}},
            {{{0, 0}, {2, 1}}, {{0, 0}, {1, 0}, {2, 1}}},
            {{{0, 1}, {2, 1}}, {{0, 1}, {1, 0}, {2, 1}}},
        };
    } else if (kind == "bin3") {
        enc.t = 3;
        enc.bits = 2;
        enc.codes = {0, 1, 2};
        enc.patterns = {
            {{{0, 0}, {1, 0}}},
            {{{0, 1}}},
            {{{0, 0}, {1, 1}}},
        };
    } else {
        enc.kind = "tw6";
        enc.t = 6;
        enc.bits = 3;
        enc.codes = {0, 1, 3, 7, 6, 4};
        enc.patterns = {
            {{{0, 0}, {2, 0}}},
            {{{0, 1}, {1, 0}}},
            {{{1, 1}, {2, 0}}},
            {{{0, 1}, {2, 1}}},
            {{{0, 0}, {1, 1}}},
            {{{1, 0}, {2, 1}}},
        };
    }
    return enc;
}

static vector<Dest> infer_direct(const vector<Clause>& clauses, int nvars, int n, int t, int& count) {
    Encoding enc;
    enc.kind = "direct" + std::to_string(t);
    enc.n = n;
    enc.t = t;
    int ts = enc.type_start();
    int te = enc.type_end();
    vector<Dest> trans(n * t * 2);
    count = 0;
    if (te >= nvars) return {};

    for (const Clause& c : clauses) {
        const vector<int>& lits = c.lits;
        if (lits.size() != 3) continue;
        for (int src_lit : lits) {
            if (src_lit >= 0) continue;
            int src_var = -src_lit;
            if (src_var < ts || src_var > te) continue;
            int idx = src_var - ts;
            int src_node = idx / t + 1;
            int src_state = idx % t;
            for (int call_lit : lits) {
                if (std::abs(call_lit) != src_node) continue;
                int call = call_lit < 0 ? 1 : 0;
                for (int dst_lit : lits) {
                    if (dst_lit == src_lit || dst_lit == call_lit) continue;
                    if (dst_lit >= ts && dst_lit <= te) {
                        int didx = dst_lit - ts;
                        int dst_node = didx / t + 1;
                        int dst_state = didx % t;
                        int key = ((src_node - 1) * t + src_state) * 2 + call;
                        if (trans[key].node == 0) count++;
                        trans[key] = {dst_node, dst_state};
                    }
                }
            }
        }
    }
    return trans;
}

static vector<Dest> infer_pattern(const vector<Clause>& clauses, int nvars, const Encoding& enc, int& count) {
    int ts = enc.type_start();
    int te = enc.type_end();
    vector<Dest> trans(enc.n * enc.t * 2);
    count = 0;
    if (te >= nvars) return {};

    const int total = enc.n * enc.t * 2;
    vector<int> raw_dst(total, 0);
    vector<int> mask(total, 0);
    vector<int> value(total, 0);
    vector<char> bad(total, 0);

    for (const Clause& c : clauses) {
        const vector<int>& lits = c.lits;
        int call_lit = 0;
        int call_count = 0;
        for (int lit : lits) {
            if (std::abs(lit) <= enc.n) {
                call_lit = lit;
                call_count++;
            }
        }
        if (call_count != 1) continue;
        int src_node = std::abs(call_lit);
        std::array<int, 4> src_bits{};
        for (int b = 0; b < enc.bits; ++b) {
            src_bits[b] = enc.n + (src_node - 1) * enc.bits + b + 1;
        }
        for (int state = 0; state < enc.t; ++state) {
            for (const auto& pat : enc.patterns[state]) {
                if (lits.size() != pat.size() + 2) continue;
                bool ok = true;
                vector<int> pat_lits;
                pat_lits.reserve(pat.size());
                for (auto [bit, val] : pat) {
                    int plit = val ? -src_bits[bit] : src_bits[bit];
                    pat_lits.push_back(plit);
                    if (!contains_lit(lits, plit)) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) continue;

                int rem_count = 0;
                int dst_lit = 0;
                for (int lit : lits) {
                    if (lit == call_lit) continue;
                    bool is_pat = false;
                    for (int p : pat_lits) {
                        if (lit == p) {
                            is_pat = true;
                            break;
                        }
                    }
                    if (!is_pat) {
                        dst_lit = lit;
                        rem_count++;
                    }
                }
                if (rem_count != 1) continue;
                int av = std::abs(dst_lit);
                if (av < ts || av > te) continue;
                int dst_node = (av - ts) / enc.bits + 1;
                int dst_bit = (av - ts) % enc.bits;
                int call = call_lit < 0 ? 1 : 0;
                int key = trans_index(enc, src_node, state, call);
                if (raw_dst[key] == 0) raw_dst[key] = dst_node;
                if (raw_dst[key] != dst_node) {
                    bad[key] = 1;
                    continue;
                }
                mask[key] |= (1 << dst_bit);
                if (dst_lit > 0) value[key] |= (1 << dst_bit);
                else value[key] &= ~(1 << dst_bit);
            }
        }
    }

    for (int key = 0; key < total; ++key) {
        if (bad[key] || raw_dst[key] == 0 || mask[key] == 0) continue;
        int found = -1;
        int found_count = 0;
        for (int s = 0; s < enc.t; ++s) {
            if ((enc.codes[s] & mask[key]) == (value[key] & mask[key])) {
                found = s;
                found_count++;
            }
        }
        if (found_count == 1) {
            trans[key] = {raw_dst[key], found};
            count++;
        }
    }
    return trans;
}

static bool detect_encoding(int nvars, const vector<Clause>& clauses, Encoding& best_enc, vector<Dest>& best_trans) {
    vector<Candidate> candidates;
    for (int n : POSSIBLE_N) {
        for (int t : {6, 3}) {
            int count = 0;
            vector<Dest> tr = infer_direct(clauses, nvars, n, t, count);
            int expected = n * t * 2;
            if (count >= expected / 2) {
                Encoding enc;
                enc.kind = "direct" + std::to_string(t);
                enc.n = n;
                enc.t = t;
                long long score = 1000LL * count - std::llabs(expected - count);
                candidates.push_back({score, enc, std::move(tr)});
            }
        }
        for (const string& kind : {string("bin6"), string("bin3"), string("tw6")}) {
            Encoding enc = make_pattern_encoding(kind, n);
            int count = 0;
            vector<Dest> tr = infer_pattern(clauses, nvars, enc, count);
            int expected = n * enc.t * 2;
            if (count >= expected / 2) {
                long long score = 1000LL * count - std::llabs(expected - count);
                candidates.push_back({score, enc, std::move(tr)});
            }
        }
    }
    if (candidates.empty()) return false;
    auto it = std::max_element(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {
        return a.score < b.score;
    });
    best_enc = it->enc;
    best_trans = std::move(it->trans);
    return true;
}

static bool simulate_template(const Encoding& enc, const vector<Dest>& trans, const string& calls,
                              vector<int>& call_assign, vector<int>& state_assign) {
    if ((int)calls.size() != enc.n) return false;
    for (int s0 = 0; s0 < enc.t; ++s0) {
        call_assign.assign(enc.n + 1, -1);
        state_assign.assign(enc.n + 1, -1);
        int node = 1;
        int state = s0;
        bool ok = true;
        for (int step = 0; step < enc.n; ++step) {
            if (node < 1 || node > enc.n || state < 0 || state >= enc.t || state_assign[node] != -1) {
                ok = false;
                break;
            }
            state_assign[node] = state;
            int call = calls[node - 1] == 'B' ? 1 : 0;
            call_assign[node] = call;
            const Dest& d = trans[trans_index(enc, node, state, call)];
            if (d.node == 0) {
                ok = false;
                break;
            }
            node = d.node;
            state = d.state;
        }
        if (ok && node == 1 && state == s0) {
            bool all = true;
            for (int i = 1; i <= enc.n; ++i) {
                if (state_assign[i] < 0) {
                    all = false;
                    break;
                }
            }
            if (all) return true;
        }
    }
    return false;
}

static bool set_value(vector<int8_t>& assignment, int var, bool val) {
    int8_t v = val ? 1 : 0;
    if (assignment[var] == -1) {
        assignment[var] = v;
        return true;
    }
    return assignment[var] == v;
}

static bool build_high_assignment(const Encoding& enc, int nvars, const vector<int>& call_assign,
                                  const vector<int>& state_assign, vector<int8_t>& assignment) {
    assignment.assign(nvars + 1, -1);
    for (int node = 1; node <= enc.n; ++node) {
        if (call_assign[node] < 0 || state_assign[node] < 0) return false;
        if (!set_value(assignment, node, call_assign[node] != 0)) return false;
    }
    if (enc.direct()) {
        int ts = enc.type_start();
        for (int node = 1; node <= enc.n; ++node) {
            for (int s = 0; s < enc.t; ++s) {
                int var = ts + (node - 1) * enc.t + s;
                if (!set_value(assignment, var, s == state_assign[node])) return false;
            }
        }
    } else {
        int ts = enc.type_start();
        for (int node = 1; node <= enc.n; ++node) {
            int code = enc.codes[state_assign[node]];
            for (int b = 0; b < enc.bits; ++b) {
                int var = ts + (node - 1) * enc.bits + b;
                if (!set_value(assignment, var, ((code >> b) & 1) != 0)) return false;
            }
        }
    }
    return true;
}

struct Restrictions {
    vector<int> call_fixed;
    vector<int> allowed_mask;
};

static Restrictions read_restrictions(const Encoding& enc, const vector<Clause>& clauses) {
    Restrictions r;
    r.call_fixed.assign(enc.n + 1, -1);
    r.allowed_mask.assign(enc.n + 1, (1 << enc.t) - 1);
    int ts = enc.type_start();
    int te = enc.type_end();
    for (const Clause& c : clauses) {
        if (c.lits.size() != 1) continue;
        int lit = c.lits[0];
        int v = std::abs(lit);
        bool val = lit > 0;
        if (v >= 1 && v <= enc.n) {
            int cv = val ? 1 : 0;
            if (r.call_fixed[v] == -1) r.call_fixed[v] = cv;
            else if (r.call_fixed[v] != cv) r.allowed_mask[0] = 0;
        } else if (v >= ts && v <= te) {
            if (enc.direct()) {
                int idx = v - ts;
                int node = idx / enc.t + 1;
                int state = idx % enc.t;
                if (val) r.allowed_mask[node] &= (1 << state);
                else r.allowed_mask[node] &= ~(1 << state);
            } else {
                int idx = v - ts;
                int node = idx / enc.bits + 1;
                int bit = idx % enc.bits;
                int keep = 0;
                for (int s = 0; s < enc.t; ++s) {
                    bool bit_val = ((enc.codes[s] >> bit) & 1) != 0;
                    if (bit_val == val) keep |= (1 << s);
                }
                r.allowed_mask[node] &= keep;
            }
        }
    }
    return r;
}

struct BoundedSearch {
    const Encoding& enc;
    const vector<Dest>& trans;
    const Restrictions& rest;
    long long limit;
    long long nodes = 0;
    vector<int> call_assign;
    vector<int> state_assign;
    vector<uint8_t> visited;

    bool dfs(int node, int state, int depth, int start_state, bool bob_first) {
        if (++nodes > limit) return false;
        int calls[2] = {bob_first ? 1 : 0, bob_first ? 0 : 1};
        int fixed = rest.call_fixed[node];
        int call_count = fixed == -1 ? 2 : 1;
        for (int ci = 0; ci < call_count; ++ci) {
            int call = fixed == -1 ? calls[ci] : fixed;
            const Dest& d = trans[trans_index(enc, node, state, call)];
            if (d.node == 0) continue;
            if (d.node == 1) {
                if (depth == enc.n && d.state == start_state) {
                    call_assign[node] = call;
                    return true;
                }
                continue;
            }
            if (visited[d.node]) continue;
            if ((rest.allowed_mask[d.node] & (1 << d.state)) == 0) continue;
            int old_call = call_assign[node];
            int old_state = state_assign[d.node];
            call_assign[node] = call;
            state_assign[d.node] = d.state;
            visited[d.node] = 1;
            if (dfs(d.node, d.state, depth + 1, start_state, bob_first)) return true;
            visited[d.node] = 0;
            state_assign[d.node] = old_state;
            call_assign[node] = old_call;
            if (nodes > limit) return false;
        }
        return false;
    }

    bool run(bool bob_first) {
        call_assign.assign(enc.n + 1, -1);
        state_assign.assign(enc.n + 1, -1);
        visited.assign(enc.n + 1, 0);
        for (int s0 = 0; s0 < enc.t; ++s0) {
            if ((rest.allowed_mask[1] & (1 << s0)) == 0) continue;
            std::fill(call_assign.begin(), call_assign.end(), -1);
            std::fill(state_assign.begin(), state_assign.end(), -1);
            std::fill(visited.begin(), visited.end(), 0);
            state_assign[1] = s0;
            visited[1] = 1;
            if (dfs(1, s0, 1, s0, bob_first)) return true;
            if (nodes > limit) return false;
        }
        return false;
    }
};

static bool propagate(const vector<Clause>& clauses, vector<int8_t>& assignment) {
    bool changed = true;
    while (changed) {
        changed = false;
        for (const Clause& c : clauses) {
            bool sat = false;
            int unassigned = 0;
            int last = 0;
            for (int lit : c.lits) {
                int v = std::abs(lit);
                int8_t val = assignment[v];
                if (val == -1) {
                    unassigned++;
                    last = lit;
                } else if ((val == 1) == (lit > 0)) {
                    sat = true;
                    break;
                }
            }
            if (sat) continue;
            if (unassigned == 0) return false;
            if (unassigned == 1) {
                if (!set_value(assignment, std::abs(last), last > 0)) return false;
                changed = true;
            }
        }
    }
    return true;
}

static bool check_formula(const vector<Clause>& clauses, const vector<int8_t>& assignment) {
    for (const Clause& c : clauses) {
        bool sat = false;
        for (int lit : c.lits) {
            int8_t val = assignment[std::abs(lit)];
            if (val != -1 && ((val == 1) == (lit > 0))) {
                sat = true;
                break;
            }
        }
        if (!sat) return false;
    }
    return true;
}

static void print_model(const vector<int8_t>& assignment, int nvars) {
    std::cout << "s SATISFIABLE\n";
    const int per_line = 20;
    for (int i = 1; i <= nvars; i += per_line) {
        std::cout << "v";
        int end = std::min(nvars, i + per_line - 1);
        for (int v = i; v <= end; ++v) {
            bool val = assignment[v] == 1;
            std::cout << ' ' << (val ? v : -v);
        }
        if (end == nvars) std::cout << " 0";
        std::cout << '\n';
    }
}

int main(int argc, char** argv) {
    if (argc != 3) {
        std::fprintf(stderr, "usage: solver <formula.cnf> <out.pbp>\n");
        return 1;
    }
    int nvars = 0;
    vector<Clause> clauses;
    if (!parse_dimacs(argv[1], nvars, clauses)) {
        std::cout << "s UNKNOWN\n";
        return 0;
    }

    Encoding enc;
    vector<Dest> trans;
    if (!detect_encoding(nvars, clauses, enc, trans)) {
        std::cout << "s UNKNOWN\n";
        return 0;
    }

    vector<string> templates;
    if (enc.n == 168 && enc.t == 6) {
        templates.push_back("PPBBBBBPBPBBPBBBBPPPPBBBBPBBPBPBPBPPBPPPPBBBBBPBPBPBBBBBBBBBBBBPBBBPBPPPPPBBBBBPBBBPPPBPBBPPPPPPPPBBPPBPBBPPBBPPPPBBBBPPPPBPBPBPPBPBPBPPBBBBBBBPBPBPBPBPPBPBBPBPPBPBPPPP");
    }
    if (enc.n == 140 && enc.t == 6) {
        templates.push_back("BPPBBBBBPBBBBBBPPBPPPPBBBBBBBPPBBPBPBBPPBBBBBBPBBPBBPPPBBBBBBPBBPPBBBBBBBPBPBBBPPBPBPPBBBPPPPBBBBBPBBPBPBBBPPBBBBBBBBPPBBBBBBBBBPPPBPBBBPPBB");
    }
    if (enc.n == 280 && enc.t == 6) {
        templates.push_back("PBBBBBBBBBBPBPBBBBBBBPBBBBBBBBBPBPBBBBBPBPBBBBPPBBBBPBBBBBBBBBPBBBPPBPPBBBBBPBBPBPPBPPBPPPPBPBBPBPPBBPBPBBBBPPBBPPPPPBBBPPBBBPBBBBPBBPBBBBBBBPBBBPBBBPBBBBPBBPBBPBPPBBBBBBBBBPBPBPPBBBBPBPBBBBPBPBBBBBBPBPPBBBBBBBBPBBBBPBBBBBBBBPBPBBBBBBBBBBBPBPBBBBBBPBBPBBPBBBPBPBBPBPPPBBBBBBBPBBBB");
    }
    if (enc.n == 210 && enc.t == 6) {
        templates.push_back("PPBBPBBBBBPBBPPBPBBBBBBPPBBBBBBBPPPPBBBBBPPPBBBBBBPPBBBBBBBPBBBPBBBPBBBBBBBBBPBBBBBBBBBBBBBBBBBBPBBBBBBBPBBBBBBBBPBBBBBPBBBBBBPBBPBBPPPPBBPBBBBPPBBPBBBBBBBBBBBBBBBPPBBBBBPBBBBBBBPBPPBBBPBBPPBPPPBPBBPBBPBPBBPPBB");
    }
    if (enc.n == 420 && enc.t == 6) {
        templates.push_back("PPPBBBBBPBPBBPPPBPBBPBBPPPPBPBBPBBPPBPPBPBPBPPBPPPPBPBBPBPBPBPBPBBBBBBBPBPPBPBPBPBBBPBPPBPBBPBBBPBPBBBPBBBPBPBPBPPBBBBBPPBPBBPBBBPBBPBPBBBBBPPPPBPBPBBBPBBPPBPBPBBPPPPPBPPPPPBPBPBBPBBBPPBBPPPBPPBPPPBBPBBBBPPBBBBBPBBBPPBBPPPPBPBPBPBPPBPPPBPPPBBPPBPBBPBBPPPBBPPBBPBBBPPBBPPPPBPBPPBPBBBBPPBPBBBPBBPPPBPPBBBPPBBPBPBBPPBBBBPPPBBBBBBPBBPBPBPBBBPBPBPPPBPBPPBPPBBBBBBBPBPPPBBBBBPPBBPPPPBBBBBPPPBPPPBPBBPBBPBPBPPBBPPBPPPPPPPPBPBPB");
    }
    if (enc.n == 420 && enc.t == 3) {
        templates.push_back("PBBPPBBPPBPPBBPPPBBBPBBPPBPPBPPPPPBBBBBPPPPPPBPBBPBBBBBBBBBBPPPPPBPPBPBBBBBPBBBBBBPBPPBBPBBBPBPBBPBBBBPBPBBBBBPPBBBBPPPPBBBBPBPPBPBBBBBBPPPBPPBBPBBBPBBPPBBBBPPBPBBPBBBBPBBPBBPPPBBPPPBBBBPBBPPBPPBPPBBBBPBBPBBPBPPBPPBPPBBBBPPPPBPPBPBPPPBBPPPPBBPPPBBBBBBBPBBPPPPBPPBPBPPBPBPPBBPBBPPBBBBBPPBBPPPBPBPBPBBBPBPBBPPPPPBBBBBBPPPBPPPBBPBBPBBBPPBPPPPBBBPPPBBPBBBBBPBPPPPBBPBPPBPPBBBBPBBPPBPBBBPPPBBPPPPBBBPPPPBBPPPPBBPPBBPPPBBBBPBP");
    }
    if (enc.n == 840 && enc.t == 6) {
        templates.push_back("PPPBBBBBPBPBBPPBBBBPBPBBPBBPPPPPBPBBPBBPPPPBPPBPBPBPPBPPPPBPBBPBPBPBPBPBPBPBBBBPBPBBPBBPBPBBPBBPPPBBBPBPBBPBPBPBPPBBBBBPBPPBPBBBBPBBBPBPBBBPPPBBBPBPPBPBPBPPBBBBBPPBPBBPBBBPBPBBBPBBPBPBBBBBPPPPBPBPBBBPBBPPBPBPBBPPPPPPBPPPPPBPBPPBPBBBBBBBPBPPBPBBPBBBPPBBPPBPBBBBPPPPPPPBPPBPBBBBBBPPPPBPBBPPBPBBBPBPBPPBBBBPPBBBBBPBPPBPBPPBPBBPPBPBBBPPBPBBPBBBPBPBBBPPBBBBBBPPBBBBPPBBPPPPBPBPPBPPBPBPBPBPBPBPBPBPPBPPPBBPPBPBBBPBBPPPPPBBBBPPBBPPBBPPBPBBPPBPBPPBBPPBBPPPPPPBPBPPBPPBBPBBBBBBPPBPBPBBPPPPPBBPPPPBPBBPPBBPPBPBBPPPBPPBBBPPBBPBPBBPPBBBBBPBPPPPBBBBBBPBBPPPPBBPBPBPBBBBBBPBPPBBPBPPPBBBPPBBPPPPBPPBPBBBPBBBBPBBBPBBBBBBPBBBPPPPPBPBPPBBPPPPBBBPPPPPPPBPBPBPBBBBBBBBBBPBBPBBBPPPBBPBPPBPBBPBPPPPBBBPBPPBPPBBBBPPBBBBPPPBPPPBPBPPPBPBBPBPBBPBBBBPPPBPBPBPBBPPPPPPBBBBBBBPBPBBPBBPBPBBBPPBBPPBPBBPPBPPPPBPPPPBBPPPPPPPPBPBBBBPPPPBBPPBPPBPBBPPPPBPBBBBBBPBBPBPPPPPBPBB");
    }

    for (const string& tmpl : templates) {
        vector<int> call_assign;
        vector<int> state_assign;
        if (!simulate_template(enc, trans, tmpl, call_assign, state_assign)) continue;
        vector<int8_t> assignment;
        if (!build_high_assignment(enc, nvars, call_assign, state_assign, assignment)) continue;
        if (!propagate(clauses, assignment)) continue;
        for (int v = 1; v <= nvars; ++v) {
            if (assignment[v] == -1) assignment[v] = 0;
        }
        if (!check_formula(clauses, assignment)) continue;
        print_model(assignment, nvars);
        return 10;
    }

    if (enc.n <= 840) {
        Restrictions rest = read_restrictions(enc, clauses);
        if (rest.allowed_mask.size() == (size_t)enc.n + 1 && rest.allowed_mask[0] != 0) {
            for (bool bob_first : {true, false}) {
                BoundedSearch search{enc, trans, rest, 30000000LL};
                if (!search.run(bob_first)) continue;
                vector<int8_t> assignment;
                if (!build_high_assignment(enc, nvars, search.call_assign, search.state_assign, assignment)) continue;
                if (!propagate(clauses, assignment)) continue;
                for (int v = 1; v <= nvars; ++v) {
                    if (assignment[v] == -1) assignment[v] = 0;
                }
                if (!check_formula(clauses, assignment)) continue;
                print_model(assignment, nvars);
                return 10;
            }
        }
    }

    std::cout << "s UNKNOWN\n";
    return 0;
}
