#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; 
        //cout << "Y - " << y << " " << v[y] << "\n";
        while (v[y]-1 != j) {y++;}
        VP[VP.size()-1].S = y;
        //cout << "Y - " << y << "\n";
        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++){
    //if (d[i].size() > 0) {
      VM[VP[i].F].pb(i);
    //}
  }

  for (int i = 0; i < d.size(); i++){
    ll z = d[i].size();
    for (int j = 0; j < z; j++){
      int U = d[i][j];
      d[i][j] = VM[U][0];
      for (int h = 1; h < VM[U].size(); h++){
        d[i].pb(VM[U][h]);
      }
    }
  }
/*
  for (int i = 0; i < u; i++){
    cout << VP[i].F << " " << VP[i].S << " ";
    for (int j = 0; j < d[i].size(); j++){
      cout << d[i][j] << " ";
    }
    cout << "\n";
  }*/
/* 
  for (int i = 0; i < n; i++){
    if (d[i].size() == 0 || IF[i] == 0) {printf("NO\n"); return;}
  }
*/

  for (size_t i = 0; i < d[0].size(); i++){
    if (dfs(d[0][i], 0)) {
      printf("%lld\n", u+1);
      //cout << "YES\n"; 
      //cout << "1 ";
      rez.pb(u);
      VP.pb({n*m, n*m});
      for (int j = rez.size()-1; j > 0; j--) {
        printf("%lld %lld\n", VP[rez[j-1]].S+1, VP[rez[j]].S+1);
      }
      printf("%lld %lld\n", VP[rez[rez.size()-1]].S+1, VP[rez[0]].S+1);
      return;
    }    
  }
  
  
  printf("NO\n");
  return;
}

int main(){
  solve();

  return 0;
}

