#include using namespace std; const int INF = 0x3f3f3f3f; int head[20]; int nxt[100], to[100], w[100], c[100], tot; char buf[5]; int cnt[6]; int val[6][3] = {{3, 2, 1}, {3, 1, 2}, {2, 3, 1}, {2, 1, 3}, {1, 3, 2}, {1, 2, 3}}; int S = 9, T = 10; int dist[20], inq[20], path[20], edge[20]; queue q; int ID(char *s) { int a = s[0] - '0', b = s[1] - '0', c = s[2] - '0'; if (a == 0 && b == 1 && c == 2) return 0; if (a == 0 && b == 2 && c == 1) return 1; if (a == 1 && b == 0 && c == 2) return 2; if (a == 2 && b == 0 && c == 1) return 3; if (a == 1 && b == 2 && c == 0) return 4; if (a == 2 && b == 1 && c == 0) return 5; } void add(int x, int y, int W, int C) { to[tot] = y, w[tot] = W, c[tot] = C, nxt[tot] = head[x], head[x] = tot++; } bool spfa() { memset(dist, 0x3f, sizeof(dist)); memset(path, -1, sizeof(path)); q.push(S), inq[S] = 1, dist[S] = 0; while (!q.empty()) { int x = q.front(); q.pop(); inq[x] = 0; for (int i = head[x]; ~i; i = nxt[i]) { int v = to[i]; if (!w[i]) continue; if (dist[v] > dist[x] + c[i]) { dist[v] = dist[x] + c[i]; path[v] = x, edge[v] = i; if (!inq[v]) q.push(v), inq[v] = 1; } } } return ~path[T]; } int min_cost() { int cost = 0; while (spfa()) { int now = T, flow = INF; while (now != S) { int e = edge[now]; flow = min(flow, w[e]); now = path[now]; } cost += flow * dist[T]; now = T; while (now != S) { int e = edge[now]; w[e] -= flow, w[e ^ 1] += flow; now = path[now]; } } return cost; } int main () { int T_T; scanf("%d", &T_T); while (T_T--) { memset(cnt, 0, sizeof(cnt)), memset(head, -1, sizeof(head)), tot = 0; int n, t[3]; scanf("%d%d%d%d", &n, &t[0], &t[1], &t[2]); for (int i = 0; i < n; i++) { scanf("%s", buf); cnt[ID(buf)]++; } for (int i = 0; i < 3; i++) { for (int j = 3; j < 3 + 6; j++) { add(i, j, INF, -val[j - 3][i]); add(j, i, 0, val[j - 3][i]); } } for (int i = 0; i < 3; i++) { add(S, i, t[i], 0); add(i, S, 0, 0); } for (int i = 3; i < 3 + 6; i++) { add(i, T, cnt[i - 3], 0); add(T, i, 0, 0); } printf("%d\n", -min_cost()); } return 0; }