i 和 i+n 表示正反点
col 表示每个点最终的颜色,¬xj,xj,T,F,U 等
然后 dfs 边权 0/1 表示颜色相等/不相等
#include<bits/stdc++.h>
#define pt putchar(' ')
#define nl puts("")
#define pi pair<int,int>
#define pb push_back
#define go(it) for(auto &it:as[x])
using namespace std;
const int N=2e5+10;
int n,m,T,F,U;
int col[N],p[N],sz[N];
vector<pi> as[N];
int fr(){
int x=0,flag=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
return x*flag;
}
void fw(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) fw(x/10);
putchar(x%10+'0');
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int change(char c)
{
if(c=='T') return T;
if(c=='F') return F;
return U;
}
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
void merge(int x,int y)
{
int px=find(x),py=find(y);
if(px^py) p[px]=py,sz[py]+=sz[px];
}
int other(int x)
{
if(col[x]=='T') return F;
if(col[x]=='F') return T;
if(col[x]=='U') return U;
return (col[x]>=n)?(col[x]-n):(col[x]+n);
}
bool dfs(int x,int c)
{
col[x]=c;
go(it)
{
int v=it.first,w=it.second;
if(!~col[v] && !dfs(v,col[x]^w)) return 0;
else if(col[v]!=(col[x]^w)) return 0;
}
return 1;
}
void solve()
{
n=fr(),m=fr();
memset(col,0,sizeof col);
memset(p,0,sizeof p);
T=2*n+1,F=2*n+3,U=2*n+2;
for(int i=1;i<=(n<<1)+3;i++)
col[i]=p[i]=i,sz[i]=(i<=n);
while(m--)
{
char op[2];
scanf("%s",op);
if(op[0]=='+' || op[0]=='-')
{
int u=fr(),v=fr();
if(op[0]=='+') col[u]=col[v];
else col[u]=other(v);
}
else col[fr()]=change(op[0]);
}
for(int i=1;i<=n;i++)
{
if(col[i]>2*n) as[i].pb({col[i],0}),as[col[i]].pb({i,0}),merge(col[i],i);
else if(col[i]>n) as[i].pb({col[i]-n,1}),as[col[i]-n].pb({i,1}),merge(col[i]-n,i);
else as[i].pb({col[i],0}),as[col[i]].pb({i,0}),merge(col[i],i);
}
int ans=0;
memset(col,-1,sizeof col);
dfs(U,1),ans+=sz[find(U)];
for(int i=1;i<=2*n;i++)
if(find(i)!=find(U) && find(i)==i && !dfs(i,1))
ans+=sz[i];
fw(ans),nl;
}
int main()
{
int c=fr(),T=fr();
while(T--) solve();
return 0;
}