//by ciwomuli
//enter ICPC WF 2020
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define LL long long
using namespace std;
template <typename T>
inline void read(T &t)
{
    int f = 0, c = getchar();
    t = 0;
    while (!isdigit(c))
        f |= c == '-', c = getchar();
    while (isdigit(c))
        t = t * 10 + c - 48, c = getchar();
    if (f)
        t = -t;
}
template <typename T, typename... Args>
inline void read(T &t, Args &...args)
{
    read(t);
    read(args...);
}
const int maxn = 505;
int a[maxn][maxn];
int c[2 * maxn];
vector<pair<int, int>> e;
int n;
int calc(vector<int> ls)
{
    if (ls.size() == 1)
        return ls[0];
    int res = -1;
    for (int u : ls)
    {
        for (int v : ls)
        {
            res = max(res, a[u][v]);
        }
    }
    vector<vector<int>> ch;
    ch.push_back({ls[0]});
    for (int i = 1; i < ls.size(); i++)
    {
        int group = -1;
        int v = ls[i];
        for (int j = 0; j < ch.size(); j++)
        {
            if (a[v][ch[j][0]] != res)
            {
                group = j;
                break;
            }
        }
        if (group == -1)
        {
            group = ch.size();
            ch.push_back({});
        }
        ch[group].push_back(v);
    }
    int v = n++;
    c[v] = res;
    for (int i = 0; i < ch.size(); i++)
    {
        int u = calc(ch[i]);
        e.emplace_back(u, v);
    }
    return v;
}
int main()
{
    read(n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            read(a[i][j]);
        }
    }
    vector<int> ls(n);
    for (int i = 0; i < n; i++)
    {
        c[i] = a[i][i];
    }
    iota(ls.begin(), ls.end(), 0);
    int root = calc(ls);
    cout << n << endl;
    for (int i = 0; i < n; i++)
        cout << c[i] << " ";
    cout << endl;
    cout << root + 1 << endl;
    for (auto it : e)
    {
        cout << it.first + 1 << " " << it.second + 1 << endl;
    }
}