#include<bits/stdc++.h>
using namespace std;
int n,m;
int mp[510][510];
struct node{
int l,r;
}a[2010];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
bool flag[510][510];
bool f[510][510];
void bfs(int x,int y){
queue<pair<int,int> >q;
q.push(make_pair(x,y));
flag[x][y]=1;
f[x][y]=1;
while(q.size()){
pair<int,int>nd=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=nd.first+dx[i];
int ny=nd.second+dy[i];
if(nx<=0||ny<=0||nx>n||ny>m) continue;
if(mp[nx][ny]<mp[nd.first][nd.second]){
flag[nx][ny]=1;
f[nx][ny]=1;
q.push(make_pair(nx,ny));
}
}
}
}
int lp[2010];
bool cmp(node x,node y){
if(x.l!=y.l) return x.l<y.l;
return x.r>y.r;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
cin>>n>>m;
int fx,fy,zx,zy;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>mp[i][j];
}
}
for(int i=1;i<=m;i++){
if(f[1][i]) continue;
bfs(1,i);
bool vis=0;
for(int j=1;j<=m;j++){
if(flag[n][j]){
lp[j]=1;
}
if(flag[n][j]&&(!vis)){
a[i].l=j;vis=1;a[i].r=j;
}
if(flag[n][j]&&(vis)&&j==m){
a[i].r=m;
}
if(!flag[n][j]&&vis){
a[i].r=j-1;break;
}
}
memset(flag,0,sizeof(flag));
}
int ans=0;
for(int i=1;i<=m;i++){
ans+=lp[i];
}
if(ans!=m){
cout<<0<<'\n'<<m-ans<<'\n';return 0;
}
sort(a+1,a+1+m,cmp);
int id;
for(int i=1;i<=m;i++){
if(a[i].l!=0){
id=i;break;
}
}
int num=1;
pair<int,int>maxn=make_pair(0,0);
for(int i=id+1;i<=m;i++){
if(a[i].l<=a[id].r+1){
if(a[i].r>maxn.first){
maxn=make_pair(a[i].r,i);
}
}
else{
id=maxn.second;
maxn=make_pair(0,0);++num;
}
}
if(num==1)
cout<<1<<"\n"<<num;
else cout<<1<<'\n'<<num+1;
return 0;
}