#include <bits/stdc++.h>
using namespace std;
struct triple {
  int x, y, z;
  triple() {}
  triple(int x, int y, int z) : x(x), y(y), z(z) {}
};
const int maxn = 1e5 + 10;
vector<triple> triplets;
vector<int> adj[maxn];
int deg[maxn];
bool check[maxn];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int n;
  cin >> n;
  map<pair<int, int>, vector<int>> mmap;
  set<int> mset;
  for (int i = 1; i <= n - 2; ++i) {
    int x, y, z;
    cin >> x >> y >> z;
    triplets.push_back({x, y, z});
    mmap[{x, y}].push_back(z);
    mmap[{y, x}].push_back(z);
    if (mmap[{x, y}].size() == 2 || mmap[{y, x}].size() == 2) {
      adj[x].push_back(y);
      adj[y].push_back(x);
      mset.insert(x);
      mset.insert(y);
      deg[x]++;
      deg[y]++;
    }
    mmap[{x, z}].push_back(y);
    mmap[{z, x}].push_back(y);
    if (mmap[{x, z}].size() == 2 || mmap[{z, x}].size() == 2) {
      adj[x].push_back(z);
      adj[z].push_back(x);
      mset.insert(x);
      mset.insert(z);
      deg[x]++;
      deg[z]++;
    }
    mmap[{y, z}].push_back(x);
    mmap[{z, y}].push_back(x);
    if (mmap[{y, z}].size() == 2 || mmap[{z, y}].size() == 2) {
      adj[y].push_back(z);
      adj[z].push_back(y);
      mset.insert(z);
      mset.insert(y);
      deg[z]++;
      deg[y]++;
    }
  }
  int root = 0;
  for (auto iter = mset.begin(); iter != mset.end(); ++iter) {
    if (deg[*iter] == 1) {
      root = *iter;
      break;
    }
  }
  vector<int> v;
  queue<int> q;
  q.push(root);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    check[u] = true;
    v.push_back(u);
    for (int v : adj[u]) {
      if (!check[v]) q.push(v);
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (!check[i]) {
      if (mmap[{i, v[0]}].size() > 0 || mmap[{v[0], i}].size() > 0)
        v.insert(v.begin(), i);
      else
        v.push_back(i);
    }
  }
  copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
  return 0;
}
