#include <bits/stdc++.h>

using namespace std;

const int N = 401;
int a[N][N], _a[N][N];
int rowCnt[N][N], _rowCnt[N][N];
int n, m;

mt19937 mt(time(nullptr));

void doOp(int i1, int j1, int i2, int j2, vector<pair<int, int>>& ops) {
    ops.push_back({i1 * m + j1, i2 * m + j2});
    --rowCnt[i1][a[i1][j1]];
    ++rowCnt[i1][a[i2][j2]];

    --rowCnt[i2][a[i2][j2]];
    ++rowCnt[i2][a[i1][j1]];

    swap(a[i1][j1], a[i2][j2]);
}

void doRecOp(int i, int j, vector<pair<int, int>>& ops, int val = 0) {
    while (val < m && rowCnt[i][val]) ++val;
    if (val == m) {
        doOp(n, 0, i, j, ops);
        return;
    }
    int i2 = 0;
    while (i2 < n && rowCnt[i2][val] < 2) ++i2;
    if (i2 == n) {
        doRecOp(i, j, ops, val + 1);
        return;
    }
    int j2 = 0;
    while (a[i2][j2] != val) {
        ++j2;
    }
    doOp(i2, j2, i, j, ops);
    doRecOp(i2, j2, ops);
}

vector<pair<int, int>> solve1() {
    for (auto i = 0; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            a[i][j] = _a[i][j];
            rowCnt[i][j] = _rowCnt[i][j];
        }
    }

    vector<pair<int, int>> ops;
    bool canChange = true;
    while (canChange) {
        canChange = false;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (rowCnt[i][a[i][j]] > 1) {
                    canChange = true;
                    doOp(i, j, n, 0, ops);
                    doRecOp(i, j, ops);
                }
            }
        }
    }
    return ops;
}

vector<pair<int, int>> solve2() {
    for (auto i = 0; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            a[i][j] = _a[i][j];
            rowCnt[i][j] = _rowCnt[i][j];
        }
    }

    vector<pair<int, int>> ops;
    bool canChange = true;
    while (canChange) {
        canChange = false;
        vector<pair<int, int>> vars;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (rowCnt[i][a[i][j]] > 1) {
                    vars.push_back({i, j});
                    canChange = true;
                }
            }
        }
        if (!vars.empty()) {
            auto [i, j] = vars[mt() % vars.size()];
            doOp(i, j, n, 0, ops);
            doRecOp(i, j, ops);
        }
    }
    return ops;
}



void doRecOp2(int i, int j, vector<pair<int, int>>& ops, int val = 0) {
    while (val < m && rowCnt[i][val]) ++val;
    if (val == m) {
        doOp(n, 0, i, j, ops);
        return;
    }
    vector<int> vars;
    for (int i2 = 0; i2 < n; ++i2) {
        if (rowCnt[i2][val] >= 2) vars.push_back(i2);
    }
    if (vars.empty()) {
        doRecOp2(i, j, ops, val + 1);
        return;
    }
    int i2 = vars[mt() % vars.size()];
    int j2 = 0;
    while (a[i2][j2] != val) {
        ++j2;
    }
    doOp(i2, j2, i, j, ops);
    doRecOp2(i2, j2, ops);
}

vector<pair<int, int>> solve3() {
    for (auto i = 0; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            a[i][j] = _a[i][j];
            rowCnt[i][j] = _rowCnt[i][j];
        }
    }

    vector<pair<int, int>> ops;
    bool canChange = true;
    while (canChange) {
        canChange = false;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (rowCnt[i][a[i][j]] > 1) {
                    canChange = true;
                    doOp(i, j, n, 0, ops);
                    doRecOp2(i, j, ops);
                }
            }
        }
    }
    return ops;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        fill(_rowCnt[i], _rowCnt[i] + N, 0);
        for (int j = 0; j < m; ++j) {
            cin >> _a[i][j];
            --_a[i][j];
            ++_rowCnt[i][_a[i][j]];
        }
    }
    fill(_rowCnt[n], _rowCnt[n] + N, 0);
    _a[n][0] = m;
    ++_rowCnt[n][m];


    auto res = solve1();
    for (int i = 0; i < 2; ++i) {
        auto sol2 = solve2();
        if (sol2.size() < res.size()) {
            res = sol2;
        }
    }
    for (int i = 0; i < 3; ++i) {
        auto sol2 = solve3();
        if (sol2.size() < res.size()) {
            res = sol2;
        }
    }

    cout << res.size() << '\n';
    for (auto [i, j] : res) {
        cout << i + 1 << ' ' << j + 1 << '\n';
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cerr << a[i][j] << ' ';
        }
        cerr << '\n';
    }
    return 0;
}
