#!/usr/bin/env python3
import lzma, sys, collections, math

def read(path):
    f=lzma.open(path,'rt') if path.endswith('.xz') else open(path)
    n=0; cs=[]; cur=[]
    for line in f:
        if not line or line[0] in 'c%': continue
        if line[0]=='p': n=int(line.split()[2]); continue
        for t in line.split():
            l=int(t)
            if l==0:
                if cur: cs.append(tuple(cur)); cur=[]
            else: cur.append(l)
    return n,cs

def bits(v,w):
    if v<0: v=(1<<w)+v
    return [(v>>i)&1 for i in range(w)]

def build_occ(n,cs):
    occ=[[] for _ in range(2*n+1)]
    for ci,c in enumerate(cs):
        for l in c: occ[l+n].append(ci)
    return occ

def propagate(n,cs,occ,ass,trail,q):
    while q:
        lit=q.popleft(); v=abs(lit); val=lit>0
        old=ass[v]
        if old!=2 and old!=val: return False
        if old==2:
            ass[v]=val; trail.append(v)
        for ci in occ[-lit+n]:
            sat=False; un=0; last=0
            for l in cs[ci]:
                av=ass[abs(l)]
                if av==2: un+=1; last=l
                elif av==(l>0): sat=True; break
            if sat: continue
            if un==0: return False
            if un==1:
                v=abs(last); val=last>0; old=ass[v]
                if old!=2 and old!=val: return False
                if old==2: ass[v]=val; trail.append(v); q.append(last)
    return True

path=sys.argv[1]; vals=list(map(int,sys.argv[2:5]))
n,cs=read(path); w=len(cs[0]); occ=build_occ(n,cs); ass=[2]*(n+1); trail=[]; q=collections.deque()
for b,v in enumerate(vals):
    for i,bit in enumerate(bits(v,w)):
        var=b*w+i+1; lit=var if bit else -var; q.append(lit)
ok=propagate(n,cs,occ,ass,trail,q)
dec=0
for var in range(1,n+1):
    if ass[var]==2:
        # try false, then true if immediate conflict
        snap=len(trail); ass[var]=False; trail.append(var); q=collections.deque([-var])
        if not propagate(n,cs,occ,ass,trail,q):
            while len(trail)>snap: ass[trail.pop()]=2
            ass[var]=True; trail.append(var); q=collections.deque([var])
            if not propagate(n,cs,occ,ass,trail,q):
                ok=False; print('both fail',var); break
        dec+=1
bad=0
if ok:
    for c in cs:
        if not any(ass[abs(l)]==(l>0) for l in c): bad+=1; break
print('ok',ok,'dec',dec,'assigned',sum(1 for x in ass if x!=2),'bad',bad)
