#include #include #include using namespace std; const int N = 35, S = 35, INF = 0x3f3f3f3f; int n, s, t, a, b, c, A, B, C, id[N], pre[S], dis[S], incf[S], q[S], idx; int head[S], numE = 1, ans, cnt[N]; bool vis[S]; struct E{ int next, v, w, c; } e[S * 6]; void add(int u, int v, int w, int c) { e[++numE] = (E) { head[u], v, w, c }; head[u] = numE; } void addEdge(int u, int v, int w, int c) { //cout << u << " " << v << " " << w << " " << c << endl; add(u, v, w, c); add(v, u, 0, -c); } bool spfa() { memset(dis, 0xcf, sizeof dis); memset(vis, false, sizeof vis); memset(pre, 0, sizeof pre); int hh = 0, tt = 1; q[0] = s, dis[s] = 0, incf[s] = INF; while (hh != tt) { int u = q[hh++]; vis[u] = false; if (hh == S) hh = 0; for (int i = head[u]; i; i = e[i].next) { int v = e[i].v; if (e[i].w && dis[u] + e[i].c > dis[v]) { dis[v] = dis[u] + e[i].c; pre[v] = i; incf[v] = min(incf[u], e[i].w); if (!vis[v]) { q[tt++] = v, vis[v] = true; if (tt == S) tt = 0; } } } } return dis[t] != 0xcfcfcfcf; } void update() { int x = t; while (x != s) { int i = pre[x]; e[i].w -= incf[t]; e[i ^ 1].w += incf[t]; x = e[i ^ 1].v; } ans += dis[t] * incf[t]; } void inline clear() { idx = 6; memset(head, 0, sizeof head); memset(cnt, 0, sizeof cnt); numE = 1; ans = 0; } char str[5]; int main() { int T; scanf("%d", &T); while (T--) { clear(); scanf("%d%d%d%d", &n, &a, &b, &c); /* 012 1 021 2 102 3 120 4 201 5 210 6 */ s = ++idx, t = ++idx; A = ++idx, B = ++idx, C = ++idx; addEdge(1, A, INF, 3); addEdge(1, B, INF, 2); addEdge(1, C, INF, 1); addEdge(2, A, INF, 3); addEdge(2, B, INF, 1); addEdge(2, C, INF, 2); addEdge(3, A, INF, 2); addEdge(3, B, INF, 3); addEdge(3, C, INF, 1); addEdge(4, A, INF, 1); addEdge(4, B, INF, 3); addEdge(4, C, INF, 2); addEdge(5, A, INF, 2); addEdge(5, B, INF, 1); addEdge(5, C, INF, 3); addEdge(6, A, INF, 1); addEdge(6, B, INF, 2); addEdge(6, C, INF, 3); // 入点 x, 出点 x + L for (int i = 1; i <= n; i++) { scanf("%s", str); if (str[0] == '0' && str[1] == '1') { cnt[1]++; } else if (str[0] == '0' && str[1] == '2') { cnt[2]++; } else if (str[0] == '1' && str[1] == '0') { cnt[3]++; } else if (str[0] == '1' && str[1] == '2') { cnt[4]++; } else if (str[0] == '2' && str[1] == '0') { cnt[5]++; } else if (str[0] == '2' && str[1] == '1') { cnt[6]++; } } for (int i = 1; i <= 6; i++) addEdge(s, i, cnt[i], 0); addEdge(A, t, a, 0); addEdge(B, t, b, 0); addEdge(C, t, c, 0); while (spfa())update(); printf("%d\n", ans); } return 0; }