#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 505;
int n, m;
int a[N][N] = {{0}};
bool vld[N] = {false};
bool vis[N][N] = {{false}};
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
void srh(int x, int y) {
vis[x][y] = true;
for (int k = 0; k < 4; k++) {
int vx = x + dx[k], vy = y + dy[k];
if (1 <= vx && vx <= n && 1 <= vy && vy <= m && a[x][y] > a[vx][vy] && !vis[vx][vy])
srh(vx, vy);
}
}
struct Seg {
int l, r;
Seg(int _l = 0, int _r = 0) :
l(_l), r(_r) {}
} s[N];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
bool flg = true;
int tot = 0;
for (int i = 1; i <= m; i++) {
memset(vis, false, sizeof vis);
srh(1, i);
int l = m + 1, r = 0;
for (int j = 1; j <= m; j++)
if (vis[n][j])
vld[j] = true, l = min(l, j), r = max(r, j);
if (l == m + 1)
continue;
for (int j = l; j <= r; j++)
if (!vis[n][j])
flg = false;
s[++tot] = Seg(l, r);
}
for (int i = 1; i <= m; i++)
flg = flg && vld[i];
if (!flg) {
int ans = 0;
for (int i = 1; i <= m; i++)
ans += !vld[i];
printf("0\n%d\n", ans);
return 0;
}
sort(s + 1, s + tot + 1, [](Seg x, Seg y) {
return x.l < y.l;
});
int p = 1, mxr = 0, ans = 0;
for (int i = 1; i <= tot; i++) {
if (s[i].l > p)
ans++, p = mxr + 1;
mxr = max(mxr, s[i].r);
}
if (p <= m)
ans++;
printf("1\n%d\n", ans);