#include <algorithm>
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Formula {
    int vars = 0;
    int clauses = 0;
    vector<int> lits;
    vector<int> start;
};

static bool parse_dimacs(const string &path, Formula &F) {
    FILE *fp = fopen(path.c_str(), "rb");
    if (!fp) return false;
    static const size_t BUFSZ = 1 << 20;
    vector<char> buf(BUFSZ);
    size_t pos = 0, len = 0;
    auto getch = [&]() -> int {
        if (pos == len) {
            len = fread(buf.data(), 1, BUFSZ, fp);
            pos = 0;
            if (len == 0) return EOF;
        }
        return buf[pos++];
    };
    auto skip_line = [&]() {
        int ch;
        while ((ch = getch()) != EOF && ch != '\n') {}
    };
    auto next_int = [&]() -> int {
        int ch;
        do {
            ch = getch();
        } while (ch != EOF && ch <= ' ');
        int sign = 1;
        if (ch == '-') {
            sign = -1;
            ch = getch();
        }
        int x = 0;
        while (ch > ' ') {
            x = x * 10 + (ch - '0');
            ch = getch();
        }
        return sign * x;
    };

    F.start.push_back(0);
    int ch;
    while ((ch = getch()) != EOF) {
        if (ch <= ' ') continue;
        if (ch == 'c') {
            skip_line();
        } else if (ch == 'p') {
            // Skip the "cnf" token and read the two header integers.
            do {
                ch = getch();
            } while (ch != EOF && ch <= ' ');
            while (ch != EOF && ch > ' ') ch = getch();
            F.vars = next_int();
            F.clauses = next_int();
            if (F.vars <= 0 || F.clauses <= 0) {
                fclose(fp);
                return false;
            }
            F.lits.reserve((size_t)F.clauses * 4);
        } else {
            if (F.vars == 0) {
                fclose(fp);
                return false;
            }
            int sign = 1;
            if (ch == '-') {
                sign = -1;
                ch = getch();
            }
            int lit = 0;
            while (ch > ' ') {
                lit = lit * 10 + (ch - '0');
                ch = getch();
            }
            lit *= sign;
            while (lit != 0) {
                F.lits.push_back(lit);
                lit = next_int();
            }
            F.start.push_back((int)F.lits.size());
        }
    }
    fclose(fp);
    F.clauses = (int)F.start.size() - 1;
    return F.vars > 0 && F.clauses > 0;
}

static inline int lit_index(int lit) {
    int v = abs(lit);
    return lit > 0 ? (v << 1) : ((v << 1) ^ 1);
}

static inline bool is_true(int lit, const vector<int8_t> &asg) {
    int8_t a = asg[abs(lit)];
    return a >= 0 && ((lit > 0 && a == 1) || (lit < 0 && a == 0));
}

static inline bool is_false(int lit, const vector<int8_t> &asg) {
    int8_t a = asg[abs(lit)];
    return a >= 0 && ((lit > 0 && a == 0) || (lit < 0 && a == 1));
}

struct WatchedGreedy {
    const Formula &F;
    vector<vector<int>> watches;
    vector<int> w0, w1;
    vector<int8_t> asg;
    vector<int> trail;
    size_t qhead = 0;

    explicit WatchedGreedy(const Formula &formula) : F(formula) {
        watches.resize((size_t)(F.vars + 1) * 2 + 2);
        w0.assign(F.clauses, -1);
        w1.assign(F.clauses, -1);
        asg.assign((size_t)F.vars + 1, -1);
        trail.reserve(F.vars);
    }

    bool build() {
        vector<int> watch_counts((size_t)(F.vars + 1) * 2 + 2, 0);
        for (int c = 0; c < F.clauses; ++c) {
            int b = F.start[c], e = F.start[c + 1];
            int len = e - b;
            if (len <= 0) return false;
            w0[c] = b;
            w1[c] = (len == 1 ? b : b + 1);
            ++watch_counts[lit_index(F.lits[w0[c]])];
            if (w1[c] != w0[c]) ++watch_counts[lit_index(F.lits[w1[c]])];
        }
        for (size_t i = 0; i < watches.size(); ++i) {
            if (watch_counts[i]) watches[i].reserve(watch_counts[i]);
        }
        for (int c = 0; c < F.clauses; ++c) {
            watches[lit_index(F.lits[w0[c]])].push_back(c);
            if (w1[c] != w0[c]) watches[lit_index(F.lits[w1[c]])].push_back(c);
        }
        for (int c = 0; c < F.clauses; ++c) {
            if (F.start[c + 1] - F.start[c] == 1) {
                if (!assign_lit(F.lits[F.start[c]])) return false;
            }
        }
        return propagate();
    }

    bool assign_lit(int lit) {
        int v = abs(lit);
        int8_t val = lit > 0 ? 1 : 0;
        if (asg[v] >= 0) return asg[v] == val;
        asg[v] = val;
        trail.push_back(lit);
        return true;
    }

    void rollback(size_t mark, size_t qmark) {
        while (trail.size() > mark) {
            int lit = trail.back();
            trail.pop_back();
            asg[abs(lit)] = -1;
        }
        qhead = min(qhead, qmark);
    }

    bool propagate() {
        while (qhead < trail.size()) {
            int lit = trail[qhead++];
            int false_idx = lit_index(-lit);
            auto &ws = watches[false_idx];
            size_t i = 0;
            while (i < ws.size()) {
                int c = ws[i];
                int wp_false = (lit_index(F.lits[w0[c]]) == false_idx) ? w0[c] : w1[c];
                int wp_other = (wp_false == w0[c]) ? w1[c] : w0[c];
                int other_lit = F.lits[wp_other];
                if (is_true(other_lit, asg)) {
                    ++i;
                    continue;
                }

                bool moved = false;
                for (int p = F.start[c]; p < F.start[c + 1]; ++p) {
                    if (p == w0[c] || p == w1[c]) continue;
                    int l = F.lits[p];
                    if (!is_false(l, asg)) {
                        if (wp_false == w0[c]) w0[c] = p;
                        else w1[c] = p;
                        ws[i] = ws.back();
                        ws.pop_back();
                        watches[lit_index(l)].push_back(c);
                        moved = true;
                        break;
                    }
                }
                if (moved) continue;

                if (is_false(other_lit, asg)) return false;
                if (!assign_lit(other_lit)) return false;
                ++i;
            }
        }
        return true;
    }

    bool complete() {
        for (int v = 1; v <= F.vars; ++v) {
            if (asg[v] >= 0) continue;
            size_t mark = trail.size();
            size_t qmark = qhead;
            if (!assign_lit(v) || !propagate()) {
                rollback(mark, qmark);
                if (!assign_lit(-v) || !propagate()) {
                    rollback(mark, qmark);
                    fprintf(stderr, "c greedy completion failed at var %d\n", v);
                    return false;
                }
            }
            if ((v & 0x7ffff) == 0) {
                fprintf(stderr, "c assigned through var %d trail=%zu\n", v, trail.size());
            }
        }
        return true;
    }
};

static int verify_unsat_count(const Formula &F, const vector<int8_t> &asg) {
    int uns = 0;
    for (int c = 0; c < F.clauses; ++c) {
        bool sat = false;
        for (int p = F.start[c]; p < F.start[c + 1]; ++p) {
            if (is_true(F.lits[p], asg)) {
                sat = true;
                break;
            }
        }
        if (!sat) ++uns;
    }
    return uns;
}

static void print_model(const vector<int8_t> &asg) {
    fwrite("s SATISFIABLE\n", 1, 14, stdout);
    string out;
    out.reserve(1 << 20);
    int col = 0;
    out += 'v';
    char tmp[32];
    for (int v = 1; v < (int)asg.size(); ++v) {
        if (col == 20) {
            out += " 0\nv";
            col = 0;
        }
        int n = snprintf(tmp, sizeof(tmp), " %d", asg[v] == 1 ? v : -v);
        out.append(tmp, tmp + n);
        if (out.size() >= (1 << 20)) {
            fwrite(out.data(), 1, out.size(), stdout);
            out.clear();
        }
        ++col;
    }
    out += " 0\n";
    if (!out.empty()) fwrite(out.data(), 1, out.size(), stdout);
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "usage: solver <formula.cnf> <out.pbp>\n");
        return 1;
    }
    Formula F;
    if (!parse_dimacs(argv[1], F)) {
        printf("s UNKNOWN\n");
        return 0;
    }
    fprintf(stderr, "c parsed %d variables %d clauses %zu literals\n", F.vars, F.clauses, F.lits.size());

    WatchedGreedy solver(F);
    if (!solver.build() || !solver.complete()) {
        printf("s UNKNOWN\n");
        return 0;
    }
    int uns = verify_unsat_count(F, solver.asg);
    fprintf(stderr, "c verification unsat=%d\n", uns);
    if (uns != 0) {
        printf("s UNKNOWN\n");
        return 0;
    }
    print_model(solver.asg);
    return 10;
}
