#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
namespace {
	const int MOD = 1000000007;
	const int MOD2 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	using vi = vector<int>;
	using vll = vector<ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

		template<class T>
		static Modular toModular(const T& m) {
			long long val = m;
			if (val < 0) val += MODVALUE;
			if (val >= MODVALUE) val -= MODVALUE;
			return Modular(val);
		}

	public:
		long long getVal() {return val;}

		bool operator == (const Modular& other) {return val == other.val;}
		bool operator != (const Modular& other) {return !(val == other.val);}
		template<class T> bool operator == (const T& other) {return *this == Modular(other);}
		template<class T> bool operator != (const T& other) {return !(*this == Modular(other));}
		template<class T> friend bool operator == (const T& other, const Modular& m) {return Modular(other) == m;}
		template<class T> friend bool operator != (const T& other, const Modular& m) {return !(Modular(other) == m);}

		bool operator < (const Modular& other) {return val < other.val;}
		bool operator <= (const Modular& other) {return val <= other.val;}
		bool operator > (const Modular& other) {return val > other.val;}
		bool operator >= (const Modular& other) {return val >= other.val;}
		template<class T> bool operator < (const T& other) {return *this < Modular(other);}
		template<class T> bool operator <= (const T& other) {return *this <= Modular(other);}
		template<class T> bool operator > (const T& other) {return *this > Modular(other);}
		template<class T> bool operator >= (const T& other) {return *this >= Modular(other);}
		template<class T> friend bool operator < (const T& other, const Modular& m) {return Modular(other) < m;}
		template<class T> friend bool operator <= (const T& other, const Modular& m) {return Modular(other) <= m;}
		template<class T> friend bool operator > (const T& other, const Modular& m) {return Modular(other) > m;}
		template<class T> friend bool operator >= (const T& other, const Modular& m) {return Modular(other) >= m;}

		Modular operator + (const Modular& other) {return toModular(val + other.val);}
		Modular& operator += (const Modular& other) {return *this = *this + other;}
		template<class T> Modular operator + (const T& other) {return *this + Modular(other);}
		template<class T> Modular& operator += (const T& other) {return *this += Modular(other);}
		template<class T> friend Modular operator + (const T& other, const Modular& m) {return Modular(other) + m;}
		template<class T> friend Modular operator += (const T& other, const Modular& m) {return Modular(other) += m;}

		Modular& operator ++() {return *this += 1;}
		Modular operator ++(int) {Modular tmp = *this; ++*this; return tmp;}

		Modular operator - () const {return Modular(-val);}
		Modular operator - (const Modular& other) {return toModular(val - other.val);}
		Modular& operator -= (const Modular& other) {return *this = *this - other;}
		template<class T> Modular operator - (const T& other) {return *this - Modular(other);}
		template<class T> Modular& operator -= (const T& other) {return *this -= Modular(other);}
		template<class T> friend Modular operator - (const T& other, const Modular& m) {return Modular(other) - m;}
		template<class T> friend Modular operator -= (const T& other, const Modular& m) {return Modular(other) -= m;}

		Modular& operator --() {return *this -= 1;}
		Modular operator --(int) {Modular tmp = *this; --*this; return tmp;}

		Modular operator * (const Modular& other) {return toModular(val * other.val % MODVALUE);}
		Modular& operator *= (const Modular& other) {return *this = *this * other;}
		template<class T> Modular operator * (const T& other) {return *this * Modular(other);}
		template<class T> Modular operator *= (const T& other) {return *this *= Modular(other);}
		template<class T> friend Modular operator * (const T& other, const Modular& m) {return Modular(other) * m;}
		template<class T> friend Modular operator *= (const T& other, const Modular& m) {return Modular(other) *= m;}

		Modular pow(long long power) {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) {return pow(other.val);}
		Modular inv() {return pow(MODVALUE-2);}

		Modular operator / (const Modular& other) {return *this * other;}
		Modular operator /= (const Modular& other) {return *this = *this / other;}
		template<class T> Modular operator / (const T& other) {return *this / Modular(other);}
		template<class T> Modular operator /= (const T& other) {return *this /= Modular(other);}
		template<class T> friend Modular operator / (const T& other, const Modular& m) {return Modular(other) / m;}
		template<class T> friend Modular operator /= (const T& other, const Modular& m) {return Modular(other) /= m;}

		friend istream& operator >> (istream& in, Modular& m) {in >> m.val; m = toModular(m.val % MODVALUE); return in;}
		friend ostream& operator << (ostream& out, const Modular& m) {return out << m.val;}

		Modular() : val(0) {}
		Modular(int val) : val(val % MODVALUE) {};
		Modular(long long val) : val(val % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) {return (a > b ? a : b);}
	inline ll max(int a, ll b) {return (a > b ? a : b);}
	inline ll min(ll a, int b) {return (a < b ? a : b);}
	inline ll min(int a, ll b) {return (a < b ? a : b);}
	inline bool chkmin(ll& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(ll& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, int y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, int y) {return x < y ? x = y, 1 : 0;}
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class T> inline void _W(const vector<T>& x);
	template<class T> inline void _W(const deque<T>& x);
	template<class T> inline void _W(const forward_list<T>& x);
	template<class T> inline void _W(const list<T>& x);
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x);
	template<class T> inline void _W(const multiset<T>& x);
	template<class T> inline void _W(const unordered_set<T>& x);
	template<class T> inline void _W(const unordered_multiset<T>& x);
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x);
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x);

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

	template<class T> inline void _W(const ordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "YES" : "NO";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD2>;

bool isFound;
vector<int> ans;

void erase(vector<int>& occ, const vector<int>& toErase, vector<int>& lastSeen, int currentT) {
	for (auto& i : toErase) {
		occ[i]--;
		chkmin(lastSeen[i], (int)toErase.size() + currentT - 1);
	}
}

void test(int n, int v, const vector<vector<int>>& a, const vector<vector<int>>& app, vector<int> occ) {
	ans.clear();
	vector<bool> isErased(n - 1, false);
	vector<int> isUsed(n + 1, false);
	vector<int> lastSeen(n + 1, INT_MAX);
	int lastUsed;

	ans.pb(v);
	for (auto& cur : app[v]) {
		erase(occ, a[cur], lastSeen, 0);
		isErased[cur] = true;
		isUsed[v] = true;
		lastUsed = cur;
	}

	isFound = 1;
	for (int t = 1; t + 1 < n; t++) {
		int takenIdx = 0;
		for (auto& i : a[lastUsed]) {
			if (occ[i] == 1)
				if (lastSeen[i] < lastSeen[takenIdx])
					takenIdx = i;
		}
		if (takenIdx == 0 || lastSeen[takenIdx] == INT_MAX) {
			isFound = 0;
			break;
		} else {
			int eraseIdx = -1;
			for (auto& cur : app[takenIdx])
				if (!isErased[cur]) {
					eraseIdx = cur;
					break;
				}
			erase(occ, a[eraseIdx], lastSeen, t);
			isErased[eraseIdx] = true;

			ans.pb(takenIdx);
			isUsed[takenIdx] = true;
			lastUsed = eraseIdx;
		}
	}

	if (isFound) {
		for (int i = 1; i <= n; i++)
			if (!isUsed[i]) {
				ans.pb(i);
				break;
			}
		reverse(all(ans));
	}
}

int main() {
	CASE(t) {
		int n; R(n);
		vector<vector<int>> a(n - 1);
		vector<vector<int>> app(n + 1);
		for (int i = 0; i < n - 1; i++) {
			int k; R(k);
			a[i].resize(k); R(a[i]);
			for (auto& j : a[i])
				app[j].pb(i);
		}

		vector<int> occ(n + 1, 0);
		for (auto& i : a)
			for (auto& j : i)
				occ[j]++;

		isFound = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				test(n, i, a, app, occ);
				if (isFound) {
					W(ans);
					break;
				}
			}
	}
	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
namespace {
	const int MOD = 1000000007;
	const int MOD2 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	using vi = vector<int>;
	using vll = vector<ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

		template<class T>
		static Modular toModular(const T& m) {
			long long val = m;
			if (val < 0) val += MODVALUE;
			if (val >= MODVALUE) val -= MODVALUE;
			return Modular(val);
		}

	public:
		long long getVal() {return val;}

		bool operator == (const Modular& other) {return val == other.val;}
		bool operator != (const Modular& other) {return !(val == other.val);}
		template<class T> bool operator == (const T& other) {return *this == Modular(other);}
		template<class T> bool operator != (const T& other) {return !(*this == Modular(other));}
		template<class T> friend bool operator == (const T& other, const Modular& m) {return Modular(other) == m;}
		template<class T> friend bool operator != (const T& other, const Modular& m) {return !(Modular(other) == m);}

		bool operator < (const Modular& other) {return val < other.val;}
		bool operator <= (const Modular& other) {return val <= other.val;}
		bool operator > (const Modular& other) {return val > other.val;}
		bool operator >= (const Modular& other) {return val >= other.val;}
		template<class T> bool operator < (const T& other) {return *this < Modular(other);}
		template<class T> bool operator <= (const T& other) {return *this <= Modular(other);}
		template<class T> bool operator > (const T& other) {return *this > Modular(other);}
		template<class T> bool operator >= (const T& other) {return *this >= Modular(other);}
		template<class T> friend bool operator < (const T& other, const Modular& m) {return Modular(other) < m;}
		template<class T> friend bool operator <= (const T& other, const Modular& m) {return Modular(other) <= m;}
		template<class T> friend bool operator > (const T& other, const Modular& m) {return Modular(other) > m;}
		template<class T> friend bool operator >= (const T& other, const Modular& m) {return Modular(other) >= m;}

		Modular operator + (const Modular& other) {return toModular(val + other.val);}
		Modular& operator += (const Modular& other) {return *this = *this + other;}
		template<class T> Modular operator + (const T& other) {return *this + Modular(other);}
		template<class T> Modular& operator += (const T& other) {return *this += Modular(other);}
		template<class T> friend Modular operator + (const T& other, const Modular& m) {return Modular(other) + m;}
		template<class T> friend Modular operator += (const T& other, const Modular& m) {return Modular(other) += m;}

		Modular& operator ++() {return *this += 1;}
		Modular operator ++(int) {Modular tmp = *this; ++*this; return tmp;}

		Modular operator - () const {return Modular(-val);}
		Modular operator - (const Modular& other) {return toModular(val - other.val);}
		Modular& operator -= (const Modular& other) {return *this = *this - other;}
		template<class T> Modular operator - (const T& other) {return *this - Modular(other);}
		template<class T> Modular& operator -= (const T& other) {return *this -= Modular(other);}
		template<class T> friend Modular operator - (const T& other, const Modular& m) {return Modular(other) - m;}
		template<class T> friend Modular operator -= (const T& other, const Modular& m) {return Modular(other) -= m;}

		Modular& operator --() {return *this -= 1;}
		Modular operator --(int) {Modular tmp = *this; --*this; return tmp;}

		Modular operator * (const Modular& other) {return toModular(val * other.val % MODVALUE);}
		Modular& operator *= (const Modular& other) {return *this = *this * other;}
		template<class T> Modular operator * (const T& other) {return *this * Modular(other);}
		template<class T> Modular operator *= (const T& other) {return *this *= Modular(other);}
		template<class T> friend Modular operator * (const T& other, const Modular& m) {return Modular(other) * m;}
		template<class T> friend Modular operator *= (const T& other, const Modular& m) {return Modular(other) *= m;}

		Modular pow(long long power) {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) {return pow(other.val);}
		Modular inv() {return pow(MODVALUE-2);}

		Modular operator / (const Modular& other) {return *this * other;}
		Modular operator /= (const Modular& other) {return *this = *this / other;}
		template<class T> Modular operator / (const T& other) {return *this / Modular(other);}
		template<class T> Modular operator /= (const T& other) {return *this /= Modular(other);}
		template<class T> friend Modular operator / (const T& other, const Modular& m) {return Modular(other) / m;}
		template<class T> friend Modular operator /= (const T& other, const Modular& m) {return Modular(other) /= m;}

		friend istream& operator >> (istream& in, Modular& m) {in >> m.val; m = toModular(m.val % MODVALUE); return in;}
		friend ostream& operator << (ostream& out, const Modular& m) {return out << m.val;}

		Modular() : val(0) {}
		Modular(int val) : val(val % MODVALUE) {};
		Modular(long long val) : val(val % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) {return (a > b ? a : b);}
	inline ll max(int a, ll b) {return (a > b ? a : b);}
	inline ll min(ll a, int b) {return (a < b ? a : b);}
	inline ll min(int a, ll b) {return (a < b ? a : b);}
	inline bool chkmin(ll& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(ll& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, int y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, int y) {return x < y ? x = y, 1 : 0;}
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class T> inline void _W(const vector<T>& x);
	template<class T> inline void _W(const deque<T>& x);
	template<class T> inline void _W(const forward_list<T>& x);
	template<class T> inline void _W(const list<T>& x);
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x);
	template<class T> inline void _W(const multiset<T>& x);
	template<class T> inline void _W(const unordered_set<T>& x);
	template<class T> inline void _W(const unordered_multiset<T>& x);
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x);
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x);

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

	template<class T> inline void _W(const ordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "YES" : "NO";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD2>;

bool isFound;
vector<int> ans;

void erase(vector<int>& occ, const vector<int>& toErase) {
	for (auto& i : toErase)
		occ[i]--;
}

void test(int n, int v, const vector<vector<int>>& a, const vector<vector<int>>& app, vector<int> occ) {
	ans.clear();
	vector<bool> isErased(n - 1, false);
	vector<int> isUsed(n + 1, false);

	ans.pb(v);
	for (auto& cur : app[v]) {
		erase(occ, a[cur]);
		isErased[cur] = true;
		isUsed[v] = true;
	}

	isFound = 1;
	for (int t = 1; t + 1 < n; t++) {
		bool ok = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				for (auto& cur : app[i])
					if (!isErased[cur]) {
						erase(occ, a[cur]);
						isErased[cur] = true;
					}
				ans.pb(i);
				isUsed[i] = true;
				ok = 1;
				break;
			}
		if (!ok) {
			isFound = 0;
			break;
		}
	}

	if (isFound) {
		for (int i = 1; i <= n; i++)
			if (!isUsed[i]) {
				ans.pb(i);
				break;
			}
		reverse(all(ans));
	}
}

int main() {
	CASE(t) {
		int n; R(n);
		vector<vector<int>> a(n - 1);
		vector<vector<int>> app(n + 1);
		for (int i = 0; i < n - 1; i++) {
			int k; R(k);
			a[i].resize(k); R(a[i]);
			for (auto& j : a[i])
				app[j].pb(i);
		}

		vector<int> occ(n + 1, 0);
		for (auto& i : a)
			for (auto& j : i)
				occ[j]++;

		isFound = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				test(n, i, a, app, occ);
				if (isFound) {
					W(ans);
					break;
				}
			}
	}
	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
namespace {
	const int MOD = 1000000007;
	const int MOD2 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	using vi = vector<int>;
	using vll = vector<ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

		template<class T>
		static Modular toModular(const T& m) {
			long long val = m;
			if (val < 0) val += MODVALUE;
			if (val >= MODVALUE) val -= MODVALUE;
			return Modular(val);
		}

	public:
		long long getVal() {return val;}

		bool operator == (const Modular& other) {return val == other.val;}
		bool operator != (const Modular& other) {return !(val == other.val);}
		template<class T> bool operator == (const T& other) {return *this == Modular(other);}
		template<class T> bool operator != (const T& other) {return !(*this == Modular(other));}
		template<class T> friend bool operator == (const T& other, const Modular& m) {return Modular(other) == m;}
		template<class T> friend bool operator != (const T& other, const Modular& m) {return !(Modular(other) == m);}

		bool operator < (const Modular& other) {return val < other.val;}
		bool operator <= (const Modular& other) {return val <= other.val;}
		bool operator > (const Modular& other) {return val > other.val;}
		bool operator >= (const Modular& other) {return val >= other.val;}
		template<class T> bool operator < (const T& other) {return *this < Modular(other);}
		template<class T> bool operator <= (const T& other) {return *this <= Modular(other);}
		template<class T> bool operator > (const T& other) {return *this > Modular(other);}
		template<class T> bool operator >= (const T& other) {return *this >= Modular(other);}
		template<class T> friend bool operator < (const T& other, const Modular& m) {return Modular(other) < m;}
		template<class T> friend bool operator <= (const T& other, const Modular& m) {return Modular(other) <= m;}
		template<class T> friend bool operator > (const T& other, const Modular& m) {return Modular(other) > m;}
		template<class T> friend bool operator >= (const T& other, const Modular& m) {return Modular(other) >= m;}

		Modular operator + (const Modular& other) {return toModular(val + other.val);}
		Modular& operator += (const Modular& other) {return *this = *this + other;}
		template<class T> Modular operator + (const T& other) {return *this + Modular(other);}
		template<class T> Modular& operator += (const T& other) {return *this += Modular(other);}
		template<class T> friend Modular operator + (const T& other, const Modular& m) {return Modular(other) + m;}
		template<class T> friend Modular operator += (const T& other, const Modular& m) {return Modular(other) += m;}

		Modular& operator ++() {return *this += 1;}
		Modular operator ++(int) {Modular tmp = *this; ++*this; return tmp;}

		Modular operator - () const {return Modular(-val);}
		Modular operator - (const Modular& other) {return toModular(val - other.val);}
		Modular& operator -= (const Modular& other) {return *this = *this - other;}
		template<class T> Modular operator - (const T& other) {return *this - Modular(other);}
		template<class T> Modular& operator -= (const T& other) {return *this -= Modular(other);}
		template<class T> friend Modular operator - (const T& other, const Modular& m) {return Modular(other) - m;}
		template<class T> friend Modular operator -= (const T& other, const Modular& m) {return Modular(other) -= m;}

		Modular& operator --() {return *this -= 1;}
		Modular operator --(int) {Modular tmp = *this; --*this; return tmp;}

		Modular operator * (const Modular& other) {return toModular(val * other.val % MODVALUE);}
		Modular& operator *= (const Modular& other) {return *this = *this * other;}
		template<class T> Modular operator * (const T& other) {return *this * Modular(other);}
		template<class T> Modular operator *= (const T& other) {return *this *= Modular(other);}
		template<class T> friend Modular operator * (const T& other, const Modular& m) {return Modular(other) * m;}
		template<class T> friend Modular operator *= (const T& other, const Modular& m) {return Modular(other) *= m;}

		Modular pow(long long power) {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) {return pow(other.val);}
		Modular inv() {return pow(MODVALUE-2);}

		Modular operator / (const Modular& other) {return *this * other;}
		Modular operator /= (const Modular& other) {return *this = *this / other;}
		template<class T> Modular operator / (const T& other) {return *this / Modular(other);}
		template<class T> Modular operator /= (const T& other) {return *this /= Modular(other);}
		template<class T> friend Modular operator / (const T& other, const Modular& m) {return Modular(other) / m;}
		template<class T> friend Modular operator /= (const T& other, const Modular& m) {return Modular(other) /= m;}

		friend istream& operator >> (istream& in, Modular& m) {in >> m.val; m = toModular(m.val % MODVALUE); return in;}
		friend ostream& operator << (ostream& out, const Modular& m) {return out << m.val;}

		Modular() : val(0) {}
		Modular(int val) : val(val % MODVALUE) {};
		Modular(long long val) : val(val % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) {return (a > b ? a : b);}
	inline ll max(int a, ll b) {return (a > b ? a : b);}
	inline ll min(ll a, int b) {return (a < b ? a : b);}
	inline ll min(int a, ll b) {return (a < b ? a : b);}
	inline bool chkmin(ll& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(ll& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, int y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, int y) {return x < y ? x = y, 1 : 0;}
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class T> inline void _W(const vector<T>& x);
	template<class T> inline void _W(const deque<T>& x);
	template<class T> inline void _W(const forward_list<T>& x);
	template<class T> inline void _W(const list<T>& x);
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x);
	template<class T> inline void _W(const multiset<T>& x);
	template<class T> inline void _W(const unordered_set<T>& x);
	template<class T> inline void _W(const unordered_multiset<T>& x);
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x);
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x);

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

	template<class T> inline void _W(const ordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "YES" : "NO";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD2>;

bool isFound;
vector<int> ans;

void erase(vector<int>& occ, const vector<int>& toErase) {
	for (auto& i : toErase)
		occ[i]--;
}

void test(int n, int v, const vector<vector<int>>& a, const vector<vector<int>>& app, vector<int> occ) {
	ans.clear();
	vector<bool> isErased(n - 1, false);
	vector<int> isUsed(n + 1, false);

	vector<int> lastUsed;

	ans.pb(v);
	for (auto& cur : app[v]) {
		erase(occ, a[cur]);
		isErased[cur] = true;
		isUsed[v] = true;
		lastUsed = a[cur];
	}

	isFound = 1;
	for (int t = 1; t + 1 < n; t++) {
		bool ok = 0;
		for (auto& i : lastUsed) {
			if (occ[i] == 1) {
				int eraseIdx = -1;
				for (auto& cur : app[i])
					if (!isErased[cur]) {
						eraseIdx = cur;
						break;
					}
				if (eraseIdx == -1)
					break;
				erase(occ, a[eraseIdx]);
				isErased[eraseIdx] = true;
				ans.pb(i);
				isUsed[i] = true;
				lastUsed = a[eraseIdx];
				ok = 1;
				break;
			}
		}
		if (!ok) {
			isFound = 0;
			break;
		}
	}

	if (isFound) {
		for (int i = 1; i <= n; i++)
			if (!isUsed[i]) {
				ans.pb(i);
				break;
			}
		reverse(all(ans));
	}
}

int main() {
	CASE(t) {
		int n; R(n);
		vector<vector<int>> a(n - 1);
		vector<vector<int>> app(n + 1);
		for (int i = 0; i < n - 1; i++) {
			int k; R(k);
			a[i].resize(k); R(a[i]);
			for (auto& j : a[i])
				app[j].pb(i);
		}

		vector<int> occ(n + 1, 0);
		for (auto& i : a)
			for (auto& j : i)
				occ[j]++;

		isFound = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				test(n, i, a, app, occ);
				if (isFound) {
					W(ans);
					break;
				}
			}
	}
	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
namespace {
	const int MOD = 1000000007;
	const int MOD2 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	using vi = vector<int>;
	using vll = vector<ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

		template<class T>
		static Modular toModular(const T& m) {
			long long val = m;
			if (val < 0) val += MODVALUE;
			if (val >= MODVALUE) val -= MODVALUE;
			return Modular(val);
		}

	public:
		long long getVal() {return val;}

		bool operator == (const Modular& other) {return val == other.val;}
		bool operator != (const Modular& other) {return !(val == other.val);}
		template<class T> bool operator == (const T& other) {return *this == Modular(other);}
		template<class T> bool operator != (const T& other) {return !(*this == Modular(other));}
		template<class T> friend bool operator == (const T& other, const Modular& m) {return Modular(other) == m;}
		template<class T> friend bool operator != (const T& other, const Modular& m) {return !(Modular(other) == m);}

		bool operator < (const Modular& other) {return val < other.val;}
		bool operator <= (const Modular& other) {return val <= other.val;}
		bool operator > (const Modular& other) {return val > other.val;}
		bool operator >= (const Modular& other) {return val >= other.val;}
		template<class T> bool operator < (const T& other) {return *this < Modular(other);}
		template<class T> bool operator <= (const T& other) {return *this <= Modular(other);}
		template<class T> bool operator > (const T& other) {return *this > Modular(other);}
		template<class T> bool operator >= (const T& other) {return *this >= Modular(other);}
		template<class T> friend bool operator < (const T& other, const Modular& m) {return Modular(other) < m;}
		template<class T> friend bool operator <= (const T& other, const Modular& m) {return Modular(other) <= m;}
		template<class T> friend bool operator > (const T& other, const Modular& m) {return Modular(other) > m;}
		template<class T> friend bool operator >= (const T& other, const Modular& m) {return Modular(other) >= m;}

		Modular operator + (const Modular& other) {return toModular(val + other.val);}
		Modular& operator += (const Modular& other) {return *this = *this + other;}
		template<class T> Modular operator + (const T& other) {return *this + Modular(other);}
		template<class T> Modular& operator += (const T& other) {return *this += Modular(other);}
		template<class T> friend Modular operator + (const T& other, const Modular& m) {return Modular(other) + m;}
		template<class T> friend Modular operator += (const T& other, const Modular& m) {return Modular(other) += m;}

		Modular& operator ++() {return *this += 1;}
		Modular operator ++(int) {Modular tmp = *this; ++*this; return tmp;}

		Modular operator - () const {return Modular(-val);}
		Modular operator - (const Modular& other) {return toModular(val - other.val);}
		Modular& operator -= (const Modular& other) {return *this = *this - other;}
		template<class T> Modular operator - (const T& other) {return *this - Modular(other);}
		template<class T> Modular& operator -= (const T& other) {return *this -= Modular(other);}
		template<class T> friend Modular operator - (const T& other, const Modular& m) {return Modular(other) - m;}
		template<class T> friend Modular operator -= (const T& other, const Modular& m) {return Modular(other) -= m;}

		Modular& operator --() {return *this -= 1;}
		Modular operator --(int) {Modular tmp = *this; --*this; return tmp;}

		Modular operator * (const Modular& other) {return toModular(val * other.val % MODVALUE);}
		Modular& operator *= (const Modular& other) {return *this = *this * other;}
		template<class T> Modular operator * (const T& other) {return *this * Modular(other);}
		template<class T> Modular operator *= (const T& other) {return *this *= Modular(other);}
		template<class T> friend Modular operator * (const T& other, const Modular& m) {return Modular(other) * m;}
		template<class T> friend Modular operator *= (const T& other, const Modular& m) {return Modular(other) *= m;}

		Modular pow(long long power) {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) {return pow(other.val);}
		Modular inv() {return pow(MODVALUE-2);}

		Modular operator / (const Modular& other) {return *this * other;}
		Modular operator /= (const Modular& other) {return *this = *this / other;}
		template<class T> Modular operator / (const T& other) {return *this / Modular(other);}
		template<class T> Modular operator /= (const T& other) {return *this /= Modular(other);}
		template<class T> friend Modular operator / (const T& other, const Modular& m) {return Modular(other) / m;}
		template<class T> friend Modular operator /= (const T& other, const Modular& m) {return Modular(other) /= m;}

		friend istream& operator >> (istream& in, Modular& m) {in >> m.val; m = toModular(m.val % MODVALUE); return in;}
		friend ostream& operator << (ostream& out, const Modular& m) {return out << m.val;}

		Modular() : val(0) {}
		Modular(int val) : val(val % MODVALUE) {};
		Modular(long long val) : val(val % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) {return (a > b ? a : b);}
	inline ll max(int a, ll b) {return (a > b ? a : b);}
	inline ll min(ll a, int b) {return (a < b ? a : b);}
	inline ll min(int a, ll b) {return (a < b ? a : b);}
	inline bool chkmin(ll& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(ll& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, int y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, int y) {return x < y ? x = y, 1 : 0;}
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class T> inline void _W(const vector<T>& x);
	template<class T> inline void _W(const deque<T>& x);
	template<class T> inline void _W(const forward_list<T>& x);
	template<class T> inline void _W(const list<T>& x);
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x);
	template<class T> inline void _W(const multiset<T>& x);
	template<class T> inline void _W(const unordered_set<T>& x);
	template<class T> inline void _W(const unordered_multiset<T>& x);
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x);
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x);

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

	template<class T> inline void _W(const ordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "YES" : "NO";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD2>;

bool isFound;
vector<int> ans;

void erase(vector<int>& occ, const vector<int>& toErase, vector<int>& firstSeen, int currentT) {
	for (auto& i : toErase) {
		occ[i]--;
		chkmin(firstSeen[i], currentT);
	}
}

void test(int n, int v, const vector<vector<int>>& a, const vector<vector<int>>& app, vector<int> occ) {
	ans.clear();
	vector<bool> isErased(n - 1, false);
	vector<int> isUsed(n + 1, false);
	vector<int> firstSeen(n + 1, INT_MAX);
	int lastUsed;

	ans.pb(v);
	for (auto& cur : app[v]) {
		erase(occ, a[cur], firstSeen, 0);
		isErased[cur] = true;
		isUsed[v] = true;
		lastUsed = cur;
	}

	isFound = 1;
	for (int t = 1; t + 1 < n; t++) {
		int takenIdx = 0;
		for (auto& i : a[lastUsed]) {
			if (occ[i] == 1)
				if (firstSeen[i] < firstSeen[takenIdx]) {
					takenIdx = i;
				}
		}
		if (takenIdx == 0 || firstSeen[takenIdx] == INT_MAX) {
			isFound = 0;
			break;
		} else {
			int eraseIdx = -1;
			for (auto& cur : app[takenIdx])
				if (!isErased[cur]) {
					eraseIdx = cur;
					break;
				}
			if (eraseIdx == -1) {
				isFound = 0;
				break;
			}
			erase(occ, a[eraseIdx], firstSeen, t);
			isErased[eraseIdx] = true;

			ans.pb(takenIdx);
			isUsed[takenIdx] = true;
			lastUsed = eraseIdx;
		}
	}

	if (isFound) {
		for (int i = 1; i <= n; i++)
			if (!isUsed[i]) {
				ans.pb(i);
				break;
			}
		reverse(all(ans));
	}
}

int main() {
	CASE(t) {
		int n; R(n);
		vector<vector<int>> a(n - 1);
		vector<vector<int>> app(n + 1);
		for (int i = 0; i < n - 1; i++) {
			int k; R(k);
			a[i].resize(k); R(a[i]);
			for (auto& j : a[i])
				app[j].pb(i);
		}

		vector<int> occ(n + 1, 0);
		for (auto& i : a)
			for (auto& j : i)
				occ[j]++;

		isFound = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				test(n, i, a, app, occ);
				if (isFound) {
					W(ans);
					break;
				}
			}
	}
	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin());
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
namespace {
	const int MOD = 1000000007;
	const int MOD2 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	using vi = vector<int>;
	using vll = vector<ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

		template<class T>
		static Modular toModular(const T& m) {
			long long val = m;
			if (val < 0) val += MODVALUE;
			if (val >= MODVALUE) val -= MODVALUE;
			return Modular(val);
		}

	public:
		long long getVal() {return val;}

		bool operator == (const Modular& other) {return val == other.val;}
		bool operator != (const Modular& other) {return !(val == other.val);}
		template<class T> bool operator == (const T& other) {return *this == Modular(other);}
		template<class T> bool operator != (const T& other) {return !(*this == Modular(other));}
		template<class T> friend bool operator == (const T& other, const Modular& m) {return Modular(other) == m;}
		template<class T> friend bool operator != (const T& other, const Modular& m) {return !(Modular(other) == m);}

		bool operator < (const Modular& other) {return val < other.val;}
		bool operator <= (const Modular& other) {return val <= other.val;}
		bool operator > (const Modular& other) {return val > other.val;}
		bool operator >= (const Modular& other) {return val >= other.val;}
		template<class T> bool operator < (const T& other) {return *this < Modular(other);}
		template<class T> bool operator <= (const T& other) {return *this <= Modular(other);}
		template<class T> bool operator > (const T& other) {return *this > Modular(other);}
		template<class T> bool operator >= (const T& other) {return *this >= Modular(other);}
		template<class T> friend bool operator < (const T& other, const Modular& m) {return Modular(other) < m;}
		template<class T> friend bool operator <= (const T& other, const Modular& m) {return Modular(other) <= m;}
		template<class T> friend bool operator > (const T& other, const Modular& m) {return Modular(other) > m;}
		template<class T> friend bool operator >= (const T& other, const Modular& m) {return Modular(other) >= m;}

		Modular operator + (const Modular& other) {return toModular(val + other.val);}
		Modular& operator += (const Modular& other) {return *this = *this + other;}
		template<class T> Modular operator + (const T& other) {return *this + Modular(other);}
		template<class T> Modular& operator += (const T& other) {return *this += Modular(other);}
		template<class T> friend Modular operator + (const T& other, const Modular& m) {return Modular(other) + m;}
		template<class T> friend Modular operator += (const T& other, const Modular& m) {return Modular(other) += m;}

		Modular& operator ++() {return *this += 1;}
		Modular operator ++(int) {Modular tmp = *this; ++*this; return tmp;}

		Modular operator - () const {return Modular(-val);}
		Modular operator - (const Modular& other) {return toModular(val - other.val);}
		Modular& operator -= (const Modular& other) {return *this = *this - other;}
		template<class T> Modular operator - (const T& other) {return *this - Modular(other);}
		template<class T> Modular& operator -= (const T& other) {return *this -= Modular(other);}
		template<class T> friend Modular operator - (const T& other, const Modular& m) {return Modular(other) - m;}
		template<class T> friend Modular operator -= (const T& other, const Modular& m) {return Modular(other) -= m;}

		Modular& operator --() {return *this -= 1;}
		Modular operator --(int) {Modular tmp = *this; --*this; return tmp;}

		Modular operator * (const Modular& other) {return toModular(val * other.val % MODVALUE);}
		Modular& operator *= (const Modular& other) {return *this = *this * other;}
		template<class T> Modular operator * (const T& other) {return *this * Modular(other);}
		template<class T> Modular operator *= (const T& other) {return *this *= Modular(other);}
		template<class T> friend Modular operator * (const T& other, const Modular& m) {return Modular(other) * m;}
		template<class T> friend Modular operator *= (const T& other, const Modular& m) {return Modular(other) *= m;}

		Modular pow(long long power) {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) {return pow(other.val);}
		Modular inv() {return pow(MODVALUE-2);}

		Modular operator / (const Modular& other) {return *this * other;}
		Modular operator /= (const Modular& other) {return *this = *this / other;}
		template<class T> Modular operator / (const T& other) {return *this / Modular(other);}
		template<class T> Modular operator /= (const T& other) {return *this /= Modular(other);}
		template<class T> friend Modular operator / (const T& other, const Modular& m) {return Modular(other) / m;}
		template<class T> friend Modular operator /= (const T& other, const Modular& m) {return Modular(other) /= m;}

		friend istream& operator >> (istream& in, Modular& m) {in >> m.val; m = toModular(m.val % MODVALUE); return in;}
		friend ostream& operator << (ostream& out, const Modular& m) {return out << m.val;}

		Modular() : val(0) {}
		Modular(int val) : val(val % MODVALUE) {};
		Modular(long long val) : val(val % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) {return (a > b ? a : b);}
	inline ll max(int a, ll b) {return (a > b ? a : b);}
	inline ll min(ll a, int b) {return (a < b ? a : b);}
	inline ll min(int a, ll b) {return (a < b ? a : b);}
	inline bool chkmin(ll& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(ll& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, ll y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmin(int& x, int y) {return x > y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(ll& x, int y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, ll y) {return x < y ? x = y, 1 : 0;}
	inline bool chkmax(int& x, int y) {return x < y ? x = y, 1 : 0;}
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class T> inline void _W(const vector<T>& x);
	template<class T> inline void _W(const deque<T>& x);
	template<class T> inline void _W(const forward_list<T>& x);
	template<class T> inline void _W(const list<T>& x);
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x);
	template<class T> inline void _W(const multiset<T>& x);
	template<class T> inline void _W(const unordered_set<T>& x);
	template<class T> inline void _W(const unordered_multiset<T>& x);
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x);
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x);
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x);

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class T> inline void _W(const vector<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const deque<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const forward_list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const list<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const set<T1,T2,T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T> inline void _W(const unordered_multiset<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2, class T3> inline void _W(const map<T1, T2, T3>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_map<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}
	template<class T1, class T2> inline void _W(const unordered_multimap<T1, T2>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

	template<class T> inline void _W(const ordered_set<T>& x) {bool isFirst = 1; for (auto i : x) {if (!isFirst) cout << ' '; isFirst = 0; _W(i);}}

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "YES" : "NO";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD2>;

bool isFound;
vector<int> ans;

void erase(vector<int>& occ, const vector<int>& toErase, vector<int>& firstSeen, int currentT) {
	for (auto& i : toErase) {
		occ[i]--;
		chkmin(firstSeen[i], currentT);
	}
}

void test(int n, int v, const vector<vector<int>>& a, const vector<vector<int>>& app, vector<int> occ) {
	ans.clear();
	vector<bool> isErased(n - 1, false);
	vector<int> isUsed(n + 1, false);
	vector<int> firstSeen(n + 1, INT_MAX);

	ans.pb(v);
	for (auto& cur : app[v]) {
		erase(occ, a[cur], firstSeen, 0);
		isErased[cur] = true;
		isUsed[v] = true;
	}

	isFound = 1;
	for (int t = 1; t + 1 < n; t++) {
		int takenIdx = 0;
		for (int i = 1; i <= n; i++) {
			if (occ[i] == 1)
				if (firstSeen[i] < firstSeen[takenIdx]) {
					takenIdx = i;
				}
		}
		if (takenIdx == 0 || firstSeen[takenIdx] == INT_MAX) {
			isFound = 0;
			break;
		} else {
			int eraseIdx = -1;
			for (auto& cur : app[takenIdx])
				if (!isErased[cur]) {
					eraseIdx = cur;
					break;
				}
			if (eraseIdx == -1) {
				isFound = 0;
				break;
			}
			erase(occ, a[eraseIdx], firstSeen, t);
			isErased[eraseIdx] = true;

			ans.pb(takenIdx);
			isUsed[takenIdx] = true;
		}
	}

	if (isFound) {
		for (int i = 1; i <= n; i++)
			if (!isUsed[i]) {
				ans.pb(i);
				break;
			}
		reverse(all(ans));
	}
}

int main() {
	CASE(t) {
		int n; R(n);
		vector<vector<int>> a(n - 1);
		vector<vector<int>> app(n + 1);
		for (int i = 0; i < n - 1; i++) {
			int k; R(k);
			a[i].resize(k); R(a[i]);
			for (auto& j : a[i])
				app[j].pb(i);
		}

		vector<int> occ(n + 1, 0);
		for (auto& i : a)
			for (auto& j : i)
				occ[j]++;

		isFound = 0;
		for (int i = 1; i <= n; i++)
			if (occ[i] == 1) {
				test(n, i, a, app, occ);
				if (isFound) {
					W(ans);
					break;
				}
			}
	}
	return 0;
}

static auto _batch_ios = [](){
	#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
	#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 0; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (y == P) y = -1;
    else if (x == P) {
        x = y;
        y = -1;
    }
    if (x == -1) return false;
    if (y == -1) {
        ans[j] = x;
        int l;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == x && ban[i] == false) {
                l = i;
            }
        }
        ban[l] = true;
        bool f = get(j - 1, P);
        if (!f) ban[l] = false;
        return f;
    }
    ans[j] = x;
    int l;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x && ban[i] == false) {
            l = i;
        }
    }
    ban[l] = true;
    bool f = get(i - 1, y);
    if (f) return true;
    ban[l] = false;
    ans[j] = y;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == y) ban[i] = true;
    }
    return get(j - 1, x);
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 1; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (y == P) y = -1;
    else if (x == P) {
        x = y;
        y = -1;
    }
    if (x == -1) return false;
    if (y == -1) {
        ans[j] = x;
        int l;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == x && ban[i] == false) {
                l = i;
            }
        }
        ban[l] = true;
        bool f = get(j - 1, P);
        ban[l] = false;
        return f;
    }
    swap(x, y);
    ans[j] = x;
    int l;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x && ban[i] == false) {
            l = i;
        }
    }
    ban[l] = true;
    bool f = get(j - 1, y);
    if (f) return true;
    ban[l] = false;
    ans[j] = y;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == y) ban[i] = true;
    }
    return get(j - 1, x);
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 1; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (y == P) y = -1;
    else if (x == P) {
        x = y;
        y = -1;
    }
    if (x == -1) return false;
    int _x = 0, _y = 0;
    for (int i = 0; i < n - 1; i++) {
        if (ban[i]) {
            for (auto el : a[i]) {
                if (el == x) _x++;
                if (el == y) _y++;
            }
        }
    }
    if (_y > _x) swap(x, y);
    ans[j] = x;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x) ban[i] = true;
    }
    return get(j - 1, -1);
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 1; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (y == P) y = -1;
    else if (x == P) {
        x = y;
        y = -1;
    }
    if (x == -1) return false;
    int _x = 0, _y = 0;
    for (int i = 0; i < n - 1; i++) {
        if (ban[i]) {
            for (auto el : a[i]) {
                if (el == x) _x++;
                if (el == y) _y++;
            }
        }
    }
    if (_y > _x) swap(x, y);
    if (y == -1 || _y != _x) {
        ans[j] = x;
        int l;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == x && ban[i] == false) {
                l = i;
            }
        }
        ban[l] = true;
        bool f = get(j - 1, P);
        ban[l] = false;
        return f;
    }
    ans[j] = x;
    int l;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x && ban[i] == false) {
            l = i;
        }
    }
    ban[l] = true;
    bool f = get(j - 1, y);
    if (f) return true;
    ban[l] = false;
    ans[j] = y;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == y) ban[i] = true;
    }
    return get(j - 1, x);
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 0; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (y == P) y = -1;
    else if (x == P) {
        x = y;
        y = -1;
    }
    if (x == -1) return false;
    if (y == -1) {
        ans[j] = x;
        int l;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == x && ban[i] == false) {
                l = i;
            }
        }
        ban[l] = true;
        bool f = get(j - 1, P);
        if (!f) ban[l] = false;
        return f;
    }
    ans[j] = x;
    int l;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x && ban[i] == false) {
            l = i;
        }
    }
    ban[l] = true;
    bool f = get(j - 1, y);
    if (f) return true;
    ban[l] = false;
    ans[j] = y;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == y) ban[i] = true;
    }
    return get(j - 1, x);
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long

vector<int> ans;
vector<vector<int>> a;
vector<bool> ban;
int n;

bool get(int j, int P) {
    //cout << j << " f" << P << endl;
    if (j == 0) {
        vector<bool> used(n + 1, false);
        for (int i = 1; i < n; i++) used[ans[i]] = true;
        for (int i = 1; i <= n; i++) {
            if (!used[i]) {
                ans[0] = i;
                return true;
            }
        }
    }
    vector<int> b(n + 1, 0);
    for (int i = 0; i < n - 1; i++) {
        if (!ban[i]) {
            for (auto x : a[i]) b[x]++;
        }
    }
    int x = -1, y = -1;
    for (int i = 0; i <= n; i++) {
        if (b[i] == 1) {
            if (x == -1) x = i;
            else y = i;
        }
    }
    if (j != 0) {
        if (y == P) y = -1;
        else if (x == P) {
            x = y, y = -1;
        }
    }
    //cout << x << " " << y << endl;
    if (x == -1) return false;
    if (y == -1) {
        ans[j] = x;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == x) ban[i] = true;
        }
        return get(j - 1, P);
    }
    ans[j] = x;
    int l = 0;
    for (int i = 0; i < n - 1; i++) {
        for (auto el : a[i]) if (el == x && ban[i] == false) ban[i] = true;
        for (auto el : a[i]) if (el == x && ban[i] == false) l = i;
    }
    if (!get(j - 1, y)) {
        cout << "F";
        ban[l] = false;
        ans[j] = y;
        for (int i = 0; i < n - 1; i++) {
            for (auto el : a[i]) if (el == y) ban[i] = true;
        }
        return get(j - 1, x);
    }
}

void solve() {
    cin >> n;
    a.resize(n - 1);
    ans.resize(n);
    ban.resize(n - 1, false);
    for (int i = 0; i < n - 1; i++) {
        int k;
        cin >> k;
        a[i].resize(k);
        for (int j = 0; j < k; j++) cin >> a[i][j];
    }
    get(n - 1, -1);
    for (int i = 0; i < n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
    a.clear();
    ans.clear();
    ban.clear();
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int q;
    cin >> q;
    while (q--) {
        solve();
    }
}


// Problem : F. Restore the Permutation by Sorted Segments
// Contest : Codeforces - Codeforces Round #636 (Div. 3)
// URL : https://codeforces.com/contest/1343/problem/F
// Memory Limit : 0 MB
// Time Limit : 0 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>

using namespace std;

int T, N;
int occ[205];
int tmp[205];
vector<vector<int>> v;
int ans[205];
bool seen[205];

int solve(int f){
	ans[1] = v[f][0], ans[2] = v[f][1];
	fill(seen+1, seen+1+N, 0);
	seen[ans[1]] = seen[ans[2]] = 1;
	//cout << ans[1] << " " << ans[2] << " " << occ[ans[1]] << " " << occ[ans[2]] << "\n";
	if(occ[ans[1]] > occ[ans[2]]){
		swap(ans[1], ans[2]);
	}
	for(int i = 3; i<=N; i++){
		for(int j = 0; j<N-1; j++){
			int cnt = v[j].size();
			int val = 0;
			for(int n : v[j]){
				cnt -= seen[n];
				if(!seen[n]){
					val = n;
				}
			}
			if(cnt == 1){
				ans[i] = val;
				seen[val] = 1;
				break;
			}
			else if(j == N-2){
				return 0;
			}
		}
	}
	return 1;
}

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--){
		cin >> N;
		for(int i = 1; i<N; i++){
			int k;
			cin >> k;
			vector<int> c;
			while(k--){
				int n;
				cin >> n;
				occ[n]++;
				tmp[n]++;
				c.push_back(n);
			}
			v.push_back(c);
		}
		random_shuffle(v.begin(), v.end());
		for(int i = 0; i<N-1; i++){
			if(v[i].size() == 2){
				if(solve(i)){
					break;
				}
			}
		}
		for(int i = 1; i<=N; i++){
			cout << ans[i] << " ";
		}
		cout << "\n";
		v.clear();
		fill(ans+1, ans+1+N, 0);
		fill(tmp+1, tmp+1+N, 0);
		fill(occ+1, occ+1+N, 0);
	}
}


// Problem : F. Restore the Permutation by Sorted Segments
// Contest : Codeforces - Codeforces Round #636 (Div. 3)
// URL : https://codeforces.com/contest/1343/problem/F
// Memory Limit : 0 MB
// Time Limit : 0 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>

using namespace std;

int T, N;
int occ[205];
int tmp[205];
vector<vector<int>> v;
int ans[205];
bool seen[205];

int solve(int f){
	ans[1] = v[f][0], ans[2] = v[f][1];
	fill(seen+1, seen+1+N, 0);
	seen[ans[1]] = seen[ans[2]] = 1;
	//cout << " " << ans[1] << " " << ans[2] << " " << occ[ans[1]] << " " << occ[ans[2]] << "\n";
	if(occ[ans[1]] > occ[ans[2]]){
		swap(ans[1], ans[2]);
	}
	for(int i = 3; i<=N; i++){
		bool b = 0;
		for(int j = 0; j<N-1; j++){
			int cnt = v[j].size();
			int val = 0;
			for(int n : v[j]){
				cnt -= seen[n];
				if(!seen[n]){
					val = n;
				}
			}
			if(cnt == 1 && !b){
				ans[i] = val;
				b = 1;
			}
			else if(cnt == 1 && b){
				return 0;
			}
		}
		if(!ans[i]){
			return 0;
		}
		seen[ans[i]] = 1;
	}
	return 1;
}

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--){
		cin >> N;
		for(int i = 1; i<N; i++){
			int k;
			cin >> k;
			vector<int> c;
			while(k--){
				int n;
				cin >> n;
				occ[n]++;
				tmp[n]++;
				c.push_back(n);
			}
			v.push_back(c);
		}
		random_shuffle(v.begin(), v.end());
		/*
		for(int i = 0; i<N-1; i++){
			for(int j : v[i]){
				cout << j << " ";
			}
			cout << "\n";
		}
		*/
		for(int i = 0; i<N-1; i++){
			if(v[i].size() == 2){
				if(solve(i)){
					break;
				}
			}
		}
		for(int i = 1; i<=N; i++){
			cout << ans[i] << " ";
		}
		cout << "\n";
		v.clear();
		fill(ans+1, ans+1+N, 0);
		fill(tmp+1, tmp+1+N, 0);
		fill(occ+1, occ+1+N, 0);
	}
}


// Problem : F. Restore the Permutation by Sorted Segments
// Contest : Codeforces - Codeforces Round #636 (Div. 3)
// URL : https://codeforces.com/contest/1343/problem/F
// Memory Limit : 0 MB
// Time Limit : 0 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>

using namespace std;

int T, N;
int occ[205];
int tmp[205];
vector<vector<int>> v;
int ans[205];
bool seen[205];

int solve(int f){
	ans[1] = v[f][0], ans[2] = v[f][1];
	fill(seen+1, seen+1+N, 0);
	seen[ans[1]] = seen[ans[2]] = 1;
	for(int i = 3; i<=N; i++){
		for(int j = 0; j<N-1; j++){
			int cnt = v[j].size();
			int val = 0;
			for(int n : v[j]){
				cnt -= seen[n];
				if(!seen[n]){
					val = n;
				}
			}
			if(cnt == 1){
				ans[i] = val;
				seen[val] = 1;
				break;
			}
			else if(j == N-2){
				return 0;
			}
		}
	}
	return 1;
}

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--){
		cin >> N;
		for(int i = 1; i<N; i++){
			int k;
			cin >> k;
			vector<int> c;
			while(k--){
				int n;
				cin >> n;
				occ[n]++;
				tmp[n]++;
				c.push_back(n);
			}
			v.push_back(c);
		}
		//random_shuffle(v.begin(), v.end());
		for(int i = 0; i<N-1; i++){
			if(v[i].size() == 2){
				if(solve(i)){
					break;
				}
			}
		}
		for(int i = 1; i<=N; i++){
			cout << ans[i] << " ";
		}
		cout << "\n";
		v.clear();
		fill(ans+1, ans+1+N, 0);
		fill(tmp+1, tmp+1+N, 0);
		fill(occ+1, occ+1+N, 0);
	}
}


// Problem : F. Restore the Permutation by Sorted Segments
// Contest : Codeforces - Codeforces Round #636 (Div. 3)
// URL : https://codeforces.com/contest/1343/problem/F
// Memory Limit : 0 MB
// Time Limit : 0 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>

using namespace std;

int T, N;
int occ[205];
int tmp[205];
vector<vector<int>> v;
int ans[205];

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--){
		cin >> N;
		for(int i = 1; i<N; i++){
			int k;
			cin >> k;
			vector<int> c;
			while(k--){
				int n;
				cin >> n;
				occ[n]++;
				tmp[n]++;
				c.push_back(n);
			}
			v.push_back(c);
		}
		for(int i = N; i>2; i--){
			int idx = 0;
			for(int k = 1; k<=N; k++){
				if(tmp[k] == 1){
					idx = k;
					break;
				}
			}
			ans[i] = idx;
			for(int j = 0; j<v.size(); j++){
				if(find(v[j].begin(), v[j].end(), idx) != v[j].end()){
					for(int &n : v[j]){
						tmp[n]--;
						n = 0;
					}
				}
			}
		}
		for(int j = 0; j<v.size(); j++){
			if(v[j][0]){
				if(occ[v[j][0]] < occ[v[j][1]]){
					ans[1] = v[j][0];
					ans[2] = v[j][1];
				}
				else{
					ans[1] = v[j][1];
					ans[2] = v[j][0];
				}
				break;
			}
		}
		for(int i = 1; i<=N; i++){
			cout << ans[i] << " ";
		}
		cout << "\n";
		v.clear();
		fill(ans+1, ans+1+N, 0);
		fill(tmp+1, tmp+1+N, 0);
		fill(occ+1, occ+1+N, 0);
	}
}


// Problem : F. Restore the Permutation by Sorted Segments
// Contest : Codeforces - Codeforces Round #636 (Div. 3)
// URL : https://codeforces.com/contest/1343/problem/F
// Memory Limit : 0 MB
// Time Limit : 0 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>

using namespace std;

int T, N;
int occ[205];
int tmp[205];
vector<vector<int>> v;
set<vector<int>> st;
int ans[205];
bool seen[205];
bool tkn[205];

int solve(int f){
	ans[1] = v[f][0], ans[2] = v[f][1];
	fill(seen+1, seen+1+N, 0);
	fill(tkn, tkn+N, 0);
	tkn[f] = 1;
	seen[ans[1]] = seen[ans[2]] = 1;
	//cout << " " << ans[1] << " " << ans[2] << " " << occ[ans[1]] << " " << occ[ans[2]] << "\n";
	if(occ[ans[1]] > occ[ans[2]]){
		swap(ans[1], ans[2]);
	}
	for(int i = 3; i<=N; i++){
		for(int j = 0; j<N-1; j++){
			if(v[j].size() <= i && !tkn[j]){
				bool b = 1;
				for(int k = i-1; k > i-v[j].size(); k--){
					//cout << j << " " << k << " " << ans[k] << "\n";
					//cout << "bs: " << binary_search(v[j].begin(), v[j].end(), ans[k]) << "\n";
					if(!binary_search(v[j].begin(), v[j].end(), ans[k])){
						b = 0;
						break;
					}
				}
				if(b){
					tkn[j] = 1;
					for(int n : v[j]){
						if(!seen[n]){
							ans[i] = n;
							seen[n] = 1;
							break;
						}
					}
					break;
				}
			}
			if(j == N-2){
				return 0;
			}
		}
	}
	return 1;
}

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--){
		cin >> N;
		for(int i = 1; i<N; i++){
			int k;
			cin >> k;
			vector<int> c;
			while(k--){
				int n;
				cin >> n;
				occ[n]++;
				tmp[n]++;
				c.push_back(n);
			}
			v.push_back(c);
		}
		random_shuffle(v.begin(), v.end());

		/*
		for(int i = 0; i<N-1; i++){
			for(int j : v[i]){
				cout << j << " ";
			}
			cout << "\n";
		}
		*/
		for(int i = 0; i<N-1; i++){
			if(v[i].size() == 2){
				if(solve(i)){
					break;
				}
			}
		}
		for(int i = 1; i<=N; i++){
			cout << ans[i] << " ";
		}
		cout << "\n";
		v.clear();
		fill(ans+1, ans+1+N, 0);
		fill(tmp+1, tmp+1+N, 0);
		fill(occ+1, occ+1+N, 0);
	}
}


#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
#define MAXN 205

vector<int> ls[MAXN],ps[MAXN];
int bs[MAXN],fs[MAXN],mk[MAXN],res[MAXN];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while(t--)
    {
        int n,x;
        cin >> n;
        for(int i=0;i<=n;i++)
        {
            ps[i].clear();
            ls[i].clear();
        }
        for(int i=0;i<n-1;i++)
        {
            cin >> bs[i];
            for(int j=0;j<bs[i];j++)
            {
                cin >> x;
                ls[i].push_back(x);
                ps[x].push_back(i);
            }
        }

        for(int i=0;i<n-1;i++)
        {
            if(bs[i]!=2)
                continue;
//            db(i)
            for(int j=0;j<=n;j++)
            {
                fs[j]=bs[j];
                mk[j]=0;
            }

            res[0]=ls[i][0];
            res[1]=ls[i][1];
            mk[res[0]]=1;
            mk[res[1]]=1;
            if(ps[res[0]].size()>ps[res[1]].size())
                swap(res[0],res[1]);

            queue<int> q;
            for(auto y : ps[res[0]])
                fs[y]--;
            for(auto y : ps[res[1]])
            {
                fs[y]--;
                if(fs[y]==1)
                    q.push(y);
            }

            int cont=2;
            while(!q.empty())
            {
                if(q.size()>1)
                    break;
                int u=q.front();
                q.pop();

//                db(u)
                int v=-1;
                for(auto y : ls[u])
                    if(!mk[y])
                        v=y;

                mk[v]=1;
                res[cont]=v;
                for(auto y : ps[v])
                {
                    fs[y]--;
                    if(fs[y]==1)
                        q.push(y);
                }
                cont++;
            }
//            db(cont)
//            db("")

            if(cont==n)
            {
                for(int i=0;i<n;i++)
                    cout << res[i] << ' ';
                cout << '\n';
                break;
            }
        }
    }

    return 0;
}
/**
5
5
2 2 3
2 1 2
2 1 4
2 4 5
6
3 2 5 6
2 4 6
3 1 3 4
2 1 3
4 1 2 4 6
7
3 1 2 6
4 1 3 5 6
2 1 2
3 4 5 7
6 1 2 3 4 5 6
3 1 3 6
2
2 1 2
5
2 2 5
3 2 3 5
4 2 3 4 5
5 1 2 3 4 5
**/


#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
#define MAXN 205

vector<int> ls[MAXN],ps[MAXN];
int bs[MAXN],fs[MAXN],mk[MAXN],res[MAXN];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int t;
    cin >> t;
    while(t--)
    {
        int n,x;
        cin >> n;
        for(int i=0;i<=n;i++)
        {
            ps[i].clear();
            ls[i].clear();
        }
        for(int i=0;i<n-1;i++)
        {
            cin >> bs[i];
            for(int j=0;j<bs[i];j++)
            {
                cin >> x;
                ls[i].push_back(x);
                ps[x].push_back(i);
            }
        }

        for(int i=0;i<n-1;i++)
        {
            if(bs[i]!=2)
                continue;
//            db(i)
            for(int j=0;j<=n;j++)
            {
                fs[j]=bs[j];
                mk[j]=0;
            }

            res[0]=ls[i][0];
            res[1]=ls[i][1];
            mk[res[0]]=1;
            mk[res[1]]=1;
            if(ps[res[0]].size()>ps[res[1]].size())
                swap(res[0],res[1]);

            queue<int> q;
            for(auto y : ps[res[0]])
                fs[y]--;
            for(auto y : ps[res[1]])
            {
                fs[y]--;
                if(fs[y]==1)
                    q.push(y);
            }

            int cont=2;
            while(!q.empty())
            {
                if(q.size()>1)
                    break;
                int u=q.front();
                q.pop();

//                db(u)
                int v=-1;
                for(auto y : ls[u])
                    if(!mk[y])
                        v=y;

                for(auto y : ps[v])
                {
                    fs[y]--;
                    if(fs[y]==1)
                        q.push(y);
                }
                mk[v]=1;
                res[cont]=v;
                cont++;
            }
//            db(cont)
//            db("")

            if(cont==n)
            {
                vector<int> it(n+1);
                for(int i=0;i<n;i++)
                    it[res[i]]=i;
                bool ok=1;
                for(int j=0;j<n-1;j++)
                {
                    int mi=MAXN;
                    int ma=0;
                    for(auto y : ls[j])
                    {
                        mi=min(mi,it[y]);
                        ma=max(ma,it[y]);
                    }
                    ok&=((ma-mi+1)==bs[j]);
                }
                if(ok)
                {
                    for(int i=0;i<n;i++)
                        cout << res[i] << ' ';
                    cout << '\n';
                    break;
                }
            }
        }
    }

    return 0;
}
/**
5
2
2 1 2
5
2 2 3
2 1 2
2 1 4
2 4 5
6
3 2 5 6
2 4 6
3 1 3 4
2 1 3
4 1 2 4 6
7
3 1 2 6
4 1 3 5 6
2 1 2
3 4 5 7
6 1 2 3 4 5 6
3 1 3 6
5
2 2 5
3 2 3 5
4 2 3 4 5
5 1 2 3 4 5
**/


#include<bits/stdc++.h>
using namespace std;
void solve()
{
    int n;
    cin>>n;
    vector<set<int>>a(n-1);
    map<set<int>,int>q;
    for(int i=0;i+1<n;i++)
    {
        int k;
        cin>>k;
        for(int j=0;j<k;j++)
        {
            int x;
            cin>>x;
            a[i].insert(x);
        }
        ++q[a[i]];
    }
    for(int elem=1;elem<=n;elem++)
    {
        vector<set<int>>b=a;
        for(int i=0;i+1<n;i++)
        {
            if(b[i].find(elem)!=b[i].end())
                b[i].erase(elem);
        }
        vector<int>ans(n,-1);
        ans[0]=elem;
        int pos=1;
        while(true)
        {
            map<int,int>cnt;
            for(auto &c : b)
            {
                ++cnt[c.size()];
            }
            if(cnt[1]!=1)
            {
                break;
            }
            else
            {
                int cur_elem=-1;
                for(int i=0;i+1<n;i++)
                {
                    if(b[i].size()==1)
                    {
                        cur_elem=*b[i].begin();
                        break;
                    }
                }
                for(int i=0;i+1<n;i++)
                {
                    if(b[i].find(cur_elem)!=b[i].end())
                        b[i].erase(cur_elem);
                }
                ans[pos++]=cur_elem;
            }
        }
        int cntxy=1;
        for(int i=1;i<n;i++)
        {
            set<int>se;
            se.insert(ans[i]);
            bool ff=false;
            for(int j=i-1;j>=0;j--)
            {
              se.insert(ans[j]);
              if(q[se]>0)
              {
                  ff=true;
                  break;
              }
            }
            if(ff==true)
               cntxy++;
        }
        if(cntxy==n)
        {
            for(auto c : ans)
            {
                cout<<c<<" ";
            }
            cout<<endl;
            return;
        }
    }
}
int main ()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include<set>
using namespace std;
const int N = 2e5+5;
typedef long long ll;
#define rep(i,a,b) for(i=(a);i<=b;i++)
#define pt(a) printf("%d\n",(a))

int main()
{
    int n,m,i,j,k,t=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        vector<set<int> > q;
        vector<int> ans;
        rep(i,1,n-1){
            scanf("%d",&m);
            set<int> cur;
            rep(j,1,m){
                int x;
                scanf("%d",&x);
                cur.insert(x);
            }
            q.push_back(cur);
        }
        rep(i,1,n){
            ans.clear();
            vector<set<int> > p = q;
            int cur = i;
            ans.push_back(cur);
            rep(j,1,n-1){
                int pos = 0 , cnt = 0;
                rep(k,0,n-2){
                    if(p[k].count(cur)) p[k].erase(cur);
                    if(p[k].size()==1) cnt++,pos = *p[k].begin();
                }
                if(cnt!=1) break;
                else cur = pos,ans.push_back(cur);
            }
            if(j==n){
                set<set<int> > d(q.begin(),q.end());
                bool ok = true;
                for(int r=1;r<n;r++){
                    set<int> f;
                    f.clear();
                    bool flag = false;
                    for(int l=r;l>=0;l--){
                        f.insert(ans[l]);
                        //printf("%d ",ans[l]);
                        if(d.count(f)) {
                            flag = true;
                            break;
                        }
                    }
                   // printf("yes%d %d\n",i,flag);
                    if(!flag) {
                        ok = false;
                        break;
                    }
                }
                if(ok){
                    for(int l=0;l<n;l++){
                        printf("%d ",ans[l]);
                    }
                    printf("\n");
                    break;
                }
            }
        }
    }
    system("pause");
    return 0;
}


#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include<set>
using namespace std;
const int N = 2e5+5;
typedef long long ll;
#define rep(i,a,b) for(i=(a);i<=b;i++)
#define pt(a) printf("%d\n",(a))

int main()
{
    int n,m,i,j,k,t=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        vector<set<int> > q;
        vector<int> ans;
        rep(i,1,n-1){
            scanf("%d",&m);
            set<int> cur;
            rep(j,1,m){
                int x;
                scanf("%d",&x);
                cur.insert(x);
            }
            q.push_back(cur);
        }
        rep(i,1,n){
            ans.clear();
            vector<set<int> > p = q;
            int cur = i;
            ans.push_back(cur);
            rep(j,1,n-1){
                int pos = 0 , cnt = 0;
                rep(k,0,n-2){
                    if(p[k].count(cur)) p[k].erase(cur);
                    if(p[k].size()==1) cnt++,pos = *p[k].begin();
                }
                if(cnt!=1) break;
                else cur = pos,ans.push_back(cur);
            }
            if(j==n){
                set<set<int> > d(q.begin(),q.end());
                bool ok = true;
                for(int r=1;r<n;r++){
                    set<int> f;
                    f.clear();
                    bool flag = false;
                    for(int l=r;l>=0;l--){
                        f.insert(ans[l]);
                        //printf("%d ",ans[l]);
                        if(d.count(f)) {
                            flag = true;
                            break;
                        }
                    }
                   // printf("yes%d %d\n",i,flag);
                    if(!flag) {
                        ok = false;
                        break;
                    }
                }
                if(ok){
                    for(int l=0;l<n;l++){
                        printf("%d ",ans[l]);
                    }
                    printf("\n");
                    break;
                }
            }
        }
    }
    //system("pause");
    return 0;
}