#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 { struct edge { int v, nxt; int d; edge(int vv = 0, int dd = 0, int nn = 0) { v = vv; d = dd; nxt = nn; } }; static const int MAXN = 1e5; static const int MAXM = 1e6; vectorh; vectore; graph() { h.clear(); e.clear(); for (int i = 0; i < MAXN; i++) { h.push_back(-1); } } void addedge(int u, int v, int d = 0) { e.push_back(edge()); e[e.size() - 1].v = v; e[e.size() - 1].d = d; e[e.size() - 1].nxt = h[u]; h[u] = e.size() - 1; } }; unionset ss; int main() { int T; cin >> T; while (T--) { int n; scanf("%d", &n); vectorv[101][11]; ss.clear(n); for (int i = 0; i < n; i++) { int m; scanf("%d", &m); for (int j = 0; j < m; j++) { int time, pos; scanf("%d%d", &time, &pos); v[time][pos].push_back(i); } } for (int i = 0; i <= 100; i++) { for (int j = 0; j <= 10; j++) { int flag = 0; for (int k = 0; k < v[i][j].size(); k++) { int id = v[i][j][k]; int re = ss.getfa(id); if (re == 0)flag = 1; } if (flag == 0)continue; for (int k = 0; k < v[i][j].size(); k++) { int id = v[i][j][k]; ss.merge(id, v[i][j][0]); } } } vectorans; for (int i = 0; i < n; i++) { if (ss.getfa(i) == 0) { ans.push_back(i); } } for (int i = 0; i < ans.size(); i++) { if (i)printf(" "); printf("%d", ans[i]+1); } printf("\n"); } }