#!/usr/bin/env python3
import lzma, sys, itertools, os

def parse(path):
    lines=lzma.open(path,'rt').read().splitlines()
    clauses=[]; nv=0
    for line in lines:
        if line.startswith('p '): nv=int(line.split()[2]); continue
        if not line or line[0] in 'c%': continue
        clauses.append(tuple(map(int,line.split()[:-1])))
    return nv,clauses

def detect_n(clauses):
    C=set(clauses); best=0
    for cand in range(1,200):
        if all((-(cand+i),i) in C and (cand+i,-i) in C for i in range(1,cand+1)):
            best=cand
    return best

def fanin(v,N,clauses,memo):
    if N < v <= 2*N: return {v-N}
    if v <= N: return set()
    if v in memo: return memo[v]
    s=set()
    for cl in clauses:
        if -v in cl:
            others=[x for x in cl if x!=-v]
            if all(x>0 and x<v for x in others):
                for x in others: s |= fanin(x,N,clauses,memo)
    memo[v]=s
    return s

def unit_eval(nv, clauses, assigns):
    val=[0]*(nv+1)
    q=[]
    def setlit(l):
        v=abs(l); b=1 if l>0 else -1
        if val[v]==-b: return False
        if val[v]==0: val[v]=b; q.append(l)
        return True
    for l in assigns:
        if not setlit(l): return None
    changed=True
    while changed:
        changed=False
        for cl in clauses:
            sat=False; un=0; last=0
            for l in cl:
                vv=val[abs(l)]
                if vv and ((l>0 and vv>0) or (l<0 and vv<0)):
                    sat=True; break
                if vv==0: un+=1; last=l
            if sat: continue
            if un==0: return None
            if un==1:
                if not setlit(last): return None
                changed=True
    return val

if __name__ == '__main__':
 for path in sys.argv[1:]:
    nv,clauses=parse(path); N=detect_n(clauses); memo={}
    print('\n',os.path.basename(path),'N',N)
    maxd=0; rows=[]
    for j in range(1,N+1):
        a=2*N+j; seed=j; triggers=[]
        for cl in clauses:
            if -a in cl and seed in cl:
                for x in cl:
                    if x not in (-a,seed) and x>0: triggers.append(x)
                break
        parents=set()
        for tr in triggers: parents |= fanin(tr,N,clauses,memo)
        parents=sorted(parents); maxd=max(maxd,len(parents))
        theta=None
        if not parents: theta=10**9
        else:
            for k in range(len(parents)+1):
                ass=[-seed]
                for p in parents: ass.append((N+p) if p in parents[:k] else -(N+p))
                local=[cl for cl in clauses if len(cl)>1 and max(abs(x) for x in cl) <= max(triggers+[a])]
                val=unit_eval(nv,local,ass)
                if val and val[a]>0:
                    theta=k; break
        rows.append((j,len(parents),theta,parents,triggers))
    keys=sorted(set(r[2] for r in rows), key=lambda x: -1 if x is None else x)
    print('maxd',maxd,'theta hist', {str(t):sum(1 for r in rows if r[2]==t) for t in keys})
    for r in rows[:20]: print(r[:4], 'trig', r[4])
