#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=510;
typedef int LL;
LL ma[maxn][maxn],n,m,cnt=0;
bool vis[maxn][maxn],check[maxn][maxn];
struct P{
LL l=0x3f3f3f3f;
LL r=0;
}c[maxn];
bool cmp(P A,P B){
if(A.l==B.l) return A.r<B.r;
return A.l<B.l;
}
struct node{
LL x,y;
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
void bfs(LL x,LL y)
{
cnt++;
queue<node>q;q.push({x,y});
memset(vis,0,sizeof(vis));
vis[x][y]=1;check[x][y]=1;
while(!q.empty())
{
node now=q.front();q.pop();
LL nx=now.x;LL ny=now.y;
for(LL i=0;i<4;i++)
{
LL tx=nx+dx[i];LL ty=ny+dy[i];
if(ma[tx][ty]<ma[nx][ny]&&!vis[tx][ty]&&tx>=1&&tx<=n&&ty>=1&&ty<=m)
{
vis[tx][ty]=1;check[tx][ty]=1;
q.push({tx,ty});
if(tx==n)
{
c[cnt].l=min(c[cnt].l,ty);
c[cnt].r=max(c[cnt].r,ty);
}
}
}
}
return;
}
int main(void)
{
scanf("%d%d",&n,&m);
for(LL i=1;i<=n;i++)
{
for(LL j=1;j<=m;j++){
scanf("%d",&ma[i][j]);
}
}
for(LL j=1;j<=m;j++)
{
if(ma[1][j]>=ma[1][j-1]){
bfs(1,j);
}
}
LL sum=0;
for(LL j=1;j<=m;j++)
{
if(check[n][j]==0){
sum++;
}
}
if(sum>0){
printf("0\n%d\n",sum);return 0;
}
sort(c+1,c+cnt+1,cmp);
LL ans=0;
LL maxv=0;LL tmp=0;
for(LL i=1;i<=cnt;i++)
{
if(c[i].l>m) break;
if(c[i].l<=1+maxv) tmp=max(tmp,c[i].r);
else
{
maxv=tmp;
ans++;
tmp=max(tmp,c[i].r);
}
}
if(maxv!=m) ans++;
printf("1\n%d\n",ans);
return 0;
}