#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <map>

#define pii pair<int, int>
#define S second
#define F first
#define pb push_back

using namespace std;

typedef long long ll;

const int MAXN = 160005;
int used[MAXN];
vector <vector <int>> d(MAXN);
ll n, m, u;
vector <int> rez;

bool dfs(int v, int k){
  if ((v == 0) && (k == u-1)) {
    rez.push_back(0);
    return true;
  }
  if (used[v] == true || (v == 0) || (k == u-1)) {return false;}
  used[v] = true;
  k++;
  for (int i = 0; i < d[v].size(); i++){
    if (dfs(d[v][i], k)) {
      rez.push_back(v);
      return true;
    }
  }
  used[v] = false;
  return false;
}

void solve (){
  cin >> n >> m;
  vector <int> IF(n);
  for (int i = 0; i < n; i++){
    used[i] = false;
    d[i].clear();
    IF[i] = 0;
  }

  ll x, y;
  u = 0;
  vector <int> v(n*m);
  vector <pair<int, int>> VP;
  
  for (int i = 0; i < n; i++){
    map <int, int> TT;
    for (int j = 0; j < m; j++){
      cin >> v[i*m+j];
      TT[v[i*m+j]-1]++;
    }
    
    vector <int> no;
    for (int j = 0; j < m; j++){
      if (TT[j] == 0) {no.pb(j);}
    }
    
    for (int j = 0; j < m; j++){
      if (TT[j] > 1) {
        VP.pb({j, 0});
        ll y = i*m; 
        while (v[y]-1 != j) {y++;}
        VP[VP.size()-1].S = y;
        
        for (int h = 0; h < no.size(); h++){
          d[u].push_back(no[h]);
        }
        u++;
      }
    }
  }
  
  vector <vector <int> > VM(m);
  for (int i = 0; i < u; i++){
    VM[VP[i].F].pb(i);
  }
  if (VP.size() == 3) {
    cout << "4\n";
    cout << VP[0].S+1 << " " << n*m+1 << "\n";
    cout << VP[1].S+1 << " " << VP[0].S+1 << "\n";
    cout << VP[2].S+1 << " " << VP[1].S+1 << "\n";
    cout << n*m+1 << " " << VP[2].S+1 << "\n";
    
  }
  return;
}

int main(){
  solve();

  return 0;
}


