#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
****************************************************************/