#include<bits/stdc++.h>
#define int long long
using namespace std;
struct Node{
int x;
int y;
};
struct li{
int l;
int r;
};
li c[507];
int n,m;
int _M[507][507];
int vis[507][507];
int l[507],r[507];
int ju[507];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int cnt;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void bfs(int s){
c[s].l=0x7fffffff;
c[s].r=-1;
queue<Node> q;
q.push(Node{1,s});
while(!q.empty()){
Node tmp=q.front();
q.pop();
if(tmp.x==n){
c[s].l=min(c[s].l,tmp.y);
c[s].r=max(c[s].r,tmp.y);
}
for(int i=0;i<4;i++){
int nx=tmp.x+dx[i];
int ny=tmp.y+dy[i];
if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny]==s){
continue;
}
if(_M[nx][ny]>=_M[tmp.x][tmp.y]){
continue;
}
vis[nx][ny]=s;
q.push(Node{nx,ny});
}
}
}
bool cmp1(li a,li b){
return a.l<b.l;
}
bool cmp2(li a,li b){
return a.r<b.r;
}
signed main(){
memset(l,0x3f,sizeof(l));
memset(r,-1,sizeof(r));
n=read();
m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
_M[i][j]=read();
}
}
int sum=0;
for(int i=1;i<=m;i++){
bfs(i);
if(c[i].r!=-1){
ju[c[i].l]+=1;
ju[c[i].r+1]-=1;
}
else{
c[i].l=c[i].r=0x7fffffff;
}
}
cnt=0;
for(int i=1;i<=m;i++){
ju[i]+=ju[i-1];
if(ju[i]==0){
cnt++;
}
}
if(cnt!=0){
cout<<0<<endl<<cnt;
return 0;
}
sort(c+1,c+n+1,cmp1);
int rmax=c[1].r;
int j=1;
int k=1;
bool flag=0;
while(j<=m){
int maxn=0;
while(c[k].l<=j){
maxn=max(maxn,c[k++].r);
}
cnt++;
j=maxn+1;
}
cout<<1<<endl<<cnt;
return 0;
}