#include #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define per(i,a,b) for(int i=(a);i>=(b);i--) #define REP(i,n) for(int i=0;i<(n);i++) #define fi first #define se second #define pb push_back #define mp make_pair using namespace std; typedef pair pii; typedef vector vi; typedef long long ll; template void read(T &x){ int f=0; x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) f|=(ch=='-'); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; if(f) x=-x; } const int N=1000005,M=N*3,inf=1e9+99; namespace G{ //注意只支持非负边权,否则需要spfa预处理 #define real d[u]+f[u]-f[t.v] struct edge{int u,v,w,f,c,p;};vectore[N]; int d[N],f[N],s,t,n,m; inline void init(int _n,int _s=0,int _t=0){ rep(i,1,n) e[i].clear(); n=_n,s=(_s?_s:1),t=(_t?_t:n),m=0; } inline void add(int u,int v,int c,int w){ e[u].pb((edge){u,v,w,0,c,(int)e[v].size()}); e[v].pb((edge){v,u,-w,0,0,(int)e[u].size()-1}); } struct node{ int d,v; friend bool operator < (const node &a,const node &b){ return a.d>b.d; } };priority_queueQ; bool dij(){ rep(i,1,n){ f[i]=min(f[i]+d[i],inf); d[i]=i==s?0:inf; } Q.push((node){0,s}); while(!Q.empty()){ int t=Q.top().d,u=Q.top().v; Q.pop();if(t>d[u])continue; REP(k,e[u].size()){ edge &t=e[u][k]; if(t.f id; string st; const int E[6][3]={ {0,1,2}, {0,2,1}, {1,0,2}, {1,2,0}, {2,0,1}, {2,1,0} }; void rmain(){ read(n); id["012"]=1; id["021"]=2; id["102"]=3; id["120"]=4; id["201"]=5; id["210"]=6; fill(cc,cc+7,0); int cnt=7; REP(i,3){ P[i]=++cnt; read(c[i]); } rep(i,1,n){ cin>>st; cc[id[st]]++; } S=++cnt,T=++cnt; G::init(cnt,S,T); rep(i,1,6){ G::add(S,i,cc[i],0); REP(j,3){ G::add(i,P[E[i-1][j]],inf,j); } } REP(j,3){ G::add(P[j],T,c[j],0); } int flow=0,cost=0; G::mcmf(flow,cost); printf("%d\n",n*3-cost); } int main(){ int T; read(T); while(T--) rmain(); return 0; }