马蜂不是很好看+—+,sorry
#include <bits/stdc++.h>
#define re register
#define il inline
const int N=5e2+2;
using namespace std;
il void read (int &ret) {
ret=0; char c=getchar();
while (c<'0' || c>'9') c = getchar ();
while (c>='0' && c<='9') { ret=(ret<<3)+(ret<<1)+c-'0'; c = getchar (); }
return ;}
il int max (int &a, int &b) { if (a<b) return b; return a; }
il int min (int &a, int &b) { if (a<b) return a; return b; }
il bool cmp (pair <int, int> &a, pair <int, int> &b) { if (a.first==b.first) return a.second>b.second; return a.first<b.first; }
int xx[]={-1, 0, 0, 1},
yy[]={0, -1, 1, 0};
int n, m,
p[N][N];
pair <int, int> to[N][N];//存该点灌溉的区间范围
bool vis[N][N];
il void dfs (int x, int y) {
if (vis[x][y]) return ;
vis[x][y]=true;
if (x==n) to[x][y].first=to[x][y].second=y;
int xn, yn;
for (re int i=0; i < 4; i++) {
xn=xx[i]+x, yn=yy[i]+y;
if (xn<1 || xn>n || yn<1 || yn>m) continue;
if (p[xn][yn] >= p[x][y]) continue;
dfs (xn, yn);
if (!to[x][y].first) to[x][y].first=to[xn][yn].first, to[x][y].second=to[xn][yn].second;
if (to[xn][yn].first) {
to[x][y].first = min (to[x][y].first, to[xn][yn].first);
to[x][y].second = max (to[x][y].second, to[xn][yn].second);
}
}
return ;}
signed main () {
read (n); read (m);
for (re int i=1; i <= n; i++)
for (re int j=1; j <= m; j++) read (p[i][j]);
for (re int i=1; i <= m; i++)
dfs (1, i);
int sum=0;
for (re int i=1; i <= m; i++) sum +=vis[n][i];
if (sum != m) {
printf ("0\n%d", m-sum);
return 0;
}
sort (to[1]+1, to[1]+m+1, cmp); //贪心求线段覆盖 for (int l=1; l <= m; l++) printf ("|||%d %d", to[1][l].first, to[1][l].second);
sum=1; int tail=to[1][1].second, i=1, t;
while (!to[1][i].first) tail=to[1][++i].second;
while (tail < m) {
t=tail;
while (to[1][++i].first < (tail+2) )
t = max (t, to[1][i].second);
tail=t;
sum++;
}
printf("1\n%d\n", sum);
return 0;
}