User: axuhongbo
Time: 2019-10-02 17:14:00
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#define itn int
#define reaD read
#define N 505
using namespace std;

int n, m, cnt, mp[N][N], l[N][N], r[N][N];
int u[4] = { -1, 0, 1, 0 }, v[4] = { 0, 1, 0, -1 };
struct node {
    int x, y;
};
bool vis[N][N];


void dfs(int x, int y) {
    vis[x][y] = 1;
    for (int i = 0; i < 4; i++) {
        int xx = x + u[i], yy = y + v[i];
        if (xx < 1 || xx > n || yy < 1 || yy > m)
            continue;
        if (mp[xx][yy] >= mp[x][y])
            continue;
        if (!vis[xx][yy])
            dfs(xx, yy);
        l[x][y] = min(l[x][y], l[xx][yy]);
        r[x][y] = max(r[x][y], r[xx][yy]);
    }
}

int main() {
    cin>>n;
    cin>>m;
    //m = read();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) cin>>mp[i][j];
    memset(l, 0x3f, sizeof(l));
    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])
            dfs(1, i);
    for (int i = 1; i <= m; i++)
        if (!vis[n][i])
            cnt++;
    if (cnt) {
        printf("0\n%d\n", cnt);
        return 0;
    }
    int left = 1, right = 0;
    while (left <= m) {
        for (int i = 1; i <= m; i++)
            if (l[1][i] <= left)
                right = max(right, r[1][i]);
        cnt++;
        left = right + 1;
    }
    printf("1\n%d\n", cnt);
    return 0;
}