// HGen Solver v20 - v15 base (probSAT+freebie+PAWS) + CDCL with clause minimization
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std;

static uint64_t _rs[4];
static void _seed(uint64_t x){for(int i=0;i<4;i++){x+=0x9e3779b97f4a7c15ULL;uint64_t z=x;z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL;z=(z^(z>>27))*0x94d049bb133111ebULL;_rs[i]=z^(z>>31);}}
static inline uint64_t _rn(){uint64_t r=((_rs[1]*5)<<7|(_rs[1]*5)>>57)*9,t=_rs[1]<<17;_rs[2]^=_rs[0];_rs[3]^=_rs[1];_rs[1]^=_rs[2];_rs[0]^=_rs[3];_rs[2]^=t;_rs[3]=(_rs[3]<<45)|(_rs[3]>>19);return r;}
static inline uint32_t _ri(uint32_t n){return(uint32_t)(((uint64_t)(uint32_t)_rn()*(uint64_t)n)>>32);}
static inline double _rd(){return(_rn()>>11)*0x1.0p-53;}

static auto T0=chrono::steady_clock::now();
static double TLIM=595.0;
static inline double el(){return chrono::duration<double>(chrono::steady_clock::now()-T0).count();}

static int N,M;
static vector<int> cd,co,cl2;
static vector<vector<int>> posOcc, negOcc;

static void parse(const char* fn){
    FILE* f=fopen(fn,"rb");if(!f)exit(1);
    fseek(f,0,SEEK_END);long sz=ftell(f);fseek(f,0,SEEK_SET);
    char* buf=new char[sz+1];fread(buf,1,sz,f);buf[sz]=0;fclose(f);
    char* p=buf;
    while(*p){if(*p=='c'){while(*p&&*p!='\n')p++;if(*p)p++;continue;}
    if(*p=='p'){sscanf(p,"p cnf %d %d",&N,&M);while(*p&&*p!='\n')p++;if(*p)p++;break;}p++;}
    co.reserve(M);cl2.reserve(M);cd.reserve(M*4);
    int ci=0,cs=0;
    while(*p&&ci<M){
        while(*p==' '||*p=='\n'||*p=='\r'||*p=='\t')p++;if(!*p)break;
        bool neg=(*p=='-');if(neg)p++;
        if(*p<'0'||*p>'9'){p++;continue;}
        int v=0;while(*p>='0'&&*p<='9'){v=v*10+(*p-'0');p++;}
        if(neg)v=-v;
        if(v==0){int l=(int)cd.size()-cs;if(l>0){co.push_back(cs);cl2.push_back(l);ci++;cs=(int)cd.size();}}
        else cd.push_back(v);
    }
    delete[]buf;M=ci;
    posOcc.resize(N+1);negOcc.resize(N+1);
    for(int c=0;c<M;c++){int s=co[c],l=cl2[c];
    for(int j=0;j<l;j++){int lit=cd[s+j];if(lit>0)posOcc[lit].push_back(c);else negOcc[-lit].push_back(c);}}
}

static vector<int> asgn;
static vector<int> ntrue, critvar, brk;
static int* flist; static int* fidx; static int nf;

static inline bool lt(int l){return l>0?asgn[l]:!asgn[-l];}
static inline void af(int c){fidx[c]=nf;flist[nf++]=c;}
static inline void rf(int c){int p=fidx[c];nf--;flist[p]=flist[nf];fidx[flist[p]]=p;fidx[c]=-1;}

static void flip(int v){
    asgn[v]^=1;
    auto& mt=asgn[v]?posOcc[v]:negOcc[v];
    auto& mf=asgn[v]?negOcc[v]:posOcc[v];
    for(int c:mt){int o=ntrue[c]++;if(o==0){rf(c);critvar[c]=v;brk[v]++;}else if(o==1)brk[critvar[c]]--;}
    for(int c:mf){int o=ntrue[c]--;if(o==1){af(c);brk[v]--;}
    else if(o==2){int s=co[c],l=cl2[c];for(int j=0;j<l;j++){int lit=cd[s+j];if(lt(lit)){critvar[c]=abs(lit);brk[abs(lit)]++;break;}}}}
}

static double st37[256],st25[256],st4[256],sthi[256],st44[256],st40[256];
static void initST(){
    for(int b=0;b<256;b++){
        st37[b]=pow(0.9+(double)b,-3.7);
        st25[b]=pow(0.9+(double)b,-2.5);
        st4[b]=pow(0.9+(double)b,-2.85);
        sthi[b]=pow(0.9+(double)b,-4.5);
        st44[b]=pow(0.9+(double)b,-4.4);
        st40[b]=pow(0.9+(double)b,-4.0);
    }
}

static inline int ps3(int c, double* st){
    int s=co[c];
    int v0=abs(cd[s]),v1=abs(cd[s+1]),v2=abs(cd[s+2]);
    int b0=brk[v0],b1=brk[v1],b2=brk[v2];
    if(b0==0) return v0; if(b1==0) return v1; if(b2==0) return v2;
    double s0=st[min(b0,255)],s1=st[min(b1,255)],s2=st[min(b2,255)];
    double t=s0+s1+s2,r=_rd()*t;
    if(r<s0)return v0;if(r<s0+s1)return v1;return v2;
}

static inline int psG(int c, double* st3){
    int s=co[c],l=cl2[c];
    double*tbl=(l<=3)?st3:st44;
    for(int j=0;j<l;j++) if(brk[abs(cd[s+j])]==0) return abs(cd[s+j]);
    double sc[16],tot=0;
    for(int j=0;j<l;j++){double ss=tbl[min(brk[abs(cd[s+j])],255)];sc[j]=ss;tot+=ss;}
    double r=_rd()*tot,cum=0;
    for(int j=0;j<l-1;j++){cum+=sc[j];if(cum>=r)return abs(cd[s+j]);}
    return abs(cd[s+l-1]);
}

static void initAssign(){
    for(int v=1;v<=N;v++)asgn[v]=_ri(2);
    memset(ntrue.data(),0,M*sizeof(int));
    memset(critvar.data(),0,M*sizeof(int));
    memset(brk.data(),0,(N+1)*sizeof(int));
    nf=0;
    for(int c=0;c<M;c++){fidx[c]=-1;int s=co[c],l=cl2[c],cnt=0,cv=0;
    for(int j=0;j<l;j++)if(lt(cd[s+j])){cnt++;cv=abs(cd[s+j]);}
    ntrue[c]=cnt;if(cnt==0)af(c);else if(cnt==1){critvar[c]=cv;brk[cv]++;}}
}

static void initFromAssign(){
    memset(ntrue.data(),0,M*sizeof(int));
    memset(critvar.data(),0,M*sizeof(int));
    memset(brk.data(),0,(N+1)*sizeof(int));
    nf=0;
    for(int c=0;c<M;c++){fidx[c]=-1;int s=co[c],l=cl2[c],cnt=0,cv=0;
    for(int j=0;j<l;j++)if(lt(cd[s+j])){cnt++;cv=abs(cd[s+j]);}
    ntrue[c]=cnt;if(cnt==0)af(c);else if(cnt==1){critvar[c]=cv;brk[cv]++;}}
}

static bool verify(){
    for(int c=0;c<M;c++){int s=co[c],l=cl2[c];bool sat=false;
    for(int j=0;j<l;j++)if(lt(cd[s+j])){sat=true;break;}if(!sat)return false;}
    return true;
}
static void printSAT(){printf("s SATISFIABLE\nv ");for(int v=1;v<=N;v++)printf("%d ",asgn[v]?v:-v);printf("0\n");}

// ============================================================
// CDCL with clause minimization for hgen8 UNSAT
// ============================================================
static int luby(int i){int k=1;while((1<<k)<=i+1)k++;if(i+1==(1<<(k-1)))return 1<<(k-2);return luby(i-(1<<(k-1))+1);}

static int solveCDCL(const char* proofPath) {
    int nv = N;
    struct CInfo { int start,sz,lbd; float act; bool learned,del; int proof_id; };
    vector<int> litpool;
    vector<CInfo> clauses;
    litpool.reserve(M*4+500000);
    clauses.reserve(M+500000);
    struct BinImp { int lit,cid; };
    int maxLit = 2*nv+2;
    vector<vector<BinImp>> binImp(maxLit);
    struct Watch { int cid,blocker; };
    vector<vector<Watch>> watches(maxLit);
    auto litIdx = [](int lit) -> int { return lit>0?2*lit:2*(-lit)+1; };
    vector<int8_t> val(nv+1,0);
    vector<int> dlevel(nv+1,-1), reason_cl(nv+1,-1), trail, trail_lim;
    trail.reserve(nv);
    int qhead=0, curLevel=0;
    auto litVal = [&](int lit) -> int { int v=abs(lit); if(val[v]==0)return 0; return(lit>0)?(int)val[v]:-(int)val[v]; };
    auto assignLit = [&](int lit,int level,int rsn){ int v=abs(lit); val[v]=(lit>0)?1:-1; dlevel[v]=level; reason_cl[v]=rsn; trail.push_back(lit); };
    auto addClause = [&](int* lits,int sz,bool learned,int lbd) -> int {
        int cid=(int)clauses.size(); int start=(int)litpool.size();
        for(int i=0;i<sz;i++) litpool.push_back(lits[i]);
        clauses.push_back({start,sz,lbd,0.0f,learned,false,0});
        if(sz==2){ binImp[litIdx(lits[0])].push_back({lits[1],cid}); binImp[litIdx(lits[1])].push_back({lits[0],cid}); }
        else if(sz>=3){ watches[litIdx(lits[0])].push_back({cid,lits[1]}); watches[litIdx(lits[1])].push_back({cid,lits[0]}); }
        return cid;
    };
    vector<int> unit_clauses;
    for(int c=0;c<M;c++){
        int s=co[c],len=cl2[c];
        if(len==0){ FILE* pf=fopen(proofPath,"w"); fprintf(pf,"pseudo-Boolean proof version 3.0\nrup >= 1 ;\noutput NONE ;\nconclusion UNSAT : -1 ;\nend pseudo-Boolean proof ;\n"); fclose(pf); return 1; }
        if(len==1) unit_clauses.push_back(c);
        addClause(&cd[s],len,false,0);
    }
    for(int uc:unit_clauses){
        int lit=litpool[clauses[uc].start];
        if(litVal(lit)==0) assignLit(lit,0,uc);
        else if(litVal(lit)==-1){ FILE* pf=fopen(proofPath,"w"); fprintf(pf,"pseudo-Boolean proof version 3.0\nrup >= 1 ;\noutput NONE ;\nconclusion UNSAT : -1 ;\nend pseudo-Boolean proof ;\n"); fclose(pf); return 1; }
    }
    auto propagate = [&]() -> int {
        while(qhead<(int)trail.size()){
            int p=trail[qhead++]; int fIdx=litIdx(-p);
            for(auto& bi:binImp[fIdx]){ int vq=litVal(bi.lit); if(vq==1)continue; if(vq==-1)return bi.cid; assignLit(bi.lit,curLevel,bi.cid); }
            auto& ws=watches[fIdx]; int j=0;
            for(int i=0;i<(int)ws.size();i++){
                int cid=ws[i].cid; if(clauses[cid].del)continue;
                if(litVal(ws[i].blocker)==1){ws[j++]=ws[i];continue;}
                CInfo& ci=clauses[cid]; int* lits=&litpool[ci.start]; int sz=ci.sz;
                if(lits[1]==-p) swap(lits[0],lits[1]);
                if(litVal(lits[1])==1){ws[j]=ws[i];ws[j].blocker=lits[1];j++;continue;}
                bool found=false;
                for(int k=2;k<sz;k++){ if(litVal(lits[k])!=-1){swap(lits[0],lits[k]);watches[litIdx(lits[0])].push_back({cid,lits[1]});found=true;break;} }
                if(found)continue;
                ws[j++]=ws[i];
                if(litVal(lits[1])==-1){while(++i<(int)ws.size())ws[j++]=ws[i];ws.resize(j);return cid;}
                assignLit(lits[1],curLevel,cid);
            }
            ws.resize(j);
        }
        return -1;
    };
    // VSIDS
    vector<double> act(nv+1,0.0); double varInc=1.0;
    vector<int> heap,heap_pos(nv+1,-1);
    auto hCmp=[&](int a,int b){return act[a]>act[b];};
    auto hUp=[&](int pos){int v=heap[pos];while(pos>0){int p2=(pos-1)/2;if(hCmp(v,heap[p2])){heap[pos]=heap[p2];heap_pos[heap[p2]]=pos;pos=p2;}else break;}heap[pos]=v;heap_pos[v]=pos;};
    auto hDown=[&](int pos){int v=heap[pos];int sz=(int)heap.size();while(true){int ch=2*pos+1;if(ch>=sz)break;if(ch+1<sz&&hCmp(heap[ch+1],heap[ch]))ch++;if(hCmp(heap[ch],v)){heap[pos]=heap[ch];heap_pos[heap[ch]]=pos;pos=ch;}else break;}heap[pos]=v;heap_pos[v]=pos;};
    auto hIns=[&](int v){if(heap_pos[v]>=0)return;heap_pos[v]=(int)heap.size();heap.push_back(v);hUp((int)heap.size()-1);};
    auto hPop=[&]()->int{int v=heap[0];heap_pos[v]=-1;if(heap.size()>1){heap[0]=heap.back();heap_pos[heap[0]]=0;heap.pop_back();hDown(0);}else heap.pop_back();return v;};
    auto hUpd=[&](int v){if(heap_pos[v]>=0)hUp(heap_pos[v]);};
    for(int v=1;v<=nv;v++){act[v]=(double)(posOcc[v].size()+negOcc[v].size());heap.push_back(v);heap_pos[v]=v-1;}
    for(int i=(int)heap.size()/2;i>=0;i--)hDown(i);
    vector<int> phase(nv+1,0);for(int v=1;v<=nv;v++)phase[v]=v;
    auto pickBranch=[&]()->int{while(!heap.empty()){int v=hPop();if(val[v]==0)return v;}return 0;};
    vector<bool> seen(nv+1,false);
    
    // Clause minimization helpers
    enum MinResult : uint8_t { MIN_UNDEF=0, MIN_REMOVABLE=1, MIN_NOT_REMOVABLE=2 };
    vector<MinResult> minCache(nv+1, MIN_UNDEF);
    vector<int> minStack;
    
    // Iterative DFS to check if literal can be removed from learned clause
    struct MinFrame { int var; int ci; int pos; };
    vector<MinFrame> minDFS;
    auto litRemovable = [&](int lit, vector<bool>& inLearnt) -> bool {
        int startV = abs(lit);
        if(minCache[startV] != MIN_UNDEF) return minCache[startV] == MIN_REMOVABLE;
        minDFS.clear();
        // Quick check for start variable
        {
            int rc = reason_cl[startV];
            if(rc < 0) { minCache[startV] = MIN_NOT_REMOVABLE; return false; }
            if(dlevel[startV] == 0) { minCache[startV] = MIN_REMOVABLE; return true; }
            minDFS.push_back({startV, rc, 0});
        }
        vector<int> visited; // track vars we visited for rollback on failure
        visited.push_back(startV);
        while(!minDFS.empty()){
            auto& fr = minDFS.back();
            CInfo& ci2 = clauses[fr.ci];
            int* ls = &litpool[ci2.start]; int sz2 = ci2.sz;
            bool expanded = false;
            while(fr.pos < sz2){
                int u = abs(ls[fr.pos]);
                fr.pos++;
                if(u == fr.var) continue;
                if(dlevel[u] == 0) continue;
                if(inLearnt[u]) continue;
                if(minCache[u] == MIN_REMOVABLE) continue;
                if(minCache[u] == MIN_NOT_REMOVABLE) {
                    // Fail: mark everything on stack as not removable
                    for(int vv : visited) minCache[vv] = MIN_NOT_REMOVABLE;
                    return false;
                }
                // MIN_UNDEF: need to explore
                int rc2 = reason_cl[u];
                if(rc2 < 0) {
                    for(int vv : visited) minCache[vv] = MIN_NOT_REMOVABLE;
                    return false;
                }
                if(dlevel[u] == 0) { minCache[u] = MIN_REMOVABLE; continue; }
                visited.push_back(u);
                minDFS.push_back({u, rc2, 0});
                expanded = true;
                break;
            }
            if(!expanded){
                // All children OK => this var is removable
                minCache[fr.var] = MIN_REMOVABLE;
                minDFS.pop_back();
            }
        }
        return minCache[startV] == MIN_REMOVABLE;
    };
    
    auto computeLBD=[&](vector<int>&lits)->int{vector<bool>levels(curLevel+1,false);int lbd=0;for(int l:lits){int lev=dlevel[abs(l)];if(lev>=0&&lev<(int)levels.size()&&!levels[lev]){levels[lev]=true;lbd++;}}return lbd;};

    auto analyze=[&](int confl,vector<int>&learnt,int&btLevel){
        fill(seen.begin(),seen.end(),false);learnt.clear();learnt.push_back(0);
        int counter=0,p=0,c=confl,idx=(int)trail.size()-1;
        do{
            CInfo&ci=clauses[c];int*lits=&litpool[ci.start];int sz=ci.sz;
            if(ci.learned)ci.act+=1.0f;
            for(int i=0;i<sz;i++){int lit=lits[i];int v=abs(lit);if(p!=0&&v==abs(p))continue;if(seen[v])continue;seen[v]=true;act[v]+=varInc;hUpd(v);if(dlevel[v]==curLevel)counter++;else if(dlevel[v]>0)learnt.push_back(lit);}
            while(idx>=0&&!seen[abs(trail[idx])])idx--;p=trail[idx];c=reason_cl[abs(p)];seen[abs(p)]=false;counter--;idx--;
        }while(counter>0);
        learnt[0]=-p;
        
        // Clause minimization: try to remove each literal (except asserting lit at [0])
        vector<bool> inLearnt(nv+1, false);
        for(int l : learnt) inLearnt[abs(l)] = true;
        // Reset minCache for vars in learnt
        for(int l : learnt) minCache[abs(l)] = MIN_UNDEF;
        // Also reset for vars at current level that were seen
        for(int i=0;i<=nv;i++) minCache[i] = MIN_UNDEF;
        
        int j = 1;
        for(int i=1;i<(int)learnt.size();i++){
            if(litRemovable(learnt[i], inLearnt)){
                inLearnt[abs(learnt[i])] = false; // removed
            } else {
                learnt[j++] = learnt[i];
            }
        }
        learnt.resize(j);
        
        btLevel=0;
        for(int i=1;i<(int)learnt.size();i++){int lev=dlevel[abs(learnt[i])];if(lev>btLevel)btLevel=lev;}
    };

    auto backtrackTo=[&](int level){
        int target=(level<(int)trail_lim.size())?trail_lim[level]:(int)trail.size();
        while((int)trail.size()>target){int lit=trail.back();trail.pop_back();int v=abs(lit);phase[v]=lit;val[v]=0;dlevel[v]=-1;reason_cl[v]=-1;hIns(v);}
        qhead=(int)trail.size();trail_lim.resize(level);curLevel=level;
    };
    FILE* pf=fopen(proofPath,"w");if(!pf)return -1;
    static char pbuf[1<<20];setvbuf(pf,pbuf,_IOFBF,sizeof(pbuf));
    fprintf(pf,"pseudo-Boolean proof version 3.0\n");
    int next_proof_id=M+1;
    // Write the UNMINIMIZED clause for proof (RUP requires the original first-UIP clause)
    // But minimized clause is also RUP-provable, so we write the minimized version
    auto writeRUP=[&](vector<int>&lits)->int{fprintf(pf,"rup ");for(int l:lits){if(l>0)fprintf(pf,"1 x%d ",l);else fprintf(pf,"1 ~x%d ",-l);}fprintf(pf,">= 1 ;\n");return next_proof_id++;};
    auto writeEmpty=[&](){fprintf(pf,"rup >= 1 ;\n");next_proof_id++;};
    auto writeDel=[&](int pid){fprintf(pf,"del id %d ;\n",pid);};
    int numLearned=0,maxLearned=4000;
    size_t maxLitpool = 100000000; // ~400MB limit on litpool
    auto reduceLearned=[&](){
        vector<bool> isR(clauses.size(),false);
        for(int j=0;j<(int)trail.size();j++){int rc=reason_cl[abs(trail[j])];if(rc>=0)isR[rc]=true;}
        vector<int> cands;
        for(int i=M;i<(int)clauses.size();i++){if(!clauses[i].del&&clauses[i].learned&&clauses[i].sz>2&&!isR[i])cands.push_back(i);}
        sort(cands.begin(),cands.end(),[&](int a,int b){if(clauses[a].lbd!=clauses[b].lbd)return clauses[a].lbd<clauses[b].lbd;return clauses[a].act>clauses[b].act;});
        int keep=(int)cands.size()/2;
        for(int i=keep;i<(int)cands.size();i++){clauses[cands[i]].del=true;if(clauses[cands[i]].proof_id>0)writeDel(clauses[cands[i]].proof_id);numLearned--;}
    };
    int confl=propagate();
    if(confl>=0){writeEmpty();fprintf(pf,"output NONE ;\nconclusion UNSAT : -1 ;\nend pseudo-Boolean proof ;\n");fclose(pf);return 1;}
    long long conflicts=0;int restartCounter=0,restartPhase=0,nextRestart=128;
    vector<int> learnt;
    while(true){
        if(__builtin_expect((conflicts&0xFF)==0,0)){
            if(el()>TLIM-5){fclose(pf);return -1;}
            if(litpool.size()>maxLitpool){fclose(pf);return -1;} // memory guard
        }
        int v=pickBranch();
        if(v==0){for(int i=1;i<=nv;i++)asgn[i]=(val[i]==1)?1:0;fclose(pf);return 0;}
        curLevel++;trail_lim.push_back((int)trail.size());
        assignLit(phase[v],curLevel,-1);
        confl=propagate();
        while(confl>=0){
            conflicts++;
            if(curLevel==0){writeEmpty();fprintf(pf,"output NONE ;\nconclusion UNSAT : -1 ;\nend pseudo-Boolean proof ;\n");fclose(pf);fprintf(stderr,"c CDCL: UNSAT %lld conflicts (%.1fs)\n",conflicts,el());return 1;}
            int btLevel;analyze(confl,learnt,btLevel);
            int lbd=computeLBD(learnt);int pid=writeRUP(learnt);
            varInc*=(1.0/0.95);if(varInc>1e100){for(int i=1;i<=nv;i++)act[i]*=1e-100;varInc*=1e-100;}
            backtrackTo(btLevel);
            if((int)learnt.size()==1){assignLit(learnt[0],0,-1);}
            else{int best=1;for(int i=2;i<(int)learnt.size();i++)if(dlevel[abs(learnt[i])]>dlevel[abs(learnt[best])])best=i;if(best!=1)swap(learnt[1],learnt[best]);int cid=addClause(learnt.data(),(int)learnt.size(),true,lbd);clauses[cid].proof_id=pid;clauses[cid].act=1.0f;numLearned++;assignLit(learnt[0],curLevel,cid);}
            restartCounter++;
            if(restartCounter>=nextRestart){restartCounter=0;restartPhase++;nextRestart=128*luby(restartPhase);backtrackTo(0);if(numLearned>maxLearned)reduceLearned();break;}
            confl=propagate();
        }
    }
}

static int solve2SAT(){
    int n2=2*N;int bc=0;for(int c=0;c<M;c++)if(cl2[c]==2)bc++;if(!bc)return -1;
    vector<vector<int>>adj(n2);
    auto idx=[](int l)->int{return l>0?2*(l-1):2*(-l-1)+1;};
    for(int c=0;c<M;c++){if(cl2[c]!=2)continue;int aa=cd[co[c]],b=cd[co[c]+1];adj[idx(-aa)].push_back(idx(b));adj[idx(-b)].push_back(idx(aa));}
    vector<int>disc(n2,0),low(n2,0),scc(n2,-1);vector<bool>onS(n2,false);vector<int>stk;
    int timer=0,nscc=0;struct Fr{int u,ei;};
    for(int st=0;st<n2;st++){if(disc[st])continue;vector<Fr>cs;disc[st]=low[st]=++timer;stk.push_back(st);onS[st]=true;cs.push_back({st,0});
    while(!cs.empty()){auto&[u,ei]=cs.back();if(ei<(int)adj[u].size()){int v=adj[u][ei++];if(!disc[v]){disc[v]=low[v]=++timer;stk.push_back(v);onS[v]=true;cs.push_back({v,0});}else if(onS[v])low[u]=min(low[u],disc[v]);}
    else{if(low[u]==disc[u]){while(true){int w=stk.back();stk.pop_back();onS[w]=false;scc[w]=nscc;if(w==u)break;}nscc++;}cs.pop_back();if(!cs.empty())low[cs.back().u]=min(low[cs.back().u],low[u]);}}}
    for(int v=0;v<N;v++)if(scc[2*v]==scc[2*v+1])return 0;
    for(int v=0;v<N;v++)asgn[v+1]=(scc[2*v]<scc[2*v+1])?1:0;
    return 1;
}

int main(int argc,char**argv){
    if(argc!=3)return 1;
    T0=chrono::steady_clock::now();
    parse(argv[1]);
    fprintf(stderr,"c %d vars %d cls\n",N,M);
    int sc[10]={};for(int c=0;c<M;c++){int k=min(cl2[c],9);sc[k]++;}
    asgn.resize(N+1);ntrue.resize(M);critvar.resize(M);brk.resize(N+1);
    flist=new int[M];fidx=new int[M];
    initST();
    bool u3=(sc[3]==M);
    bool mb=(sc[2]>M/2);

    if(mb){
        fprintf(stderr,"c hgen8 detected\n");
        int r=solve2SAT();
        if(r==1&&verify()){printSAT();return 10;}
        fprintf(stderr,"c Running CDCL...\n");
        int result=solveCDCL(argv[2]);
        fprintf(stderr,"c CDCL returned %d (%.1fs)\n",result,el());
        if(result==1){printf("s UNSATISFIABLE\n");return 20;}
        if(result==0&&verify()){printSAT();return 10;}
        printf("s UNKNOWN\n");return 0;
    }

    long long baseFlips=max(5000000LL,(long long)N*N*20LL);
    baseFlips=min(baseFlips,200000000LL);
    fprintf(stderr,"c SLS u3=%d flips=%lldM\n",u3,baseFlips/1000000);

    vector<int> bestAsgn(N+1,0);
    int bestFalse=M+1;
    vector<int> cweight(M,1);
    int maxWeight=1;
    int smoothPeriod=max(1,N/2);
    int localMinSteps=0;

    // Portfolio: cb=3.7 (70%), 2.5 (10%), 4.5 (10%), 2.85 (10%)
    double* stTables[]={st37,st37,st37,st37,st37,st37,st37,st25,sthi,st4};
    int nTables=10;

    for(int restart=0;;restart++){
        if(el()>TLIM)break;
        _seed((uint64_t)restart*999999937ULL+42);

        // Restart strategy: alternate random and best+noise
        if(restart>1 && restart%2==0 && bestFalse<M){
            for(int v=1;v<=N;v++) asgn[v]=bestAsgn[v];
            int noiseP = 5 + _ri(16); // 5-20% noise
            for(int v=1;v<=N;v++) if(_ri(100)<noiseP) asgn[v]^=1;
            initFromAssign();
        } else {
            initAssign();
        }

        fill(cweight.begin(),cweight.end(),1);
        maxWeight=1; localMinSteps=0;
        double* curST=stTables[restart%nTables];

        for(long long t=0;t<baseFlips;t++){
            if(nf==0){if(verify()){fprintf(stderr,"c SOLVED R%d (%.1fs)\n",restart,el());printSAT();return 10;}break;}
            if(__builtin_expect((t&0xFFFF)==0,0)){if(el()>TLIM)goto done;}

            if(nf<bestFalse){bestFalse=nf;for(int v=1;v<=N;v++)bestAsgn[v]=asgn[v];}

            int c;
            if(maxWeight>1 && _ri(4)==0){
                int bestC=flist[0],bestW=cweight[flist[0]];
                int sample=min(nf,8);
                for(int i=1;i<sample;i++){int ci=flist[_ri(nf)];if(cweight[ci]>bestW){bestC=ci;bestW=cweight[ci];}}
                c=bestC;
            } else {
                c=flist[_ri(nf)];
            }

            int prevNf=nf;
            if(u3) flip(ps3(c,curST));
            else flip(psG(c,curST));

            if(nf>=prevNf){
                localMinSteps++;
                if(localMinSteps%smoothPeriod==0){
                    for(int i=0;i<nf;i++){int ci=flist[i];if(cweight[ci]>1)cweight[ci]--;}
                    maxWeight=max(1,maxWeight-1);
                } else if(_ri(3)==0){
                    for(int i=0;i<nf;i++){cweight[flist[i]]++;if(cweight[flist[i]]>maxWeight)maxWeight=cweight[flist[i]];}
                }
            }
        }
        if(restart<10||restart%200==0)
            fprintf(stderr,"c R%d: %d false best=%d (%.1fs)\n",restart,nf,bestFalse,el());
    }
    done:
    printf("s UNKNOWN\n");return 0;
}
