#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int n,m; const int N=503; bool vis[N][N];//因为可能是死路,所以l,r不能表示这个点有没有更新过,所以要加vis标记 int d[N][N]; int l[N][N],r[N][N]; int py[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; void dfs(int x,int y) { vis[x][y]=true; for(int i=0;i<4;i++) { int nx=x+py[i][0]; int ny=y+py[i][1]; if(!nx || !ny || nx>n || ny>m || d[nx][ny]>=d[x][y] ) continue; if(!vis[nx][ny]) dfs(nx,ny); l[x][y]=min(l[x][y],l[nx][ny]); r[x][y]=max(r[x][y],r[nx][ny]); } } struct node { int l,r; bool operator < (const node & o) const { return l<o.l; } }xl[N]; int main() { memset(l,0x3f,sizeof(l)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&d[i][j]); for(int i=1;i<=m;i++) l[n][i]=r[n][i]=i; for(int i=1;i<=m;i++) if(!vis[1][i] && d[1][i]>=d[1][i+1] )//>=都不能被后面一个替代,因为等于的不查可能最后就不成功了 dfs(1,i); int fail=0; for(int i=1;i<=m;i++) if(!vis[n][i]) fail++; if(fail) { printf("0 %d ",fail); return 0; } else printf("1 "); int nw=1,cnt=0; while(nw<=m) { int rr=nw-1; for(int i=1;i<=m;i++) if(l[1][i]<=nw && rr<r[1][i] ) rr=r[1][i]; cnt++; nw=rr+1; } printf("%d ",cnt); return 0; }