#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <vector>
using namespace std;
int n,m;
int getcc(pair<int,int> q)
{
    //cout<<"HO";
    return q.first*m+q.second;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //int n,m;
    cin >>n>>m;
    srand (time(NULL));
    int tab[n][m];
    int pos[n][m];
    int qeer=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin >> tab[i][j];
            tab[i][j]--;
            pos[i][j]=qeer;
            qeer++;
        }
    }
    int kol[n][m];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            kol[i][j]=0;
        }
    }
    vector<pair<int,int> > izb[m];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            kol[i][tab[i][j]]++;
            if(kol[i][tab[i][j]]>=2)
            {
                izb[tab[i][j]].push_back({i,j});
            }
        }
    }
    for(int i=0;i<m;i++) reverse(izb[i].begin(),izb[i].end());
    vector<int> ned[n];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            if(kol[i][j]==0) ned[i].push_back(j);
    }
    int res=0;
    for(int i=0;i<n;i++) res+=ned[i].size();
    vector<pair<int,int> > obm;obm.clear();
    while(true)
    {
    int qqq=0;
    while(izb[qqq].size()==0 && qqq<m) qqq++;
    if(qqq==m)
    {
        break;
    }
    obm.push_back({getcc(izb[qqq][izb[qqq].size()-1]),n*m});
    pair<int,int> pp=izb[qqq][izb[qqq].size()-1];

    int tbl=pp.first;
    izb[qqq].pop_back();
    while(true)
    {
     //   cout<<"HI";
        int l=ned[tbl][ned[tbl].size()-1];
        ned[tbl].pop_back();
        if(izb[l].size()==0)
        {
            obm.push_back({n*m,getcc(pp)});
            break;
        }
        else
        {
            pair<int,int> nex=izb[l][izb[l].size()-1];
            izb[l].pop_back();
            obm.push_back({getcc(nex),getcc(pp)});
            pp=nex;tbl=pp.first;
        }
     //   cout<<"end";
    }

    }
   // cout<<"HI"<<obm.size();;
    for(int i=0;i<m;i++) izb[i].clear();
    for(int i=0;i<n;i++) ned[i].clear();
    for(int i=0;i<n;i++) for(int j=0;j<m;j++) kol[i][j]=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            kol[i][tab[i][j]]++;
            if(kol[i][tab[i][j]]>=2)
            {
                izb[tab[i][j]].push_back({i,j});
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
            if(kol[i][j]==0) ned[i].push_back(j);
    }
    res=0;
    for(int i=0;i<n;i++) res+=ned[i].size();
    vector<pair<int,int> > obm1;obm1.clear();
    while(true)
    {
    int qqq=0;
    while(izb[qqq].size()==0 && qqq<m) qqq++;
    if(qqq==m)
    {
        break;
    }
    obm1.push_back({getcc(izb[qqq][izb[qqq].size()-1]),n*m});
    pair<int,int> pp=izb[qqq][izb[qqq].size()-1];

    int tbl=pp.first;
    izb[qqq].pop_back();
    while(true)
    {

        int l=ned[tbl][ned[tbl].size()-1];
        ned[tbl].pop_back();
        if(izb[l].size()==0)
        {
            obm1.push_back({n*m,getcc(pp)});
            break;
        }
        else
        {
            pair<int,int> nex=izb[l][izb[l].size()-1];
            izb[l].pop_back();
            obm1.push_back({getcc(nex),getcc(pp)});
            pp=nex;tbl=pp.first;
        }
     //   cout<<"end";
    }

    }
    if(obm.size()>obm1.size()) swap(obm,obm1);
    for(int shuffle=0;shuffle<30;shuffle++)
    {
        for(int i=0;i<m;i++) izb[i].clear();
        for(int i=0;i<n;i++) ned[i].clear();
        for(int i=0;i<n;i++) for(int j=0;j<m;j++) kol[i][j]=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                kol[i][tab[i][j]]++;
                if(kol[i][tab[i][j]]>=2)
                {
                    izb[tab[i][j]].push_back({i,j});
                }
            }
        }
        for(int i=0;i<m;i++) if(rand()%2==0) reverse(izb[i].begin(),izb[i].end());
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                if(kol[i][j]==0) ned[i].push_back(j);
        }
        res=0;
        for(int i=0;i<n;i++) res+=ned[i].size();
        obm1.clear();
        while(true)
        {
        int qqq=0;
        while(izb[qqq].size()==0 && qqq<m) qqq++;
        if(qqq==m)
        {
            break;
        }
        obm1.push_back({getcc(izb[qqq][izb[qqq].size()-1]),n*m});
        pair<int,int> pp=izb[qqq][izb[qqq].size()-1];

        int tbl=pp.first;
        izb[qqq].pop_back();
        while(true)
        {

            int l=ned[tbl][ned[tbl].size()-1];
            ned[tbl].pop_back();
            if(izb[l].size()==0)
            {
                obm1.push_back({n*m,getcc(pp)});
                break;
            }
            else
            {
                pair<int,int> nex=izb[l][izb[l].size()-1];
                izb[l].pop_back();
                obm1.push_back({getcc(nex),getcc(pp)});
                pp=nex;tbl=pp.first;
            }
         //   cout<<"end";
        }

        }
        if(obm.size()>obm1.size()) swap(obm,obm1);
    }
    cout<<obm.size()<<'\n';
        for(int i=0;i<obm.size();i++) cout<<obm[i].first+1<<' '<<obm[i].second+1<<'\n';
}
