#include using namespace std; typedef long long ll; typedef pair pii; typedef pair pil; typedef pair pli; typedef pairpll; const ll MOD = 1e9 + 7; const int MAXN = 1e5; ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } ll lcm(ll a, ll b) { return a / gcd(a, b) * b; } ll pow(ll a, ll b) { ll res = 1; while (b) { if (b & 1) res = res * a % MOD; a = a * a % MOD; b >>= 1; } return res; } struct unionset { int size; int fa[30000]; void clear(int jj) { for (int i = 0; i <= jj; i++) { fa[i] = i; } } int getfa(int x) { return fa[x] == x ? x : fa[x] = getfa(fa[x]); } bool merge(int a, int b) { int faa = getfa(a); int fbb = getfa(b); if (faa > fbb)swap(faa, fbb); if (faa != fbb) { fa[fbb] = faa; return true; } return false; } }; struct graph { const static int MAXN = 20000; static const int MAXM = 100000; static const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; }edge[MAXM]; int head[MAXN], tol; int pre[MAXN], dis[MAXN]; bool vis[MAXN]; int N;//节点总个数,节点编号从0~N-1 void init(int n) { N = n; tol = 0; memset(head,-1,sizeof(head));} void addedge(int u,int v,int cap,int cost) { edge[tol].to= v;edge[tol].cap= cap;edge[tol].cost= cost;edge[tol].flow= 0; edge[tol].next= head[u];head[u] = tol++;edge[tol].to= u;edge[tol].cap= 0; edge[tol].cost= -cost;edge[tol].flow= 0;edge[tol].next= head[v];head[v] = tol++; } bool spfa(int s,int t) { queueq; for(int i = 0;i < N;i++) {dis[i] = INF;vis[i] = false;pre[i] = -1;} dis[s] = 0;vis[s] = true;q.push(s); while(!q.empty()){ int u = q.front();q.pop(); vis[u] = false; for(int i = head[u]; i != -1;i = edge[i].next) {int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) { dis[v] = dis[u] + edge[i].cost; pre[v] = i; if (!vis[v]) { vis[v] = true; q.push(v); } } } }if (pre[t] == -1)return false; else return true; } int minCostMaxflow(int s, int t, int& cost) { int flow = 0; cost = 0; while (spfa(s, t)) { int Min = INF; for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) { if (Min > edge[i].cap - edge[i].flow)Min = edge[i].cap - edge[i].flow; }for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) { edge[i].flow += Min; edge[i ^ 1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; }return flow; } }; graph g; char s[6][4] = { "012","021","102","120","201","210" }; int getid(char ss[]) { for (int i = 0; i < 6; i++) { if (strcmp(ss, s[i]) == 0)return i; } return 0; } int main() { int T; cin >> T; while (T--) { int n, a, b, c; scanf("%d%d%d%d", &n, &a, &b, &c); g.init(11); int ct[10]; memset(ct, 0, sizeof ct); g.addedge(9, 6, a, 0); g.addedge(9, 7, b, 0); g.addedge(9, 8, c, 0); for (int i = 0; i < n; i++) { char s[4]; scanf("%s", s); int id = getid(s); ct[id]++; } for (int i = 0; i < 6; i++) { g.addedge(s[i][0] - '0' + 6, i, ct[i], -3); g.addedge(s[i][1] - '0' + 6, i, ct[i], -2); g.addedge(s[i][2] - '0' + 6, i, ct[i], -1); g.addedge(i, 10, ct[i], 0); } int ans = 0; g.minCostMaxflow(9 , 10,ans); printf("%d\n",- ans); } }