1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
   | #include<bits/stdc++.h> using namespace std;
  typedef long long ll; typedef double db; typedef unsigned long long ull; typedef pair <int,int> Pii; #define reg register #define pb push_back #define mp make_pair #define Mod1(x) ((x>=P)&&(x-=P)) #define Mod2(x) ((x<0)&&(x+=P)) #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); } template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
  char IO; template <class T=int> T rd(){ 	T s=0; int f=0; 	while(!isdigit(IO=getchar())) if(IO=='-') f=1; 	do s=(s<<1)+(s<<3)+(IO^'0'); 	while(isdigit(IO=getchar())); 	return f?-s:s; }
  const int N=1e5+10,INF=1e9+10;
  int n,m,S,T; char s[N]; struct Edge{ 	int to,nxt,w; }e[N<<1]; int head[N],ecnt=1; void AddEdge(int u,int v,int w) { 	e[++ecnt]=(Edge){v,head[u],w}; 	head[u]=ecnt; } void Link(int u,int v,int w){  	AddEdge(u,v,w),AddEdge(v,u,0); }
  int F[N],X[N],Y[N],col[N],A[N];
  int Find(int x){  	if(F[x]==x) return x; 	int f=F[x]; F[x]=Find(F[x]); 	col[x]^=col[f]; 	return F[x]; }
  int dis[N]; int Bfs() { 	rep(i,1,T) dis[i]=INF; 	static queue <int> que; 	dis[S]=0; que.push(S); 	while(!que.empty()) { 		int u=que.front(); que.pop(); 		for(int i=head[u];i;i=e[i].nxt) { 			int v=e[i].to,w=e[i].w; 			if(!w || dis[v]<=dis[u]+1) continue; 			dis[v]=dis[u]+1,que.push(v); 		} 	} 	return dis[T]<INF; }
  int Dfs(int u,int in) { 	if(u==T) return in; 	int out=0; 	for(int i=head[u];i;i=e[i].nxt) { 		int v=e[i].to,w=e[i].w; 		if(!w || dis[v]!=dis[u]+1) continue; 		int t=Dfs(v,min(in-out,w)); 		e[i].w-=t,e[i^1].w+=t,out+=t; 		if(in==out) break; 	} 	if(!out) dis[u]=0; 	return out; }
  int Dinic() { 	int ans=0;  	while(Bfs()) ans+=Dfs(S,INF); 	return ans; }
 
  int main() { 	rep(kase,1,rd()) { 		n=rd(),m=rd(); 		rep(i,1,n) F[i]=i,col[i]=0; 		scanf("%s",s+1); 		S=n+1,T=n+2; 		rep(i,1,n) A[i]=rd(); 		rep(i,1,m) { 			X[i]=rd(),Y[i]=rd(); 			int x=abs(X[i]),y=abs(Y[i]); 			int u=Find(x),v=Find(y); 			if(u==v) continue; 			F[u]=v,col[u]=col[x]^col[y]^(X[i]<0)^(Y[i]<0)^1; 		} 		rep(i,1,n) Find(i); 		rep(i,1,n) { 			if(col[i]^s[i]^'0') Link(S,i,A[i]); 			else Link(i,T,A[i]); 		} 		rep(i,1,m) { 			int t=col[abs(X[i])]^(X[i]<0); 			assert(col[abs(X[i])]^col[abs(Y[i])]^(X[i]<0)^(Y[i]<0)); 			if(t) Link(abs(X[i]),abs(Y[i]),INF); 			else Link(abs(Y[i]),abs(X[i]),INF); 		} 		printf("%d\n",Dinic()); 		rep(i,1,T) head[i]=0; ecnt=1; 	} }
   |