#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <pthread.h>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;

struct FastInput {
    static constexpr size_t BUFSZ = 1 << 20;
    FILE* f = nullptr;
    char buf[BUFSZ];
    size_t pos = 0, len = 0;

    explicit FastInput(const char* path) { f = fopen(path, "rb"); }
    ~FastInput() {
        if (f) fclose(f);
    }
    int get() {
        if (pos >= len) {
            len = fread(buf, 1, BUFSZ, f);
            pos = 0;
            if (!len) return EOF;
        }
        return buf[pos++];
    }
    bool token(string& out) {
        out.clear();
        int c;
        do {
            c = get();
            if (c == EOF) return false;
        } while (isspace(c));
        while (c != EOF && !isspace(c)) {
            out.push_back((char)c);
            c = get();
        }
        return true;
    }
    bool next_int(int& out) {
        int c;
        do {
            c = get();
            if (c == EOF) return false;
        } while (isspace(c));
        int sign = 1;
        if (c == '-') {
            sign = -1;
            c = get();
        }
        int x = 0;
        while (c != EOF && !isspace(c)) {
            x = x * 10 + (c - '0');
            c = get();
        }
        out = sign * x;
        return true;
    }
    void skip_line() {
        int c;
        do {
            c = get();
        } while (c != EOF && c != '\n');
    }
};

struct CNF {
    int vars = 0;
    int clauses_declared = 0;
    vector<int> lits;
    vector<uint32_t> start;
    vector<uint16_t> len;
    vector<uint32_t> pos_clauses;
    vector<uint32_t> pos_count;
    vector<uint32_t> neg_count;
};

static inline int lit_index(int lit) {
    int v = abs(lit);
    return 2 * (v - 1) + (lit > 0 ? 1 : 0);
}

static bool read_cnf(const char* path, CNF& f) {
    FastInput in(path);
    if (!in.f) return false;
    string tok;
    while (in.token(tok)) {
        if (tok == "c") {
            in.skip_line();
        } else if (tok == "p") {
            string kind, sv, sc;
            if (!in.token(kind) || !in.token(sv) || !in.token(sc)) return false;
            f.vars = stoi(sv);
            f.clauses_declared = stoi(sc);
            break;
        }
    }
    if (f.vars <= 0 || f.clauses_declared <= 0) return false;

    f.start.reserve((size_t)f.clauses_declared + 1);
    f.len.reserve((size_t)f.clauses_declared);
    f.lits.reserve((size_t)f.clauses_declared * 5 + 1024);
    f.pos_count.assign((size_t)f.vars + 1, 0);
    f.neg_count.assign((size_t)f.vars + 1, 0);

    vector<int> cur;
    cur.reserve(1024);
    bool all_pos = true;
    int lit;
    while (in.next_int(lit)) {
        if (lit == 0) {
            if (cur.empty()) continue;
            if (cur.size() > 65535) return false;
            uint32_t ci = (uint32_t)f.len.size();
            f.start.push_back((uint32_t)f.lits.size());
            f.len.push_back((uint16_t)cur.size());
            for (int x : cur) f.lits.push_back(x);
            if (all_pos) f.pos_clauses.push_back(ci);
            cur.clear();
            all_pos = true;
            continue;
        }
        if (abs(lit) < 1 || abs(lit) > f.vars) return false;
        cur.push_back(lit);
        if (lit > 0)
            ++f.pos_count[(size_t)lit];
        else {
            ++f.neg_count[(size_t)-lit];
            all_pos = false;
        }
    }
    f.start.push_back((uint32_t)f.lits.size());
    return (int)f.len.size() == f.clauses_declared;
}

struct MinBlock {
    int y0 = 0;
    vector<int> sels;
    vector<int> bit0;
};

static bool clause_eq(const CNF& f, uint32_t ci, const int* xs, int n) {
    if (ci >= f.len.size() || f.len[ci] != n) return false;
    uint32_t s = f.start[ci];
    for (int i = 0; i < n; ++i) {
        if (f.lits[s + i] != xs[i]) return false;
    }
    return true;
}

static bool match_clause_vec(const CNF& f, uint32_t ci, const vector<int>& xs) {
    if (ci >= f.len.size() || f.len[ci] != xs.size()) return false;
    uint32_t s = f.start[ci];
    for (size_t i = 0; i < xs.size(); ++i) {
        if (f.lits[s + i] != xs[i]) return false;
    }
    return true;
}

static bool match_row(const CNF& f, uint32_t pos, const int bits[6], int y0, int sel, int aux0) {
    uint32_t c = pos;
    int a = aux0;
    int prev = a;
    int tmp[16];

    tmp[0] = bits[0]; tmp[1] = y0; tmp[2] = a;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = -bits[0]; tmp[1] = -y0; tmp[2] = a;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = bits[0]; tmp[1] = -y0;
    if (!clause_eq(f, c++, tmp, 2)) return false;
    ++a;

    auto eq_step = [&](int x, int yv) -> bool {
        int cur = a++;
        tmp[0] = x; tmp[1] = yv; tmp[2] = cur; tmp[3] = -prev;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = x; tmp[1] = yv; tmp[2] = -cur; tmp[3] = prev;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = -x; tmp[1] = -yv; tmp[2] = cur; tmp[3] = -prev;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = -x; tmp[1] = -yv; tmp[2] = -cur; tmp[3] = prev;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = -x; tmp[1] = yv; tmp[2] = prev;
        if (!clause_eq(f, c++, tmp, 3)) return false;
        tmp[0] = x; tmp[1] = -yv; tmp[2] = -prev;
        if (!clause_eq(f, c++, tmp, 3)) return false;
        prev = cur;
        return true;
    };
    for (int i = 1; i < 5; ++i) {
        if (!eq_step(bits[i], y0 + i)) return false;
    }
    int cur = a++;
    tmp[0] = y0 + 5; tmp[1] = cur; tmp[2] = -prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = y0 + 5; tmp[1] = -cur; tmp[2] = prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = -(y0 + 5); tmp[1] = -prev;
    if (!clause_eq(f, c++, tmp, 2)) return false;
    prev = cur;
    if (!eq_step(bits[5], y0 + 6)) return false;
    cur = a++;
    tmp[0] = y0 + 7; tmp[1] = cur; tmp[2] = -prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = y0 + 7; tmp[1] = -cur; tmp[2] = prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = -(y0 + 7); tmp[1] = -prev;
    if (!clause_eq(f, c++, tmp, 2)) return false;
    prev = cur;

    tmp[0] = -(y0 + 8); tmp[1] = -prev;
    if (!clause_eq(f, c++, tmp, 2)) return false;
    tmp[0] = -(y0 + 9); tmp[1] = -prev;
    if (!clause_eq(f, c++, tmp, 2)) return false;
    tmp[0] = -(y0 + 8); tmp[1] = -(y0 + 9); tmp[2] = -prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = y0 + 8; tmp[1] = y0 + 9; tmp[2] = prev;
    if (!clause_eq(f, c++, tmp, 3)) return false;

    for (int i = 0; i < 5; ++i) {
        tmp[0] = -sel; tmp[1] = -(y0 + i); tmp[2] = bits[i];
        if (!clause_eq(f, c++, tmp, 3)) return false;
        tmp[0] = -sel; tmp[1] = -bits[i]; tmp[2] = y0 + i;
        if (!clause_eq(f, c++, tmp, 3)) return false;
    }
    tmp[0] = -sel; tmp[1] = -(y0 + 5);
    if (!clause_eq(f, c++, tmp, 2)) return false;
    tmp[0] = -sel; tmp[1] = -(y0 + 6); tmp[2] = bits[5];
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = -sel; tmp[1] = -bits[5]; tmp[2] = y0 + 6;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    for (int i = 7; i <= 9; ++i) {
        tmp[0] = -sel; tmp[1] = -(y0 + i);
        if (!clause_eq(f, c++, tmp, 2)) return false;
    }

    vector<int> xor_aux;
    xor_aux.reserve(10);
    for (int i = 0; i < 5; ++i) {
        cur = a++;
        xor_aux.push_back(cur);
        int x = bits[i], yv = y0 + i;
        tmp[0] = sel; tmp[1] = yv; tmp[2] = x; tmp[3] = -cur;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = sel; tmp[1] = -yv; tmp[2] = -x; tmp[3] = -cur;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = sel; tmp[1] = -yv; tmp[2] = x; tmp[3] = cur;
        if (!clause_eq(f, c++, tmp, 4)) return false;
        tmp[0] = sel; tmp[1] = yv; tmp[2] = -x; tmp[3] = cur;
        if (!clause_eq(f, c++, tmp, 4)) return false;
    }
    cur = a++;
    xor_aux.push_back(cur);
    tmp[0] = sel; tmp[1] = y0 + 5; tmp[2] = -cur;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    tmp[0] = sel; tmp[1] = -(y0 + 5); tmp[2] = cur;
    if (!clause_eq(f, c++, tmp, 3)) return false;
    cur = a++;
    xor_aux.push_back(cur);
    tmp[0] = sel; tmp[1] = y0 + 6; tmp[2] = bits[5]; tmp[3] = -cur;
    if (!clause_eq(f, c++, tmp, 4)) return false;
    tmp[0] = sel; tmp[1] = -(y0 + 6); tmp[2] = -bits[5]; tmp[3] = -cur;
    if (!clause_eq(f, c++, tmp, 4)) return false;
    tmp[0] = sel; tmp[1] = -(y0 + 6); tmp[2] = bits[5]; tmp[3] = cur;
    if (!clause_eq(f, c++, tmp, 4)) return false;
    tmp[0] = sel; tmp[1] = y0 + 6; tmp[2] = -bits[5]; tmp[3] = cur;
    if (!clause_eq(f, c++, tmp, 4)) return false;
    for (int i = 7; i <= 9; ++i) {
        cur = a++;
        xor_aux.push_back(cur);
        tmp[0] = sel; tmp[1] = y0 + i; tmp[2] = -cur;
        if (!clause_eq(f, c++, tmp, 3)) return false;
        tmp[0] = sel; tmp[1] = -(y0 + i); tmp[2] = cur;
        if (!clause_eq(f, c++, tmp, 3)) return false;
    }
    vector<int> final_clause;
    final_clause.reserve(11);
    final_clause.push_back(sel);
    for (int x : xor_aux) final_clause.push_back(x);
    return match_clause_vec(f, c++, final_clause) && c == pos + 92;
}

static vector<MinBlock> detect_min_blocks(const CNF& f, int primary_limit) {
    vector<MinBlock> blocks;
    uint32_t pos = 0;
    while (pos + 92 <= f.len.size()) {
        bool matched = false;
        if (f.len[pos] == 3) {
            uint32_t s = f.start[pos];
            int x0 = f.lits[s], y0 = f.lits[s + 1], aux0 = f.lits[s + 2];
            if (x0 > 0 && y0 == x0 + 6 && aux0 > primary_limit) {
                uint32_t p = pos;
                int row = 0;
                MinBlock b;
                b.y0 = y0;
                while (p + 92 <= f.len.size()) {
                    int bits[6];
                    int sel;
                    if (row == 0) {
                        for (int i = 0; i < 6; ++i) bits[i] = x0 + i;
                        sel = x0 + 16;
                    } else {
                        int base = x0 + 17 + 7 * (row - 1);
                        for (int i = 0; i < 6; ++i) bits[i] = base + i;
                        sel = base + 6;
                    }
                    if (!match_row(f, p, bits, y0, sel, aux0 + 18 * row)) break;
                    b.sels.push_back(sel);
                    b.bit0.push_back(bits[0]);
                    ++row;
                    p += 92;
                }
                if (!b.sels.empty() && p < f.len.size() && f.len[p] == b.sels.size()) {
                    bool ok = true;
                    uint32_t ss = f.start[p];
                    for (size_t i = 0; i < b.sels.size(); ++i) {
                        if (f.lits[ss + i] != b.sels[b.sels.size() - 1 - i]) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) {
                        blocks.push_back(std::move(b));
                        pos = p + 1;
                        matched = true;
                    }
                }
            }
        }
        if (!matched) ++pos;
    }
    return blocks;
}

struct Solver {
    const CNF& f;
    vector<uint8_t> val;  // 0 unassigned, 1 true, 2 false
    vector<int> trail;
    size_t q = 0;

    vector<uint16_t> w0, w1;
    vector<int32_t> watch_head;
    vector<int32_t> watch_next;

    vector<int32_t> pos_head;
    vector<int32_t> pos_next;
    vector<uint32_t> pos_occ_clause;
    vector<uint16_t> pos_remain;
    vector<uint8_t> pos_sat;
    priority_queue<pair<uint16_t, uint32_t>, vector<pair<uint16_t, uint32_t>>, greater<pair<uint16_t, uint32_t>>> pos_heap;
    bool update_positive = true;
    struct PosChange {
        uint32_t p;
        uint16_t old_remain;
        uint8_t old_sat;
    };
    vector<PosChange> pos_trail;

    explicit Solver(const CNF& cnf) : f(cnf) {
        val.assign((size_t)f.vars + 1, 0);
        trail.reserve((size_t)f.vars);
    }

    int lit_value(int lit) const {
        uint8_t vv = val[(size_t)abs(lit)];
        if (!vv) return 0;
        return ((vv == 1) == (lit > 0)) ? 1 : -1;
    }

    bool enqueue(int lit) {
        int v = abs(lit);
        uint8_t want = lit > 0 ? 1 : 2;
        if (val[(size_t)v]) return val[(size_t)v] == want;
        val[(size_t)v] = want;
        trail.push_back(lit);
        if (update_positive && v < (int)pos_head.size()) {
            if (lit > 0) {
                for (int32_t e = pos_head[(size_t)v]; e >= 0; e = pos_next[(size_t)e]) {
                    uint32_t p = pos_occ_clause[(size_t)e];
                    if (!pos_sat[(size_t)p]) {
                        pos_trail.push_back({p, pos_remain[(size_t)p], pos_sat[(size_t)p]});
                        pos_sat[(size_t)p] = 1;
                    }
                }
            } else {
                for (int32_t e = pos_head[(size_t)v]; e >= 0; e = pos_next[(size_t)e]) {
                    uint32_t p = pos_occ_clause[(size_t)e];
                    if (!pos_sat[(size_t)p] && pos_remain[(size_t)p] > 0) {
                        pos_trail.push_back({p, pos_remain[(size_t)p], pos_sat[(size_t)p]});
                        uint16_t r = --pos_remain[(size_t)p];
                        pos_heap.push({r, p});
                    }
                }
            }
        }
        return true;
    }

    void build_positive_data() {
        size_t total = 0;
        for (uint32_t ci : f.pos_clauses) total += f.len[ci];
        pos_head.assign((size_t)f.vars + 1, -1);
        pos_next.reserve(total);
        pos_occ_clause.reserve(total);
        pos_remain.reserve(f.pos_clauses.size());
        pos_sat.assign(f.pos_clauses.size(), 0);
        for (uint32_t p = 0; p < f.pos_clauses.size(); ++p) {
            uint32_t ci = f.pos_clauses[p];
            pos_remain.push_back(f.len[ci]);
            pos_heap.push({f.len[ci], p});
            for (uint32_t j = f.start[ci]; j < f.start[ci + 1]; ++j) {
                int v = f.lits[j];
                int32_t e = (int32_t)pos_next.size();
                pos_next.push_back(pos_head[(size_t)v]);
                pos_occ_clause.push_back(p);
                pos_head[(size_t)v] = e;
            }
        }
    }

    void recompute_positive() {
        while (!pos_heap.empty()) pos_heap.pop();
        for (uint32_t p = 0; p < f.pos_clauses.size(); ++p) {
            uint32_t ci = f.pos_clauses[p];
            bool sat = false;
            uint16_t rem = 0;
            for (uint32_t j = f.start[ci]; j < f.start[ci + 1]; ++j) {
                int lv = lit_value(f.lits[j]);
                if (lv == 1) {
                    sat = true;
                    break;
                }
                if (lv == 0) ++rem;
            }
            pos_sat[(size_t)p] = sat ? 1 : 0;
            pos_remain[(size_t)p] = rem;
            if (!sat) pos_heap.push({rem, p});
        }
    }

    void build_watchers() {
        size_t C = f.len.size();
        w0.assign(C, 0);
        w1.assign(C, 0);
        watch_head.assign((size_t)2 * f.vars + 2, -1);
        watch_next.assign((size_t)2 * C, -1);
        for (uint32_t ci = 0; ci < C; ++ci) {
            if (f.len[ci] == 0) continue;
            w0[ci] = 0;
            w1[ci] = f.len[ci] == 1 ? 0 : 1;
            if (f.len[ci] >= 2) {
                int l0 = f.lits[f.start[ci]];
                int l1 = f.lits[f.start[ci] + 1];
                int32_t e0 = (int32_t)(2u * ci);
                int32_t e1 = (int32_t)(2u * ci + 1u);
                int idx0 = lit_index(l0), idx1 = lit_index(l1);
                watch_next[(size_t)e0] = watch_head[(size_t)idx0];
                watch_head[(size_t)idx0] = e0;
                watch_next[(size_t)e1] = watch_head[(size_t)idx1];
                watch_head[(size_t)idx1] = e1;
            }
        }
    }

    int propagate() {
        while (q < trail.size()) {
            int lit = trail[q++];
            int false_lit = -lit;
            int idx = lit_index(false_lit);
            int32_t prev = -1;
            int32_t e = watch_head[(size_t)idx];
            while (e >= 0) {
                int32_t next = watch_next[(size_t)e];
                uint32_t ci = (uint32_t)(e >> 1);
                int slot = e & 1;
                uint16_t wp = slot ? w1[ci] : w0[ci];
                uint32_t base = f.start[ci];
                if (f.lits[base + wp] != false_lit) {
                    prev = e;
                    e = next;
                    continue;
                }
                uint16_t otherp = slot ? w0[ci] : w1[ci];
                int other = f.lits[base + otherp];
                if (lit_value(other) == 1) {
                    prev = e;
                    e = next;
                    continue;
                }
                bool moved = false;
                for (uint16_t k = 0; k < f.len[ci]; ++k) {
                    if (k == w0[ci] || k == w1[ci]) continue;
                    int cand = f.lits[base + k];
                    if (lit_value(cand) != -1) {
                        if (slot) w1[ci] = k;
                        else w0[ci] = k;
                        if (prev < 0) watch_head[(size_t)idx] = next;
                        else watch_next[(size_t)prev] = next;
                        int nidx = lit_index(cand);
                        watch_next[(size_t)e] = watch_head[(size_t)nidx];
                        watch_head[(size_t)nidx] = e;
                        moved = true;
                        break;
                    }
                }
                if (moved) {
                    e = next;
                    continue;
                }
                int ov = lit_value(other);
                if (ov == -1) return (int)ci;
                if (ov == 0 && !enqueue(other)) return (int)ci;
                prev = e;
                e = next;
            }
        }
        return -1;
    }

    struct Checkpoint {
        size_t trail_size;
        size_t q_value;
        size_t pos_size;
    };
    Checkpoint checkpoint() const { return {trail.size(), q, pos_trail.size()}; }
    void undo(Checkpoint cp) {
        for (size_t i = trail.size(); i > cp.trail_size; --i) {
            val[(size_t)abs(trail[i - 1])] = 0;
        }
        trail.resize(cp.trail_size);
        q = cp.q_value;
        while (pos_trail.size() > cp.pos_size) {
            PosChange ch = pos_trail.back();
            pos_trail.pop_back();
            pos_remain[(size_t)ch.p] = ch.old_remain;
            pos_sat[(size_t)ch.p] = ch.old_sat;
            if (!ch.old_sat) pos_heap.push({ch.old_remain, ch.p});
        }
    }

    bool positive_phase_dfs(int depth = 0) {
        (void)depth;
        while (true) {
            uint32_t p = UINT32_MAX;
            while (!pos_heap.empty()) {
                auto [r, cand] = pos_heap.top();
                if (pos_sat[(size_t)cand] || r != pos_remain[(size_t)cand]) {
                    pos_heap.pop();
                    continue;
                }
                p = cand;
                break;
            }
            if (p == UINT32_MAX) return true;
            if (pos_remain[(size_t)p] == 0) {
                if (getenv("SOLVER_DEBUG")) fprintf(stderr, "positive empty p=%u ci=%u\n", p, f.pos_clauses[(size_t)p] + 1);
                return false;
            }
            uint32_t ci = f.pos_clauses[(size_t)p];
            vector<pair<int64_t, int>> cand;
            for (uint32_t j = f.start[ci]; j < f.start[ci + 1]; ++j) {
                int lit = f.lits[j];
                if (lit_value(lit) != 0) continue;
                int v = lit;
                int64_t score = (int64_t)f.neg_count[(size_t)v] - (int64_t)f.pos_count[(size_t)v];
                cand.push_back({score, lit});
            }
            sort(cand.begin(), cand.end());
            if (cand.empty()) {
                if (getenv("SOLVER_DEBUG")) fprintf(stderr, "positive no lit p=%u ci=%u rem=%u\n", p, ci + 1, pos_remain[(size_t)p]);
                return false;
            }
            for (auto [score, lit] : cand) {
                (void)score;
                auto cp = checkpoint();
                bool ok = enqueue(lit);
                int conf = ok ? propagate() : ci;
                if (ok && conf < 0 && positive_phase_dfs(depth + 1)) return true;
                if (getenv("SOLVER_DEBUG")) {
                    fprintf(stderr, "positive candidate failed lit=%d p=%u ci=%u conf=%d\n", lit, p, ci + 1, conf + 1);
                }
                undo(cp);
            }
            return false;
        }
    }

    bool positive_phase() { return positive_phase_dfs(0); }

    bool complete_remaining() {
        update_positive = false;
        for (int v = 1; v <= f.vars; ++v) {
            if (val[(size_t)v]) continue;
            auto cp = checkpoint();
            if (enqueue(-v) && propagate() < 0) continue;
            undo(cp);
            if (enqueue(v) && propagate() < 0) continue;
            undo(cp);
            return false;
        }
        return true;
    }

    bool verify() const {
        for (uint32_t ci = 0; ci < f.len.size(); ++ci) {
            bool ok = false;
            for (uint32_t j = f.start[ci]; j < f.start[ci + 1]; ++j) {
                if (lit_value(f.lits[j]) == 1) {
                    ok = true;
                    break;
                }
            }
            if (!ok) return false;
        }
        return true;
    }
};

static int solve_main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    if (argc != 3) {
        fprintf(stderr, "usage: solver <formula.cnf> <out.pbp>\n");
        return 1;
    }

    CNF f;
    if (!read_cnf(argv[1], f) || f.len.empty() || f.len[0] < 3) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "parse failed or empty\n");
        cout << "s UNKNOWN\n";
        return 0;
    }
    int primary_limit = abs(f.lits[f.start[0] + 2]) - 1;
    if (primary_limit <= 0 || primary_limit >= f.vars) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "bad primary limit %d vars %d\n", primary_limit, f.vars);
        cout << "s UNKNOWN\n";
        return 0;
    }

    vector<MinBlock> blocks = detect_min_blocks(f, primary_limit);
    if (blocks.empty()) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "no blocks P=%d C=%zu pos=%zu\n", primary_limit, f.len.size(), f.pos_clauses.size());
        cout << "s UNKNOWN\n";
        return 0;
    }
    if (getenv("SOLVER_DEBUG")) fprintf(stderr, "parsed V=%d C=%zu P=%d blocks=%zu pos=%zu\n", f.vars, f.len.size(), primary_limit, blocks.size(), f.pos_clauses.size());

    Solver s(f);
    s.build_positive_data();
    s.build_watchers();

    for (uint32_t ci = 0; ci < f.len.size(); ++ci) {
        if (f.len[ci] == 1 && !s.enqueue(f.lits[f.start[ci]])) {
            cout << "s UNKNOWN\n";
            return 0;
        }
    }

    for (const MinBlock& b : blocks) {
        if (!s.enqueue(b.sels[0])) {
            cout << "s UNKNOWN\n";
            return 0;
        }
        for (size_t i = 1; i < b.sels.size(); ++i) {
            if (!s.enqueue(-b.sels[i])) {
                cout << "s UNKNOWN\n";
                return 0;
            }
        }
        for (int i = 0; i < 10; ++i) {
            if (!s.enqueue(-(b.y0 + i))) {
                cout << "s UNKNOWN\n";
                return 0;
            }
        }
        for (size_t r = 0; r < b.bit0.size(); ++r) {
            int base = b.bit0[r];
            for (int k = 0; k < 6; ++k) {
                int lit = r == 0 ? -(base + k) : (base + k);
                if (!s.enqueue(lit)) {
                    cout << "s UNKNOWN\n";
                    return 0;
                }
            }
        }
    }

    int init_conf = s.propagate();
    if (init_conf >= 0) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "init conflict %d\n", init_conf + 1);
        cout << "s UNKNOWN\n";
        return 0;
    }
    if (!s.positive_phase()) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "positive phase failed trail=%zu\n", s.trail.size());
        cout << "s UNKNOWN\n";
        return 0;
    }
    if (!s.complete_remaining()) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "completion failed trail=%zu\n", s.trail.size());
        cout << "s UNKNOWN\n";
        return 0;
    }
    if (!s.verify()) {
        if (getenv("SOLVER_DEBUG")) fprintf(stderr, "verify failed\n");
        cout << "s UNKNOWN\n";
        return 0;
    }

    cout << "s SATISFIABLE\n";
    int col = 0;
    cout << "v ";
    for (int v = 1; v <= f.vars; ++v) {
        cout << (s.val[(size_t)v] == 1 ? v : -v) << ' ';
        if (++col == 20) {
            cout << "0\n";
            if (v != f.vars) cout << "v ";
            col = 0;
        }
    }
    if (col) cout << "0\n";
    return 10;
}

struct ThreadArgs {
    int argc;
    char** argv;
    int ret = 1;
};

static void* thread_entry(void* ptr) {
    ThreadArgs* args = static_cast<ThreadArgs*>(ptr);
    args->ret = solve_main(args->argc, args->argv);
    return nullptr;
}

int main(int argc, char** argv) {
    ThreadArgs args{argc, argv, 1};
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    // Large PRP instances need deep chronological backtracking over positive
    // domain clauses. Use an explicit stack so the deterministic search does
    // not depend on the worker's default pthread/main stack limit.
    pthread_attr_setstacksize(&attr, (size_t)256 << 20);
    pthread_t tid;
    int rc = pthread_create(&tid, &attr, thread_entry, &args);
    pthread_attr_destroy(&attr);
    if (rc != 0) return solve_main(argc, argv);
    pthread_join(tid, nullptr);
    return args.ret;
}
