#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
const int edge=505,
dx[4]={0,0,-1,1},
dy[4]={1,-1,0,0};
int h[edge][edge];bool need[edge];
int N,M,city,station;
int dp[edge];
struct point{int st,en;}a[edge]={0};
void input()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
scanf("%d",&h[i][j]);
}
bool f[edge][edge];
void search(const int &x,const int &y)
{
if (x>N||y>M||x<1||y<1) return;
f[x][y]=true;
int x1,y1;
for(int i=0;i<=3;i++)
{
x1=x+dx[i];
y1=y+dy[i];
if(h[x][y]>h[x1][y1]&&!f[x1][y1])
search(x1,y1);
}
}
void count()
{
for(int j=1;j<=M;j++)
if(!f[N][j]) city++;
}
int main()
{
input();
for(int i=1;i<=M;i++)
search(1,i);
count();
if (city)
{
printf("0\n%d\n",city);
//system("pause");
return 0;
}
for(int i=1;i<=M;i++){
if(need[i])continue;
memset(f,0,sizeof(f));
f[1][i]=true;
search(1,i);
//for(int j=1;j<=M;j++)cout<<f[N][j]<<' ';cout<<endl;
if(f[N][1])a[i].st=1;
if(f[N][M])a[i].en=M;
for(int j=1;j<=M;j++){
if(f[N][j]&&!f[N][j-1]&&j>1)a[i].st=j;
if(f[N][j]&&!f[N][j+1]&&j<M)a[i].en=j;
}
//cout<<a[i].st<<' '<<a[i].en<<endl;
for(int j=1;j<=M;j++)
if(j!=i&&f[1][j])need[j]=true;
}
for(int i=1;i<=M;i++)dp[i]=1000000000;
for(int i=1;i<=M;i++)
for(int j=1;j<=M;j++)
if(!need[j]&&i<=a[j].en)
dp[i]=min(dp[i],dp[a[j].st-1]+1);
printf("1\n%d\n",dp[M]);
//system("pause");
return 0;
}
/**************************************************************
Problem: 2299
User: admin
Language: C++
Result: Accepted
Time:185 ms
Memory:8736 kb
****************************************************************/