#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define pb push_back #define all(a) a.begin(),a.end() #define pointtype double #define pointtype_INT 0 using namespace std; using namespace tr1; typedef long long LL; typedef pairpii; typedef unsigned uint; typedef unsigned long long uLL; const double pi=acos(-1); template void Read(T &x){ char c; bool f(0); while(c=getchar(),c!=EOF){ if(c=='-') f=1; else if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); if(f) x=-x; return; } } } struct point{ pointtype x,y; inline point(){ } inline point(pointtype x,pointtype y=0):x(x),y(y){ } inline point operator+(const point &a)const{ return point(x+a.x,y+a.y); } inline point operator+=(const point &a){ return *this=*this+a; } inline point operator-(const point &a)const{ return point(x-a.x,y-a.y); } inline point operator-=(const point &a){ return *this=*this-a; } inline bool operator<(const point &b)const{ if(x==b.x) return y struct hashnode{ T val; T2 v; hashnode *next; }; template inline int& addhash(int u,const T &val,T2 *&ecnt,T2 **adj){ T2 *p=++ecnt; p->val=val; p->v=0; p->next=adj[u]; adj[u]=p; return p->v; } template class hash_table{ hashnode*adj[MOD],edge[ss+10],*ecnt; int sz; public: inline int Get_val(int x){ return x%MOD; } #if pointtype_INT==1 inline int Get_val(point x){ return (x.x*998244353ll+x.y)%MOD; } #endif inline hash_table():ecnt(edge),sz(0){ for(int i=0;i* hash(const T &x){ int t=Get_val(x); for(hashnode *p=adj[t];p;p=p->next) if(p->val==x) return p; return 0; } inline int &operator[](const T &x){ hashnode *p=hash(x); if(p) return p->v; return ++sz,addhash(Get_val(x)%MOD,x,ecnt,adj); } inline bool count(const T &x){ return hash(x); } inline void clear(){ ecnt=edge; int t=MOD>>2<<2,i; for(i=0;i struct Matrix{ int a[sz][sz]; inline Matrix(){ memset(a,0,sizeof a); } inline Matrix(int){ memset(a,0,sizeof a); for(int i=0;i>=1; } return ret; } }; struct cpx{ double r,i; inline cpx(){ } inline cpx(double r,double i=0):r(r),i(i){ } inline cpx operator+(const cpx &a)const{ return cpx(r+a.r,i+a.i); } inline cpx operator-(const cpx &a)const{ return cpx(r-a.r,i-a.i); } inline cpx operator*(const cpx &a)const{ return cpx(r*a.r-i*a.i,r*a.i+i*a.r); } inline cpx operator/(const double &a)const{ return cpx(r/a,i/a); } inline cpx operator/(const cpx&a)const{ return *this*cpx(a.r,-a.i)/(a.r*a.r+a.i*a.i); } inline cpx operator+=(const cpx &a){ return *this=*this+a; } inline cpx operator-=(const cpx &a){ return *this=*this-a; } inline cpx operator*=(const cpx &a){ return *this=*this*a; } inline cpx operator/=(const cpx &a){ return *this=*this/a; } inline cpx conj(){ return cpx(r,-i); } }; template struct polynomial{ T a[len]; inline void clear(){ int t=len>>2<<2,i; for(i=0;i>2<<2,i; for(i=0;i>2<<2,i; for(i=0;i>=1,~j&t;); if(i,class cmp=std::less > struct priority_queue{ std::priority_queueins,del; inline void push(T a){ ins.push(a); } inline void erase(T a){ del.push(a); } inline void pop(){ while(!del.empty()&&ins.top()==del.top()) ins.pop(),del.pop(); ins.pop(); } inline T top(){ while(!del.empty()&&ins.top()==del.top()) ins.pop(),del.pop(); return ins.top(); } inline T second_top(){ T tmp=top(),ret; pop(); ret=top(); push(tmp); return ret; } inline void clear(){ while(!ins.empty()) ins.pop(); while(!del.empty()) del.pop(); } inline int size(){ return ins.size()-del.size(); } inline bool empty(){ return !size(); } }; } void exgcd(long long a,long long b,long long &d,long long &x,long long &y){ if(!b){ d=a; x=1; y=0; return; } exgcd(b,a%b,d,y,x); y-=a/b*x; } //template #define MAXN 100 #define INF 0x3fffffff int cases; mapp; int n,a,b,c,cnt[7],S,T; int tot,dist[MAXN+10]; queueq; bool vis[MAXN+10]; struct node{ int v,wt,cap; node *next,*back; }*adj[MAXN+10],edge[MAXN*MAXN+10],*ecnt,*pre[MAXN+10]; inline void addedge(int u,int v,int cap,int wt){ node *p=++ecnt; p->v=v; p->wt=wt; p->cap=cap; p->next=adj[u]; adj[u]=p; p=p->back=++ecnt; p->v=u; p->cap=0; p->wt=-wt; p->next=adj[v]; adj[v]=p; p->back=ecnt-1; } bool spfa(){ int u; int i; for(i=1;i<=tot;i++) dist[i]=-INF; dist[S]=0; q.push(S); while(!q.empty()){ u=q.front(); q.pop(); vis[u]=0; for(node *p=adj[u];p;p=p->next){ if(p->cap&&dist[p->v]wt){ pre[p->v]=p; dist[p->v]=dist[u]+p->wt; if(!vis[p->v]) vis[p->v]=1,q.push(p->v); } } } return dist[T]!=-INF; } int mcmf(){ int cost=0,delta; node *p; while(spfa()){ delta=INF; for(p=pre[T];p;p=pre[p->back->v]) delta=min(delta,p->cap); for(p=pre[T];p;p=pre[p->back->v]){ p->cap-=delta; p->back->cap+=delta; } cost+=dist[T]*delta; } return cost; } int main() { Read(cases); p["012"]=1; p["021"]=2; p["102"]=3; p["120"]=4; p["201"]=5; p["210"]=6; while(cases--){ Read(n),Read(a),Read(b),Read(c); string s; char t[5]; int i; memset(cnt,0,sizeof cnt); for(i=1;i<=n;i++){ scanf("%s",t); s=t; cnt[p[s]]++; } ecnt=edge; memset(adj,0,sizeof adj); S=10,T=11; addedge(S,7,a,0); addedge(S,8,b,0); addedge(S,9,c,0); for(auto x:p){ s=x.first; int pos=x.second; for(i=0;i<3;i++) addedge(7+s[i]-'0',pos,n,3-i); addedge(pos,T,cnt[pos],0); } tot=11; int ans=0; ans=mcmf(); printf("%d\n",ans); } }