#include<bits/stdc++.h>
using namespace std;
int n,m;
int h[505][505];
bool vis[505][505];
int dp[505];
bool f;
int cnt;
struct node{
int x,y;
}ct;
queue<node> Q;
node dst[505];
int xx,yy;
int ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&h[i][j]);
}
}
ct.x=1;
for(int i=1;i<=m;i++)
{
ct.y=i;
Q.push(ct);
}
while(!Q.empty())
{
ct=Q.front();
Q.pop();
xx=ct.x;
yy=ct.y;
if(vis[xx][yy]) continue;
vis[xx][yy]=1;
cnt++;
if(!vis[xx+1][yy]&&(h[xx+1][yy]<h[xx][yy])&&(xx<n))
{
ct.x=xx+1;
ct.y=yy;
Q.push(ct);
}
if(!vis[xx][yy+1]&&(h[xx][yy+1]<h[xx][yy])&&(yy<m))
{
ct.x=xx;
ct.y=yy+1;
Q.push(ct);
}
if(!vis[xx-1][yy]&&(h[xx-1][yy]<h[xx][yy])&&(xx>1))
{
ct.x=xx-1;
ct.y=yy;
Q.push(ct);
}
if(!vis[xx][yy-1]&&(h[xx][yy-1]<h[xx][yy])&&(yy>1))
{
ct.x=xx;
ct.y=yy-1;
Q.push(ct);
}
}
if(cnt!=n*m)
{
puts("0");
cnt=0;
for(int i=1;i<=m;i++)
{
if(!vis[n][i]) cnt++;
}
printf("%d",cnt);
return 0;
}
puts("1");
ct.x=1;
for(int i=1;i<=m;i++)
{
ct.y=i;
Q.push(ct);
memset(vis,0,sizeof(vis));
f=0;
while(!Q.empty())
{
ct=Q.front();
Q.pop();
xx=ct.x;
yy=ct.y;
if(vis[xx][yy]) continue;
vis[xx][yy]=1;
if(!vis[xx+1][yy]&&(h[xx+1][yy]<h[xx][yy])&&(xx<n))
{
ct.x=xx+1;
ct.y=yy;
Q.push(ct);
}
if(!vis[xx][yy+1]&&(h[xx][yy+1]<h[xx][yy])&&(yy<m))
{
ct.x=xx;
ct.y=yy+1;
Q.push(ct);
}
if(!vis[xx-1][yy]&&(h[xx-1][yy]<h[xx][yy])&&(xx>1))
{
ct.x=xx-1;
ct.y=yy;
Q.push(ct);
}
if(!vis[xx][yy-1]&&(h[xx][yy-1]<h[xx][yy])&&(yy>1))
{
ct.x=xx;
ct.y=yy-1;
Q.push(ct);
}
}
for(int j=1;j<=m;j++)
{
if(vis[n][j])
{
if(!f)
{
f=1;
dst[i].x=j;
}
dst[i].y=j;
}
}
}
memset(dp,0x3f,sizeof(dp));
for(int i=1;i<=m;i++)
{
if(dst[i].x==1) dp[i]=1;
}
for(int i=1;i<=m;i++)
{
if(dst[i].x==0&&dst[i].y==0) continue;
for(int j=1;j<i;j++)
{
if(dst[j].x==0&&dst[j].y==0) continue;
if(dst[j].y>=(dst[i].x-1))
{
dp[i]=min(dp[i],dp[j]+1);
}
}
}
ans=m;
for(int i=m;i>=1;i--)
{
if(dst[i].x==0&&dst[i].y==0) continue;
if(dst[i].y==m) ans=min(ans,dp[i]);
}
printf("%d",ans);
return 0;
}