#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-loops")

using namespace std;

using ll = long long;
using ld = long double;

ll n, m, k, q, x, y, z, a, b, c, d;
string s;
unordered_map< ll, unordered_set<ll> > m1;
unordered_map< ll, unordered_set<ll> > m0;
vector<ll> v;
vector< unordered_map< ll, unordered_set<ll> > > v1;
vector< pair<ll, ll> > ans;

void solve() {
    cin >> n >> m;
    v.resize(n * m);
    v1.resize(m);
    for (int i = 0; i < n * m; i++) {
        cin >> v[i];
        v[i]--;
        v1[i / m][v[i]].insert(i);
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (v1[i][j].size() == 0) {
                m0[i].insert(j);
            }
            else if (v1[i][j].size() > 1) {
                while (v1[i][j].size() > 1) {
                    m1[j].insert(*v1[i][j].begin());
                    v1[i][j].erase(v1[i][j].begin());
                }
            }
        }
    }
    // for (auto &i : m1) {
    //     cout << i.first << '\n';
    //     for (ll j : i.second) {
    //         cout << '\t' << j << '\n';
    //     }
    // }
    while (!m1.empty()) {
        for (int i = 0; i < n; i++) {
            if (m1[i].size() > 0) {
                ans.push_back({*m1[i].begin(), n * m});
                ll nm = *m1[i].begin();
                m1[i].erase(*m1[i].begin());
                if (m1[i].size() == 0) {
                    m1.erase(i);
                }
                ll x = nm / m;
                while (m0[x].size() != 0) {
                    ll y = *m0[x].begin();
                    if (m1.count(y)) {
                        ll z = *m1[y].begin();
                        ans.push_back({z, x});
                        m0[x].erase(m0[x].begin());
                        if (m0[x].size() == 0) {
                            m0.erase(x);
                        }
                        m1[y].erase(m1[y].begin());
                        if (m1[y].size() == 0) {
                            m1.erase(y);
                        }
                        x = z / m;
                    }
                    else {
                        ans.push_back({nm, x});
                        m0[x].erase(m0[x].begin());
                        if (m0[x].size() == 0) {
                            m0.erase(x) ;
                        }
                        break;
                    }
                }
                break;
            }
        }
    }
    cout << ans.size() << '\n';
    for (int i = 0; i < ans.size(); i++) {
        cout << ans[i].first + 1 << ' ' << ans[i].second + 1 << '\n';
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout << setprecision(10);
    solve();
}
