#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <cstdlib>#include <algorithm>#define M0(a) memset(a, 0, sizeof(a))using namespace std;const int Inf = 100000000;const int maxn = 210;const int maxm=4 * maxn * maxn;struct Tedge{ int y, f, cost, next;};Tedge edge[maxm+1];bool vis[maxn*2+2];int n, m, T, S, len, cost; int son[maxn*2+2], now[maxn*2+2], dist[maxn*2+2];int TT, store;int map[210][210];int ans[210];void add_edge(int x,int y,int f,int cost){ ++len; edge[len].y = y; edge[len].f = f; edge[len].cost = cost; edge[len].next = son[x]; son[x] = len;}void init(){ scanf("%d%d", &n, &m); store = 0; len = 1; M0(son); M0(map); int k, y; for (int i = 1; i <= n; ++i){ scanf("%d", &k); for (int j = 1; j <= k; ++j){ scanf("%d", &y); map[i][y] = 100; } } for (int i = 1; i <= n; ++i){ scanf("%d", &y); map[i][y]--; if (y) store++; } for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (map[i][j] > 0){ add_edge(i, j + n, 1, map[i][j]); add_edge(j + n, i, 0, -map[i][j]); } S = 0; T = n + m + 1; for (int i = 1; i <= n; ++i){ add_edge(S, i, 1, 0); add_edge(i, S, 0, 0); } for (int i = 1; i <= m; ++i){ add_edge(i + n, T, 1, 0); add_edge(T, i + n, 0, 0); }}int aug(int x, int flow){ if (x == T) { cost += flow * dist[S]; return flow; } vis[x] = true; int delta; for (int p = now[x]; p; p = edge[p].next) if ( !vis[edge[p].y] && edge[p].f>0 && dist[edge[p].y] + edge[p].cost == dist[x]){ delta = aug(edge[p].y, min(flow, edge[p].f)); if (delta > 0) { now[x] = p; edge[p].f -= delta; edge[p ^ 1].f += delta; return delta; } } now[x] = 0; return 0;}bool modlabel(){ int delta = Inf; for (int x = S; x <= T; ++x) if (vis[x]){ for (int p = son[x]; p ; p = edge[p].next) if ((!vis[edge[p].y]) && (edge[p].f>0)) delta = min(delta, dist[edge[p].y] + edge[p].cost - dist[x]); } if (delta == Inf) return true; for (int x = S; x <= T; ++x) if (vis[x]) dist[x] += delta; M0(vis); return false;}void zkw_flow(){ for (int i = S; i <= T; ++i) dist[i]=0; memset(vis,0,sizeof(vis)); cost=0; do { memcpy(now, son, sizeof(now)); while (aug(S, Inf) > 0) M0(vis); } while (!modlabel());}void solve(){ M0(ans); int p; int ansma = 0, cnt = 0; for (int i = 1; i <= n; ++i){ p = son[i]; while (p){ if (edge[p].f == 0 && edge[p].y > n && edge[p].y <= n + m){ ans[i] = edge[p].y - n; ++ansma; if (edge[p].cost == 99) ++cnt; break; } p = edge[p].next; } } printf("%d %dn", ansma, store - cnt); for (int i = 1; i < n; ++i) printf("%d ", ans[i]); printf("%dn", ans[n]);}int main(){ int cas; scanf("%d", &cas); while (cas--){ init(); zkw_flow(); solve(); if (cas) puts(""); } return 0;}