#include #include #include #include #include using namespace std; #define MX (200 + 2) int read(){ char k = getchar(); int x = 0; while(k < '0' || k > '9') k = getchar(); while(k >= '0' && k <= '9') x = x * 10 + k - '0' ,k = getchar(); return x; } int head[MX] ,tot = 1; struct edge{ int node ,next ,w ,c; }h[MX]; void addedge(int u ,int v ,int w ,int c ,int flg = 1){ // if(flg)printf("%d->%d %d %d\n" ,u ,v ,w ,c); h[++tot] = (edge){v ,head[u] ,w ,c} ,head[u] = tot; if(flg) addedge(v ,u ,0 ,-c ,0); } int min(int a ,int b){return a < b ? a : b;} int S ,T; int pre[MX] ,flow[MX] ,dis[MX] ,inq[MX]; bool spfa(){ for(int i = 1 ; i <= T ; ++i) dis[i] = -13240621; flow[S] = 1045141919; pre[T] = 0 ,dis[S] = 0; queue q; q.push(S); while(!q.empty()){int x = q.front(); q.pop(); inq[x] = 0; //printf("%d\n" ,x); for(int i = head[x] ,d ; i ; i = h[i].next){ if(dis[d = h[i].node] < dis[x] + h[i].c && h[i].w){ pre[d] = i; dis[d] = dis[x] + h[i].c; flow[d] = min(flow[x] ,h[i].w); if(!inq[d]) q.push(d) ,inq[d] = 1; } } } return pre[T]; } void mcmf(){ int Ans = 0 ,flw = 0; while(spfa()){ Ans += dis[T] * flow[T]; flw += flow[T]; int x = T; while(x != S){ //printf("%d " ,x); h[pre[x]].w -= flow[T]; h[pre[x] ^ 1].w += flow[T]; x = h[pre[x] ^ 1].node; }//puts(""); } printf("%d\n" ,Ans); } int cnt[MX]; std::string s[] = {"012" ,"021" ,"102" ,"120" ,"201" ,"210"}; void solve(){ memset(head ,0 ,sizeof head) ,tot = 1; int n = read() ,a = read() ,b = read() ,c = read(); memset(cnt ,0 ,sizeof cnt); S = 10 ,T = 11; addedge(S ,7 ,a ,0); addedge(S ,8 ,b ,0); addedge(S ,9 ,c ,0); for(int i = 1 ; i <= n ; ++i){ string str; cin >> str; if(str == "012") ++cnt[1]; if(str == "021") ++cnt[2]; if(str == "102") ++cnt[3]; if(str == "120") ++cnt[4]; if(str == "201") ++cnt[5]; if(str == "210") ++cnt[6]; } for(int i = 0 ; i < 6 ; ++i){ for(int j = 0 ; j < 3 ; ++j){ addedge(7 + s[i][j] - '0' ,i + 1 ,114514 ,3 - j); } addedge(i + 1 ,T ,cnt[i + 1] ,0); } mcmf(); } int main(){ int T = read(); while(T--) solve(); return 0; }