#include "bits/stdc++.h"
using namespace std;

#define rep(i, a, b) for(int i=a; i<=b; i++)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int) x.size()
#define pb push_back
#define f first
#define s second
#define nl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int MOD = 1e9+7;
template<class T> using pqg = priority_queue<T,vector<T>,greater<T>>;

pii done[501];
int par[1001];
int n;
int a[501][501];
int val[1001];
bool used[5001];

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  // freopen("input.txt", "r", stdin); 
  // freopen("output.txt", "w", stdout);

  cin >> n;
  rep(i, 1, n){
    rep(j, 1, n){
      cin >> a[i][j];
    }
  }

  int cnt=n;
  rep(i, 1, n){
    rep(i, 1, 5000) used[i]=false;
    vi vec;
    vi ind(5001);
    vi id(5001);
    rep(j, 1, n){
      if(!used[a[i][j]]){
        vec.pb(a[i][j]);
        used[a[i][j]]=true;
      }
    }
    sort(all(vec), greater<int>());
    rep(k, 0, sz(vec)-1){
      ind[vec[k]]=k+1;
    }
    rep(k, done[i].f, sz(vec)-1){
      if(k+1==sz(vec)){
        par[i]=(k==done[i].f?done[i].s:cnt);
        val[i]=vec[k];
        id[vec[k]]=i;
        continue;
      }
      cnt++;
      par[cnt]=(k==done[i].f?done[i].s:cnt-1);
      id[vec[k]]=cnt;
      val[cnt]=vec[k];
    }
    rep(j, 1, n){
      if(ind[a[i][j]]>done[j].f) done[j]={ind[a[i][j]], id[a[i][j]]};
    }
  }

  cout << cnt << nl;
  rep(i, 1, cnt) cout << val[i] << " ";
  cout << nl;
  rep(i, 1, cnt){
    if(par[i]==0){
      cout << i << nl; break;
    }
  }
  rep(i, 1, cnt){
    if(par[i]) cout << i << " " << par[i] << nl;
  }
}