#include <bits/stdc++.h>
using namespace std;
void bsort(int &a, int &b, int &c) {
  if (a > b) swap(a, b);
  if (b > c) swap(b, c);
  if (a > b) swap(a, b);
}
tuple<int, int, int> assemble(
    const pair<pair<int, int>, pair<int, int>> &triangle,
    vector<int> &current) {
  int a = current[triangle.first.first], b = current[triangle.first.second],
      c = current[triangle.second.second];
  bsort(a, b, c);
  return make_tuple(a, b, c);
}
void solve() {
  int n;
  cin >> n;
  int a, b, c;
  map<pair<int, int>, int> counts;
  vector<vector<int>> graph(n);
  map<tuple<int, int, int>, int> slices;
  for (int i = 0; i < n - 2; ++i) {
    cin >> a >> b >> c;
    --a, --b, --c;
    bsort(a, b, c);
    slices[make_tuple(a, b, c)] = i;
    ++counts[make_pair(a, b)];
    ++counts[make_pair(b, c)];
    ++counts[make_pair(a, c)];
    graph[a].push_back(b);
    graph[a].push_back(c);
    graph[b].push_back(a);
    graph[b].push_back(c);
    graph[c].push_back(a);
    graph[c].push_back(b);
  }
  vector<vector<int>> edges_graph(n);
  for (auto [edge, count] : counts) {
    if (count != 1) continue;
    auto [u, v] = edge;
    edges_graph[u].push_back(v);
    edges_graph[v].push_back(u);
  }
  vector<int> current = {0};
  int avoid = 0;
  for (int i = 0; i < n - 1; ++i) {
    for (auto j : edges_graph[current.back()]) {
      if (j != avoid) {
        avoid = current.back();
        current.push_back(j);
        break;
      }
    }
  }
  vector<int> renumber(n);
  for (int i = 0; i < current.size(); ++i) renumber[current[i]] = i;
  vector<pair<pair<int, int>, pair<int, int>>> consider;
  for (int i = 0; i < n; ++i) {
    int a = current[i], b = current[(i + 1) % n], c = current[(i + 2) % n];
    bsort(a, b, c);
    if (slices.count(make_tuple(a, b, c))) {
      consider.emplace_back(make_pair(i, (i + 1) % n),
                            make_pair((i + 1) % n, (i + 2) % n));
    }
  }
  set<int> represented;
  for (int i = 0; i < n; ++i) represented.insert(i);
  vector<int> res;
  while (represented.size() > 3) {
    auto [u, v] = consider.back();
    res.push_back(slices[assemble(consider.back(), current)]);
    consider.pop_back();
    int low = u.first;
    int high = v.second;
    if (low != *represented.begin())
      low = *represented.lower_bound(low - 1);
    else
      low = *represented.rbegin();
    if (high != *represented.rbegin())
      high = *represented.upper_bound(high);
    else
      high = *represented.begin();
    represented.erase(u.second);
    pair<pair<int, int>, pair<int, int>> low_side =
        make_pair(make_pair(low, u.first), make_pair(u.first, v.second));
    tuple<int, int, int> lo = assemble(low_side, current);
    if (slices.count(lo)) consider.push_back(low_side);
    pair<pair<int, int>, pair<int, int>> high_side =
        make_pair(make_pair(u.first, v.second), make_pair(v.second, high));
    tuple<int, int, int> hi = assemble(high_side, current);
    if (slices.count(hi)) consider.push_back(high_side);
  }
  vector<int> final(represented.begin(), represented.end());
  for (auto &i : final) i = current[i];
  sort(final.begin(), final.end());
  res.push_back(slices[make_tuple(final[0], final[1], final[2])]);
  for (auto i : current) cout << i + 1 << " ";
  cout << endl;
  for (auto i : res) cout << i + 1 << " ";
  cout << endl;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(NULL);
  int t;
  cin >> t;
  while (t--) {
    solve();
  }
}
