#include<bits/stdc++.h>
using namespace std;
#define var auto

vector<int> ranks;
vector<vector<int>> graph;
vector<bool> arrived;

int main(){
  int n;
  cin >> n;
  var all = 2 * n * n - 2 * n;
  ranks = vector<int>(n * n, 0);
  graph = vector<vector<int>>(n * n, vector<int>());
  arrived = vector<bool>(n * n, false);
  for (int i = 0; i < all; i++){
    int a, b;
    cin >> a >> b;
    a--;b--;
    ranks[a]++;
    graph[a].push_back(b);
    graph[b].push_back(a);
    ranks[b]++;
  }
  int top;
  for (int i = 0; i < ranks.size(); i++){
    if (ranks[i] == 2){
      top = i;
      break;
    }
  }
  vector<int> next{};
  for (int i = 0; i < n; i++){
    arrived[top] = true;
    cout << top + 1;
    if (i != n - 1) cout << ' ';
    else cout << '\n';
    int ntop = -1;
    for (var&& item : graph[top]){
      if (arrived[item]) continue;
      arrived[item] = true;
      if (ranks[item] <= 3 && ntop == -1 && i != n - 1){
	ntop = item;
      }
      else{
	next.push_back(item);
      }
    }
    top = ntop;
  }

  
  for (int itr = 0; itr < n - 1; itr++){
    vector<int> nnext{};
    bool first = true;
    for (var&& elem : next){
      if (!first) cout << ' ';
      first = false;
      cout << elem + 1;
      for (var&& item : graph[elem]){
	if (arrived[item]) continue;
	arrived[item] = true;
	nnext.push_back(item);
      }
    }
    cout << '\n';
    next = nnext;
  }
}

