#!/usr/bin/env python3
import sys,lzma,time,collections
class DSU:
 def __init__(self,n): self.p=list(range(n)); self.sz=[1]*n
 def find(self,x):
  while self.p[x]!=x:
   self.p[x]=self.p[self.p[x]]; x=self.p[x]
  return x
 def union(self,a,b):
  a=self.find(a); b=self.find(b)
  if a==b: return
  if self.sz[a]<self.sz[b]: a,b=b,a
  self.p[b]=a; self.sz[a]+=self.sz[b]

def op(p): return lzma.open(p,'rt') if p.endswith('.xz') else open(p)
for path in sys.argv[1:]:
 t=time.time(); n=0; rows=[]; bins=[]
 with op(path) as f:
  for line in f:
   if not line or line[0]=='c': continue
   if line[0]=='p': n=int(line.split()[2]); continue
   arr=[int(x) for x in line.split() if x!='0']
   if len(arr)==2: bins.append(tuple(arr))
   elif arr: rows.append(arr)
 sel=[0]*(n+1); rowof=[-1]*(n+1)
 for ri,r in enumerate(rows):
  for lit in r: sel[abs(lit)]=lit; rowof[abs(lit)]=ri
 dsu=DSU(n+1)
 for a,b in bins:
  va,vb=abs(a),abs(b)
  if rowof[va]!=rowof[vb]: dsu.union(va,vb)
 compmap={}; adj=[[] for _ in rows]
 for v in range(1,n+1):
  c=dsu.find(v); j=compmap.setdefault(c,len(compmap)); adj[rowof[v]].append(j)
 cols=len(compmap)
 # validate columns have at most one var per row and external clique edge count maybe skipped
 R=len(rows); pairU=[-1]*R; pairV=[-1]*cols; dist=[0]*R
 from collections import deque
 def bfs():
  q=deque(); found=False
  for u in range(R):
   if pairU[u]<0: dist[u]=0; q.append(u)
   else: dist[u]=-1
  while q:
   u=q.popleft()
   for v in adj[u]:
    pu=pairV[v]
    if pu<0: found=True
    elif dist[pu]<0: dist[pu]=dist[u]+1; q.append(pu)
  return found
 def dfs(u):
  for v in adj[u]:
   pu=pairV[v]
   if pu<0 or (dist[pu]==dist[u]+1 and dfs(pu)):
    pairU[u]=v; pairV[v]=u; return True
  dist[u]=-1; return False
 matching=0
 while bfs():
  for u in range(R):
   if pairU[u]<0 and dfs(u): matching+=1
 print(path.split('/')[-1], 'rows',R,'cols',cols,'vars',n,'match',matching,'SAT' if matching==R else 'UNSAT', 'deficit',R-matching,'time',round(time.time()-t,2), flush=True)
