#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target ("avx,avx2,tune=native")
#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#define int long long
#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) a.begin(),a.end()
#define sqr(x) ((x)*(x))
#define PI 3.14159265358979323846
using namespace std;
using pii = pair <int, int>;
constexpr int maxn = 1e6 + 10;
constexpr int mod = 998244353;
constexpr long long inf = 1e18 + 10;
constexpr long double eps = 1e-15;
mt19937_64 rng (chrono::steady_clock::now ().time_since_epoch ().count ());

int n, m;

inline int get (pii a) {
    if (a.X == -1) return n * m + 1;
    return a.X * m + a.Y + 1;
}

int a [444][444];
set <int> mas;
set <int> add [444];
set <pii> del [444];
int pos = -1;
vector <pii> res;
vector <pii> res2;

inline void f (pii s) {
    pii v = s;
    res.clear ();
    while (true) {
        if (v.X == -1) {
            for (int i = 0; i < m; ++i) if (!del[i].empty ()) {
                v = *del[i].begin ();
                del[i].erase (v);
                break;
            }
            if (v.X == -1) return;
            res.pb (mp (get (v), n * m + 1));
        }
        int x = *add[v.X].begin ();
        add[v.X].erase (x);
        if (del[x].empty ()) {
            res.pb (mp (get (s), get (v)));
            break;
        }
        pii u = *del[x].begin ();
        del[x].erase (u);
        res.pb (mp (get (u), get (v)));
        v = u;
    }
}

inline bool check (pii v) {
    if (v.X == -1) {
        for (int i = 0; i < m; ++i) if (!del[i].empty ()) return true;
        return false;
    }
    //if (v.X < 0 || v.X >= 444) while (true) {}
    return !add[v.X].empty ();
}

stack <pii> help;

inline void solve () {
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            cin >> a[i][j], --a[i][j];
    for (int i = 0; i < n; ++i) {
        mas.clear ();
        for (int j = 0; j < m; ++j) {
            if (mas.count (a[i][j])) del[a[i][j]].insert (mp (i, j));
            mas.insert (a[i][j]);
        }
        for (int j = 0; j < m; ++j) if (!mas.count (j)) add[i].insert (j);
    }
    pii V = mp (-1, -1);
    int C = 0;
    if (check (V)) f (V);
    else {
        cout << "0\n";
        return;
    }
    for (int i = (int) res.size () - 1; i >= 0; --i) help.push (res[i]);
    while (!help.empty ()) {
        pii q = help.top ();
        pii v = mp ((q.X - 1) / m, (q.X - 1) % m);
        if (q.X == n * m + 1) v = mp (-1, -1);
        help.pop ();
            res2.pb (q);
    }
    cout << (int) res2.size () << '\n';
    for (pii i : res2) cout << i.X << ' ' << i.Y << '\n';
}

signed main() {
    //freopen ("parallelepiped.in", "r", stdin);
    //freopen ("parallelepiped.out", "w", stdout);
    cin.tie(nullptr) -> sync_with_stdio(false);
    //cout << fixed << setprecision (12);
    int t = 1, g;
    //cin >> t;
    while (t--) solve ();
    return 0;
}