/*⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣀⠀⠀⠀⠀⠀⢀⣾⣇⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⣀⣤⣤⣤⣀⠀⠀⣤⣤⠀⠀⠀⠀⠀⣀⣤⣤⣄⡀⠀⠀⢠⣤⣤⣤⣄⡀⢠⣤⣄⠀⠀⢀⣤⣤⠀⠀⠀⢠⣤⣤⣤⣤⣤⣤⡀⠀⣀⣤⣤⣤⣀⠀⠀⠀
⣿⣷⣄⠀⠀⠀⢸⣿⣿⠀⠀⠀⢀⣴⣿⡇⠀⠀⠀⢠⣿⡿⠛⠉⠙⠛⠀⠀⣿⣿⠀⠀⠀⢠⣾⣿⠛⠙⢻⣿⣦⠀⢸⣿⡟⠛⣿⣿⠄⠹⣿⣧⣠⣿⡿⠁⠀⠀⠀⠘⠛⢻⣿⣿⠛⠛⢁⣾⣿⠟⠉⠻⣿⣷⠀⠀
⣿⡟⢿⣧⠀⠀⠈⣿⣿⠀⠀⢠⣾⠟⣿⡇⠀⠀⠀⣿⣿⡇⠀⢶⣶⣶⡆⠀⣿⣿⠀⠀⠀⢸⣿⡇⠀⠀⠀⣿⣿⠀⢸⣿⣷⣾⣿⡋⠀⠀⠘⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀⢸⣿⣿⠀⠀⠀⣿⣿⡇⠀
⣿⣿⠘⣿⡆⠀⠀⣿⡇⠀⠀⣾⡟⠀⣿⡇⠀⠀⠀⠘⣿⣷⣤⣤⣼⣿⡇⠀⣿⣿⣤⣤⣤⡘⢿⣿⣤⣤⣼⣿⠟⠀⢸⣿⡇⠈⢿⣿⣆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀⠈⢿⣿⣦⣤⣴⣿⡿⠀⠀
⣿⣿⠀⣿⣇⠀⠀⣿⣇⠀⠀⣿⡇⠀⣿⡇⠀⠀⠀⠀⠀⠉⠛⠛⠋⠉⠀⠀⠉⠉⠉⠉⠉⠁⠀⠉⠛⠛⠋⠁⠀⠀⠈⠙⠁⠀⠈⠉⠉⠀⠀⠙⠙⠁⠀⠀⠀⠀⠀⠀⠀⠈⠋⠋⠀⠀⠀⠀⠉⠙⠛⠋⠉⠀⠀⠀
⣿⣿⠀⣹⣿⠀⢸⣿⣿⠀⢸⣿⡃⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣿⡏⣼⡿⠛⢀⣾⡟⣿⣇⠘⠻⣿⡆⣿⡇⠀⠀⠀⢠⣤⡄⠀⠀⣤⣤⠀⢀⣤⣄⠀⠀⣠⣤⡄⢠⣤⣤⣤⣄⡀⠀⠀⠀⠀⣤⣤⡄⠀⠀⠀⣤⣤⠀⢀⣤⣤⠀⠀⢠⣤⡄⠀⣤⣤⣤⣤⣤⡀⠀⠀⠀⠀⠀⠀⠀
⣿⣇⠻⣷⡄⣾⡟⠀⠘⣿⣆⣴⣿⠃⣿⡇⠀⠀⠀⢸⣿⡇⠀⠀⣿⣿⠀⢸⣿⣿⣠⣾⡿⠋⠀⢸⣿⡟⠛⣿⣿⡆⠀⠀⣼⣿⢿⣿⡀⠀⠀⣿⣿⠀⢸⣿⣿⣷⡀⢸⣿⡇⠀⣿⣿⠛⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀
⣿⡿⠀⠈⢸⡿⠸⣷⣿⠺⣿⠌⠀⠀⣿⡇⠀⠀⠀⢸⣿⣇⠀⠀⣿⣿⠀⢸⣿⣿⣿⣯⡀⠀⠀⢸⣿⣷⣶⣿⣟⠀⠀⢰⣿⡟⡘⣿⣷⠀⠀⣿⣿⠀⢸⣿⡏⢻⣷⣸⣿⡇⠀⣿⣿⠿⠿⠿⠀⠀⠀⠀⠀⠀⠀⠀
⠿⠿⠿⠿⢿⣿⠇⣿⡇⢿⣿⠿⠿⠿⠿⠇⠀⠀⠀⠘⣿⣿⣤⣤⣿⡿⠀⢸⣿⣿⠙⢿⣿⣦⡀⢸⣿⡇⠈⢻⣿⣆⢀⣿⣿⠿⠿⢿⣿⣇⠀⣿⣿⠀⢸⣿⡇⠀⢻⣿⣿⡇⠀⣿⣿⣤⣤⣤⡄⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠈⢻⣷⣿⣷⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠉⠀⠀⠈⠋⠋⠀⠀⠉⠋⠋⠈⠋⠁⠀⠀⠙⠉⠈⠙⠁⠀⠀⠀⠙⠉⠀⠉⠋⠀⠈⠋⠁⠀⠀⠙⠙⠁⠀⠙⠉⠉⠉⠙⠁⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠙⠻⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*/
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

const int NMAX=400;
int mx[NMAX+5][NMAX+5];
vector<int>need[NMAX+5],have[NMAX+5][NMAX+5];
int mas[200000];
int n,m;

vector<pair<int,int>>ops;
vector<pair<int,int>>ops2;
vector<pair<int,int>>ops3;
vector<pair<int,int>>ops4;
vector<pair<int,int>>ops5;
vector<pair<int,int>>ops6;

void solve1(){
    int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    while(1){
        int last=-1,row=-1;
        for(int i=1;i<=n;i++){
            for(int ii=1;ii<=m;ii++){
                if(have[i][ii].size()>1){
                    last=have[i][ii].back();
                    row=i;
                    have[i][ii].pop_back();
                    i=n+1;ii=m+1;
                    goto exit_lbl;
                    break;
                }
            }
        }
        exit_lbl:;
        if(last==-1){
            break;
        }
        ops.push_back({last,n*m+1});
        swap(mas[last],mas[n*m+1]);
        while(true){
            if(need[row].empty())break;
            int num=need[row].back();need[row].pop_back();
            for(int i=n;i>=1;i--){
                if(have[i][num].size()<=1)continue;
                ops.push_back({have[i][num].back(),last});
                swap(mas[have[i][num].back()],mas[last]);
                last=have[i][num].back();have[i][num].pop_back();
                row=i;
                break;
            }
        }
        ops.push_back({n*m+1,last});
        //cout<<n*m+1<<" "<<last<<"\n";
        swap(mas[n*m+1],mas[last]);
    }
}
void solve2(){
    int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    while(1){
        int last=-1,row=-1;
        for(int i=1;i<=n;i++){
            for(int ii=1;ii<=m;ii++){
                if(have[i][ii].size()>1){
                    last=have[i][ii].back();
                    row=i;
                    have[i][ii].pop_back();
                    i=n+1;ii=m+1;
                    goto exit_lbl;
                    break;
                }
            }
        }
        exit_lbl:;
        if(last==-1){
            break;
        }
        ops2.push_back({last,n*m+1});
        swap(mas[last],mas[n*m+1]);
        while(true){
            if(need[row].empty())break;
            int num=need[row].back();need[row].pop_back();
            for(int i=1;i<=n;i++){
                if(have[i][num].size()<=1)continue;
                ops2.push_back({have[i][num].back(),last});
                swap(mas[have[i][num].back()],mas[last]);
                last=have[i][num].back();have[i][num].pop_back();
                row=i;
                break;
            }
        }
        ops2.push_back({n*m+1,last});
        //cout<<n*m+1<<" "<<last<<"\n";
        swap(mas[n*m+1],mas[last]);
    }
}

void solve3(){
     int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    vector<pair<int,int>>ops;
    while(1){
    int last=-1,row=-1;
    int __first=-1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].size()>1){
                __first=last=have[i][ii].back();
                row=i;
                have[i][ii].pop_back();
                i=n+1;ii=n+1;
                break;
            }
        }
    }
    if(last==-1){
        break;
    }
    ops3.push_back({last,n*m+1});
    swap(mas[last],mas[n*m+1]);
    while(true){
        if(need[row].empty())break;
        int num=need[row].back();need[row].pop_back();
        int best=-1;
        for(int i=1;i<=n;i++){
            if(have[i][num].size()<=1)continue;
            if(best==-1||need[i].size()>need[best].size())best=i;
        }
        if(best==-1){
            continue;
        }
        ops3.push_back({have[best][num].back(),last});
        swap(mas[have[best][num].back()],mas[last]);
        last=have[best][num].back();have[best][num].pop_back();
        row=best;        
    }
    ops3.push_back({n*m+1,last});
    //cout<<n*m+1<<" "<<last<<"\n";
    swap(mas[n*m+1],mas[last]);
    }
} void solve4(){
    int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    while(1){
        int last=-1,row=-1;
        for(int i=n;i>=1;i--){
            for(int ii=1;ii<=m;ii++){
                if(have[i][ii].size()>1){
                    last=have[i][ii].back();
                    row=i;
                    have[i][ii].pop_back();
                    i=n+1;ii=m+1;
                    goto exit_lbl;
                    break;
                }
            }
        }
        exit_lbl:;
        if(last==-1){
            break;
        }
        ops4.push_back({last,n*m+1});
        swap(mas[last],mas[n*m+1]);
        while(true){
            if(need[row].empty())break;
            int num=need[row].back();need[row].pop_back();
            for(int i=n;i>=1;i--){
                if(have[i][num].size()<=1)continue;
                ops4.push_back({have[i][num].back(),last});
                swap(mas[have[i][num].back()],mas[last]);
                last=have[i][num].back();have[i][num].pop_back();
                row=i;
                break;
            }
        }
        ops4.push_back({n*m+1,last});
        //cout<<n*m+1<<" "<<last<<"\n";
        swap(mas[n*m+1],mas[last]);
    }
}
void solve5(){
    int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    while(1){
        int last=-1,row=-1;
        for(int i=n;i>=1;i--){
            for(int ii=1;ii<=m;ii++){
                if(have[i][ii].size()>1){
                    last=have[i][ii].back();
                    row=i;
                    have[i][ii].pop_back();
                    i=n+1;ii=m+1;
                    goto exit_lbl;
                    break;
                }
            }
        }
        exit_lbl:;
        if(last==-1){
            break;
        }
        ops5.push_back({last,n*m+1});
        swap(mas[last],mas[n*m+1]);
        while(true){
            if(need[row].empty())break;
            int num=need[row].back();need[row].pop_back();
            for(int i=1;i<=n;i++){
                if(have[i][num].size()<=1)continue;
                ops5.push_back({have[i][num].back(),last});
                swap(mas[have[i][num].back()],mas[last]);
                last=have[i][num].back();have[i][num].pop_back();
                row=i;
                break;
            }
        }
        ops5.push_back({n*m+1,last});
        //cout<<n*m+1<<" "<<last<<"\n";
        swap(mas[n*m+1],mas[last]);
    }
}

void solve6(){int pos=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++){
            have[i][mx[i][ii]].push_back(pos++);
        }
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].empty())need[i].push_back(ii);
        }
    }
    vector<pair<int,int>>ops;
    while(1){
    int last=-1,row=-1;
    int __first=-1;
    for(int i=n;i>=1;i--){
        for(int ii=1;ii<=m;ii++){
            if(have[i][ii].size()>1){
                __first=last=have[i][ii].back();
                row=i;
                have[i][ii].pop_back();
                i=n+1;ii=n+1;
                break;
            }
        }
    }
    if(last==-1){
        break;
    }
    ops6.push_back({last,n*m+1});
    swap(mas[last],mas[n*m+1]);
    while(true){
        if(need[row].empty())break;
        int num=need[row].back();need[row].pop_back();
        int best=-1;
        for(int i=1;i<=n;i++){
            if(have[i][num].size()<=1)continue;
            if(best==-1||need[i].size()>need[best].size())best=i;
        }
        if(best==-1){
            continue;
        }
        ops6.push_back({have[best][num].back(),last});
        swap(mas[have[best][num].back()],mas[last]);
        last=have[best][num].back();have[best][num].pop_back();
        row=best;        
    }
    ops6.push_back({n*m+1,last});
    //cout<<n*m+1<<" "<<last<<"\n";
    swap(mas[n*m+1],mas[last]);
    }
} 

signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    int ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)cin>>mx[i][ii],mas[ps++]=mx[i][ii];
    }
    solve1();
    ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)mas[ps++]=mx[i][ii];
    }
    for(int i=1;i<=n;i++)for(int ii=1;ii<=m;ii++)have[i][ii].clear(),need[i].clear();
    solve2();
    if(ops.size()>ops2.size())swap(ops,ops2);
    ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)mas[ps++]=mx[i][ii];
    }
    for(int i=1;i<=n;i++)for(int ii=1;ii<=m;ii++)have[i][ii].clear(),need[i].clear();
    solve3();
    if(ops.size()>ops3.size())swap(ops,ops3);

    ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)mas[ps++]=mx[i][ii];
    }
    for(int i=1;i<=n;i++)for(int ii=1;ii<=m;ii++)have[i][ii].clear(),need[i].clear();
    solve4();
    if(ops.size()>ops4.size())swap(ops,ops4);

    ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)mas[ps++]=mx[i][ii];
    }
    for(int i=1;i<=n;i++)for(int ii=1;ii<=m;ii++)have[i][ii].clear(),need[i].clear();
    solve5();
    if(ops.size()>ops5.size())swap(ops,ops5);

    ps=1;
    for(int i=1;i<=n;i++){
        for(int ii=1;ii<=m;ii++)mas[ps++]=mx[i][ii];
    }
    for(int i=1;i<=n;i++)for(int ii=1;ii<=m;ii++)have[i][ii].clear(),need[i].clear();
    //solve6();
    //if(ops.size()>ops6.size())swap(ops,ops6);

    cout<<ops.size()<<"\n";
    for(auto [a,b]:ops)cout<<a<<" "<<b<<"\n";
    
}