#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+5;
int n,m,cnt=0,grid[maxn][maxn];
int dx[]={0,0,1,0,-1};
int dy[]={0,1,0,-1,0};
int vis[maxn][maxn],visg[maxn][maxn];
struct seg
{
int l,r;
seg();
seg(int L,int R);
}pool[maxn];
seg::seg(){}
seg::seg(int L,int R){l=L,r=R;}
bool cmp(seg a,seg b){return a.l<b.r;}
void bfs(int sx,int sy)
{
if(vis[sx][sy])return;
queue< pair<int,int> >q;
q.push(make_pair(sx,sy));
vis[sx][sy]=1;int L=sy,R=sy;
while(!q.empty())
{
int x=q.front().first,y=q.front().second,cur=grid[x][y];q.pop();
for(int i=1;i<=4;++i)
{
int tx=x+dx[i];
int ty=y+dy[i];
if(tx<1 or tx>n or ty<1 or ty>m or grid[tx][ty]>=cur)continue;
if(!vis[tx][ty])
{
q.push(make_pair(tx,ty));
vis[tx][ty]=1;
}
L=min(L,ty);
R=max(R,ty);
}
}
pool[++cnt]=seg(L,R);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin>>grid[i][j];
for(int i=1;i<=m;++i)
bfs(1,i);
int flag=0,zeros=0;
for(int i=1;i<=m;++i)
{
if(!vis[n][i])flag=1,++zeros;
}
if(flag)
{
cout<<0<<endl<<zeros<<endl;
return 0;
}
int p1=1,ans=0;
while(p1<=m)
{
int p2=0;
for(int i=1;i<=cnt;++i)
if(pool[i].l<=p1)p2=max(p2,pool[i].r);
++ans;
p1=p2+1;
}
puts("1");
cout<<ans<<endl;
}