/*poc - prva kolona, kraj - poslednja kolona
valja - poslednja kolona gde se pojavio. Cuva i info o valjanosti
traje - poslednji red gde se pojavio
prvi - prvi red gde se pojavio
*/
#include <iostream>
using namespace std;

int main()
{ int i, j, k, kol, n, sum,rad;
  int *poc, *kraj, *valja, *traje, *prvi;
  cin >>n>>kol;
  prvi = new int [kol+1];  poc = new int[kol+1];
  kraj = new int [kol+1];  valja = new int[kol+1];
  traje = new int[kol+1];
  for(i=1;i<=kol;i++)
  {poc[i]=0; kraj[i]=0; prvi[i] = 0;
   valja[i]=0; traje[i]=0;
  }

  for(i=1;i<=n;i++)
    for(k=1;k<=n;k++)
    { cin>>rad;
      if(poc[rad] == 0)// tek se pojavio
        { prvi[rad]=i; poc[rad]= k; kraj[rad]=k;
          traje[rad] = i; valja[rad] = k;
        }
      else
        {if(valja[rad]>0)// jos je dobar
           {if(traje[rad]<(i-1)) valja[rad] = -1;// preskocio bar jedan red, ne valja
            else if(traje[rad]==(i-1))//bio u predhodnom redu
              { if((k==poc[rad])&&(valja[rad]==kraj[rad]))// prvi u redu i predhodni tacan
                    { traje[rad]=i; valja[rad]=k;}
                else valja[rad] = -1;
             }
            else // traje[rad]== i, u istom smo redu
              { if(valja[rad]==k-1)//ima predhodna kolona, popunjen red do sada
                 { valja[rad]++;
                   if(prvi[rad]==i) kraj[rad]++;//jos smo u prvom redu
                   else if(valja[rad]> kraj[rad]) valja[rad]=-1;//preso desnu granicu
                 }
                else valja[rad] = -1;// nepotpun red
              }
           }
        }
    }
   sum = 0;
   for(i=1;i<=kol;i++)
     if (valja[i]>0) sum++;
   cout<<sum;

  delete []prvi;  delete []poc;
  delete []kraj;  delete []valja;
  delete []traje;

  return 0;
}