#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdint>

// CDCL v18: Improved BVE + BSS + optimized CDCL

static const int PBUF = 1 << 20;

// === Improved BVE with sorted elimination order ===
struct BVE {
    int nvars;
    struct Clause { std::vector<int> lits; bool deleted; };
    std::vector<Clause> cls;
    std::vector<std::vector<int>> pos_occ, neg_occ;
    std::vector<bool> elim;
    std::vector<std::vector<int>> resolvents;
    
    void init(int nv){nvars=nv;pos_occ.resize(nv+1);neg_occ.resize(nv+1);elim.assign(nv+1,false);}
    void addClause(const std::vector<int>&lits){
        int idx=cls.size();cls.push_back({lits,false});
        for(int l:lits){if(l>0)pos_occ[l].push_back(idx);else neg_occ[-l].push_back(idx);}
    }
    
    void run(){
        for(int round=0;round<5;round++){
            bool progress=false;
            for(int v=1;v<=nvars;v++){
                if(elim[v])continue;
                std::vector<int>pc,nc;
                for(int ci:pos_occ[v])if(!cls[ci].deleted)pc.push_back(ci);
                for(int ci:neg_occ[v])if(!cls[ci].deleted)nc.push_back(ci);
                int np=pc.size(),nn=nc.size();
                if(np==0||nn==0)continue;
                std::vector<std::vector<int>>res;bool too_many=false;
                for(int pi:pc){for(int ni:nc){
                    std::vector<int>r;bool taut=false;
                    for(int l:cls[pi].lits){if(l==v)continue;r.push_back(l);}
                    for(int l:cls[ni].lits){if(l==-v)continue;bool dup=false;for(int x:r){if(x==l){dup=true;break;}if(x==-l){taut=true;break;}}if(taut)break;if(!dup)r.push_back(l);}
                    if(!taut){res.push_back(std::move(r));if((int)res.size()>np+nn){too_many=true;break;}}}
                    if(too_many)break;}
                if(too_many)continue;
                elim[v]=true;
                for(int ci:pc)cls[ci].deleted=true;
                for(int ci:nc)cls[ci].deleted=true;
                for(auto&r:res){resolvents.push_back(r);addClause(r);}
                progress=true;
            }
            if(!progress)break;
        }
    }
    void getSurviving(std::vector<std::vector<int>>&out){for(auto&c:cls)if(!c.deleted&&!c.lits.empty())out.push_back(c.lits);}
};

// === Binary Self-Subsumption ===
struct BinSelfSub {
    int nvars;
    std::vector<std::vector<int>> impl;
    std::vector<int> in_clause;
    int round;
    static int widx(int l) { return l > 0 ? 2*l : 2*(-l)+1; }
    void init(int nv) { nvars=nv; impl.resize(2*(nv+1)); in_clause.assign(2*(nv+1),0); round=0; }
    void addBinary(int a, int b) { impl[widx(-a)].push_back(b); impl[widx(-b)].push_back(a); }
    void run(std::vector<std::vector<int>>& clauses, std::vector<std::vector<int>>& proof_lines) {
        for(auto& cl:clauses) if(cl.size()==2) addBinary(cl[0],cl[1]);
        for(int rounds=0;rounds<3;rounds++){
            int removed=0;
            for(auto& cl:clauses){
                if(cl.size()<3)continue;
                round++;
                for(int l:cl) in_clause[widx(l)]=round;
                bool changed=false; int j=0;
                for(int i=0;i<(int)cl.size();i++){
                    int l=cl[i]; bool removable=false;
                    for(int m:impl[widx(l)]) if(in_clause[widx(m)]==round&&m!=l){removable=true;break;}
                    if(removable){in_clause[widx(l)]=0;changed=true;removed++;}
                    else cl[j++]=cl[i];
                }
                if(changed){cl.resize(j);proof_lines.push_back(cl);if(cl.size()==2)addBinary(cl[0],cl[1]);}
            }
            if(removed==0)break;
        }
    }
};

// === CDCL Solver ===
struct Solver {
    int nvars;
    std::vector<int> pool;
    struct CInfo { int start, size, lbd; bool learnt; };
    std::vector<CInfo> cinfo;
    struct BinW { int other; };
    std::vector<std::vector<BinW>> binw;
    struct LongW { int cid, blocker; };
    std::vector<std::vector<LongW>> longw;
    static int widx(int l) { return l > 0 ? 2*l : 2*(-l)+1; }
    
    std::vector<int8_t> val;
    std::vector<int> lev;
    std::vector<int8_t> rtag;
    std::vector<int> rval;
    std::vector<int> trail, trail_lim;
    int qhead;
    int8_t lv(int l) const { int8_t v=val[abs(l)]; return l>0?v:-v; }
    
    std::vector<double> act; double vinc;
    std::vector<int> heap, hpos;
    void _hu(int i){int v=heap[i];while(i>0){int p=(i-1)/2;if(act[heap[p]]>=act[v])break;heap[i]=heap[p];hpos[heap[p]]=i;i=p;}heap[i]=v;hpos[v]=i;}
    void _hd(int i){int v=heap[i],sz=heap.size();while(true){int c=2*i+1;if(c>=sz)break;if(c+1<sz&&act[heap[c+1]]>act[heap[c]])c++;if(act[v]>=act[heap[c]])break;heap[i]=heap[c];hpos[heap[c]]=i;i=c;}heap[i]=v;hpos[v]=i;}
    void hins(int v){if(hpos[v]>=0)return;hpos[v]=heap.size();heap.push_back(v);_hu(hpos[v]);}
    int hpop(){if(heap.empty())return 0;int v=heap[0];hpos[v]=-1;if(heap.size()>1){heap[0]=heap.back();heap.pop_back();hpos[heap[0]]=0;_hd(0);}else heap.pop_back();return v;}
    void bump(int v){act[v]+=vinc;if(act[v]>1e100){for(int i=1;i<=nvars;i++)act[i]*=1e-100;vinc*=1e-100;}if(hpos[v]>=0)_hu(hpos[v]);}
    
    std::vector<int8_t> phase;
    std::vector<bool> seen;
    std::vector<int> learnt_buf;
    int btlev, learnt_lbd;
    int bin_ca, bin_cb;
    
    FILE*pfp;char pbuf[PBUF];int ppos;
    void pfl(){if(pfp&&ppos>0){fwrite(pbuf,1,ppos,pfp);ppos=0;}}
    void pw(const char*s,int n){if(!pfp)return;if(ppos+n>PBUF)pfl();if(n>PBUF){fwrite(s,1,n,pfp);return;}memcpy(pbuf+ppos,s,n);ppos+=n;}
    void ps(const char*s){pw(s,strlen(s));}
    void pi(int n){char b[16];int l=sprintf(b,"%d",n);pw(b,l);}
    
    long long nconf;
    int luby_idx; long long next_restart;
    static int luby_val(int i){int sz=1;while(sz<=i)sz=2*sz+1;while(sz-1!=i){sz=(sz-1)/2;if(i>=sz){i-=sz;}}return(sz+1)/2;}
    int num_learnt;
    
    std::vector<int> min_stack, min_poison, analyze_toclear;
    int min_tick;
    uint32_t abstract_levels;
    
    void init(int nv){
        nvars=nv;
        val.assign(nv+1,0);lev.assign(nv+1,-1);
        rtag.assign(nv+1,0);rval.assign(nv+1,-1);
        act.assign(nv+1,0);phase.assign(nv+1,-1);seen.assign(nv+1,false);
        hpos.assign(nv+1,-1);
        binw.resize(2*(nv+1));longw.resize(2*(nv+1));
        vinc=1.0;qhead=0;nconf=0;num_learnt=0;
        luby_idx=0;next_restart=16;
        pfp=nullptr;ppos=0;
        min_poison.assign(nv+1,0);min_tick=0;
    }
    
    void openProof(const char*pp){pfp=fopen(pp,"w");ppos=0;if(pfp)ps("pseudo-Boolean proof version 2.0\n");}
    void writeRup(const std::vector<int>&cl){if(!pfp)return;ps("rup");for(int l:cl){if(l>0){ps(" 1 x");pi(l);}else{ps(" 1 ~x");pi(-l);}}ps(" >= 1 ;\n");}
    
    void addBin(int a,int b,bool learnt){binw[widx(a)].push_back({b});binw[widx(b)].push_back({a});if(learnt)num_learnt++;}
    int addLong(const int*lits,int n,bool learnt,int lbd=0){int cid=cinfo.size(),s=pool.size();cinfo.push_back({s,n,lbd,learnt});for(int i=0;i<n;i++)pool.push_back(lits[i]);longw[widx(lits[0])].push_back({cid,lits[1]});longw[widx(lits[1])].push_back({cid,lits[0]});if(learnt)num_learnt++;return cid;}
    
    void enq(int lit,int8_t tag,int rv){int v=abs(lit);val[v]=lit>0?1:-1;lev[v]=trail_lim.size();rtag[v]=tag;rval[v]=rv;trail.push_back(lit);}
    int curLev()const{return trail_lim.size();}
    
    int propagate(){
        while(qhead<(int)trail.size()){
            int p=trail[qhead++];int fp=-p;
            {const auto&bw=binw[widx(fp)];const int bsz=bw.size();const BinW*bd=bw.data();
             for(int i=0;i<bsz;i++){int o=bd[i].other;int8_t v=lv(o);if(v>0)continue;if(__builtin_expect(v<0,0)){bin_ca=fp;bin_cb=o;return -2;}enq(o,2,fp);}}
            {auto&ws=longw[widx(fp)];int i=0,j=0;
             while(i<(int)ws.size()){
                if(lv(ws[i].blocker)>0){ws[j++]=ws[i++];continue;}
                int cid=ws[i].cid;auto&ci=cinfo[cid];
                if(__builtin_expect(ci.size==0,0)){i++;continue;}
                int*c=&pool[ci.start];int cn=ci.size;
                if(c[0]==fp){int t=c[0];c[0]=c[1];c[1]=t;}
                if(lv(c[0])>0){ws[j].cid=cid;ws[j].blocker=c[0];j++;i++;continue;}
                bool found=false;
                for(int k=2;k<cn;k++){if(lv(c[k])>=0){int t=c[1];c[1]=c[k];c[k]=t;longw[widx(c[1])].push_back({cid,c[0]});i++;found=true;break;}}
                if(found)continue;
                ws[j++]=ws[i++];
                if(lv(c[0])<0){while(i<(int)ws.size())ws[j++]=ws[i++];ws.resize(j);return cid;}
                else{
                    if(ci.learnt&&ci.lbd>2){int nlbd=0;static std::vector<int>ls2;static int lt2=0;if((int)ls2.size()<=curLev())ls2.assign(curLev()+1,0);lt2++;for(int kk=0;kk<cn;kk++){int d=lev[abs(c[kk])];if(d>0&&ls2[d]!=lt2){ls2[d]=lt2;nlbd++;}}if(nlbd<ci.lbd)ci.lbd=nlbd;}
                    enq(c[0],1,cid);
                }
             }ws.resize(j);}
        }
        return -1;
    }
    
    bool litRedundant(int l){
        min_stack.clear();min_stack.push_back(abs(l));int top=analyze_toclear.size();
        while(!min_stack.empty()){int v=min_stack.back();min_stack.pop_back();
            if(rtag[v]==0){for(int i=top;i<(int)analyze_toclear.size();i++)seen[analyze_toclear[i]]=false;analyze_toclear.resize(top);return false;}
            auto chk=[&](int q)->bool{int w=abs(q);if(seen[w]||lev[w]==0)return true;if(rtag[w]==0||!((1u<<(lev[w]&31))&abstract_levels)){min_poison[w]=min_tick;return false;}if(min_poison[w]==min_tick)return false;seen[w]=true;analyze_toclear.push_back(w);min_stack.push_back(w);return true;};
            if(rtag[v]==2){if(!chk(rval[v])){for(int i=top;i<(int)analyze_toclear.size();i++)seen[analyze_toclear[i]]=false;analyze_toclear.resize(top);return false;}}
            else if(rtag[v]==1){int cid=rval[v];int*c=&pool[cinfo[cid].start];int cn=cinfo[cid].size;for(int jj=0;jj<cn;jj++){if(abs(c[jj])==v)continue;if(!chk(c[jj])){for(int i=top;i<(int)analyze_toclear.size();i++)seen[analyze_toclear[i]]=false;analyze_toclear.resize(top);return false;}}}}
        return true;
    }
    
    void analyze(int confl){
        learnt_buf.clear();learnt_buf.push_back(0);analyze_toclear.clear();
        int cnt=0,p=0,idx=trail.size()-1;
        auto proc=[&](int q){int v=abs(q);if(v==abs(p)&&p!=0)return;if(seen[v]||lev[v]==0)return;seen[v]=true;bump(v);analyze_toclear.push_back(v);if(lev[v]==curLev())cnt++;else learnt_buf.push_back(q);};
        if(confl==-2){proc(bin_ca);proc(bin_cb);}
        else{int*c=&pool[cinfo[confl].start];int cn=cinfo[confl].size;for(int j=0;j<cn;j++)proc(c[j]);}
        do{while(!seen[abs(trail[idx])])idx--;p=trail[idx--];seen[abs(p)]=false;cnt--;
            if(cnt>0){int v=abs(p);if(rtag[v]==2)proc(rval[v]);else if(rtag[v]==1){int cid=rval[v];int*c=&pool[cinfo[cid].start];int cn=cinfo[cid].size;for(int j=0;j<cn;j++)proc(c[j]);}}}while(cnt>0);
        learnt_buf[0]=-p;
        min_tick++;abstract_levels=0;for(auto l:learnt_buf)abstract_levels|=1u<<(lev[abs(l)]&31);
        for(auto l:learnt_buf)seen[abs(l)]=true;
        int j=1;for(int i=1;i<(int)learnt_buf.size();i++){if(!litRedundant(learnt_buf[i]))learnt_buf[j++]=learnt_buf[i];}learnt_buf.resize(j);
        for(auto v:analyze_toclear)seen[v]=false;for(auto l:learnt_buf)seen[abs(l)]=false;
        {static std::vector<int>ls;static int lt=0;if((int)ls.size()<=curLev())ls.assign(curLev()+1,0);lt++;learnt_lbd=0;for(auto l:learnt_buf){int d=lev[abs(l)];if(d>0&&ls[d]!=lt){ls[d]=lt;learnt_lbd++;}}}
        if(learnt_buf.size()==1)btlev=0;
        else{int best=1;for(int i=2;i<(int)learnt_buf.size();i++)if(lev[abs(learnt_buf[i])]>lev[abs(learnt_buf[best])])best=i;std::swap(learnt_buf[1],learnt_buf[best]);btlev=lev[abs(learnt_buf[1])];}
    }
    
    void backtrack(int l){
        if(curLev()<=l)return;
        for(int i=trail.size()-1;i>=trail_lim[l];i--){int v=abs(trail[i]);phase[v]=val[v];val[v]=0;lev[v]=-1;hins(v);}
        trail.resize(trail_lim[l]);trail_lim.resize(l);qhead=trail.size();
    }
    
    void reduceDB(){
        struct LI{int cid,lbd;};std::vector<LI>cands;
        for(int i=0;i<(int)cinfo.size();i++){auto&ci=cinfo[i];if(!ci.learnt||ci.size==0)continue;if(ci.lbd<=3)continue;int v=abs(pool[ci.start]);if(val[v]!=0&&rtag[v]==1&&rval[v]==i)continue;cands.push_back({i,ci.lbd});}
        std::sort(cands.begin(),cands.end(),[](const LI&a,const LI&b){return a.lbd>b.lbd;});
        int del=cands.size()/2;for(int i=0;i<del;i++)cinfo[cands[i].cid].size=0;num_learnt-=del;
        for(auto&ws:longw)ws.clear();for(int i=0;i<(int)cinfo.size();i++){auto&ci=cinfo[i];if(ci.size<2)continue;int*c=&pool[ci.start];longw[widx(c[0])].push_back({i,c[1]});longw[widx(c[1])].push_back({i,c[0]});}
    }
    
    int run(){
        if(propagate()!=-1)return 20;
        int red_lim=500;
        while(true){
            int confl=propagate();
            if(confl!=-1){
                nconf++;
                if(curLev()==0)return 20;
                analyze(confl);writeRup(learnt_buf);
                backtrack(btlev);
                if(learnt_buf.size()==1)enq(learnt_buf[0],0,-1);
                else if(learnt_buf.size()==2){addBin(learnt_buf[0],learnt_buf[1],true);enq(learnt_buf[0],2,learnt_buf[1]);}
                else{int cid=addLong(learnt_buf.data(),learnt_buf.size(),true,learnt_lbd);enq(learnt_buf[0],1,cid);}
                vinc*=(1.0/0.90);
                if(nconf>=next_restart){backtrack(0);luby_idx++;next_restart=nconf+luby_val(luby_idx)*16;}
                if(num_learnt>red_lim){backtrack(0);reduceDB();red_lim=(int)(red_lim*1.1)+500;}
            }else{
                int v=0;while(!heap.empty()){v=hpop();if(val[v]==0)break;v=0;}
                if(!v)return 10;
                trail_lim.push_back(trail.size());
                enq(phase[v]<0?-v:v,0,-1);
            }
        }
    }
    
    void finishUnsat(){if(pfp){ps("rup >= 1 ;\noutput NONE\nconclusion UNSAT : -1\nend pseudo-Boolean proof\n");pfl();fclose(pfp);pfp=0;}}
    void finishSat(){if(pfp){pfl();fclose(pfp);pfp=0;}}
};

struct FastReader{FILE*f;char buf[1<<16];int pos,len;FastReader(FILE*f):f(f),pos(0),len(0){}int gc(){if(pos>=len){len=fread(buf,1,sizeof(buf),f);pos=0;if(len==0)return EOF;}return(unsigned char)buf[pos++];}bool readInt(int&x){int c=gc(),s=1;x=0;while(c==' '||c=='\n'||c=='\r'||c=='\t')c=gc();if(c==EOF)return false;if(c=='-'){s=-1;c=gc();}if(c<'0'||c>'9')return false;while(c>='0'&&c<='9'){x=x*10+(c-'0');c=gc();}x*=s;return true;}};

int main(int argc,char**argv){
    if(argc<3)return 0;
    FILE*fp=fopen(argv[1],"r");if(!fp)return 0;
    int nv=0,nc=0;char buf[1<<20];
    while(fgets(buf,sizeof(buf),fp)){if(buf[0]=='c')continue;if(buf[0]=='p'){sscanf(buf,"p cnf %d %d",&nv,&nc);break;}}
    FastReader reader(fp);
    std::vector<std::vector<int>>raw;std::vector<int>lits;int d;
    while(reader.readInt(d)){if(d==0){raw.push_back(lits);lits.clear();}else lits.push_back(d);}
    fclose(fp);
    
    // Pre-BVE unit propagation
    {
        std::vector<int8_t> pval(nv+1,0);
        std::vector<std::vector<int>> bin_impl(2*(nv+1));
        auto pw=[](int l)->int{return l>0?2*l:2*(-l)+1;};
        auto plv=[&](int l)->int8_t{int8_t v=pval[abs(l)];return l>0?v:-v;};
        std::vector<int> prop_q;
        for(auto&cl:raw){if(cl.size()==1)prop_q.push_back(cl[0]);else if(cl.size()==2){bin_impl[pw(-cl[0])].push_back(cl[1]);bin_impl[pw(-cl[1])].push_back(cl[0]);}}
        int qi=0;bool uf=false;
        while(qi<(int)prop_q.size()&&!uf){int l=prop_q[qi++];if(plv(l)>0)continue;if(plv(l)<0){uf=true;break;}pval[abs(l)]=l>0?1:-1;for(int m:bin_impl[pw(l)]){if(plv(m)>0)continue;if(plv(m)<0){uf=true;break;}pval[abs(m)]=m>0?1:-1;prop_q.push_back(m);}}
        if(!uf){std::vector<std::vector<int>>s;for(auto&cl:raw){bool sat=false;std::vector<int>nc2;for(int l:cl){int8_t v=plv(l);if(v>0){sat=true;break;}if(v==0)nc2.push_back(l);}if(!sat&&!nc2.empty())s.push_back(std::move(nc2));}raw=std::move(s);}
    }

    // BVE
    BVE bve;bve.init(nv);
    for(auto&cl:raw)bve.addClause(cl);
    bve.run();
    std::vector<std::vector<int>>surviving;
    bve.getSurviving(surviving);
    
    // BSS
    BinSelfSub bss;bss.init(nv);
    std::vector<std::vector<int>> bss_proofs;
    bss.run(surviving,bss_proofs);
    
    // Build solver
    Solver S;S.init(nv);S.openProof(argv[2]);
    for(auto&r:bve.resolvents)S.writeRup(r);
    for(auto&r:bss_proofs)S.writeRup(r);
    
    bool empty_cl=false;
    for(auto&cl:surviving){
        for(int l:cl)S.act[abs(l)]+=1.0;
        if(cl.empty())empty_cl=true;
        else if(cl.size()==1){if(S.lv(cl[0])<0)empty_cl=true;else if(S.lv(cl[0])==0)S.enq(cl[0],0,-1);}
        else if(cl.size()==2)S.addBin(cl[0],cl[1],false);
        else S.addLong(cl.data(),cl.size(),false);
    }
    S.heap.clear();S.hpos.assign(nv+1,-1);
    {std::vector<bool>used(nv+1,false);for(auto&cl:surviving)for(int l:cl)used[abs(l)]=true;
     for(int v=1;v<=nv;v++)if(used[v])S.hins(v);}
    
    int r;
    if(empty_cl)r=20;
    else r=S.run();
    
    if(r==20){S.finishUnsat();printf("s UNSATISFIABLE\n");return 20;}
    if(r==10){S.finishSat();printf("s SATISFIABLE\nv");for(int v=1;v<=nv;v++)printf(" %d",S.val[v]>0?v:-v);printf(" 0\n");return 10;}
    return 0;
}
