#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int r, c;//全局变量自动初始化为零
int maps[201][201], memstate[201][201];//前者储存地图数据,后面那货储存
//每一点路径的最大值来记忆,便于后面衔接减少时间浪费
int droad[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };//分别向上向下向左向右
void read();
void findans(int target);
int dfs(int x, int y);//行和列
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> r >> c;
read();//读入数据
findans(0);//寻找答案并输出
return 0;
}
void read() {
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++)
cin >> maps[i][j];
}
void findans(int target) {
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
target = max(target, dfs(i, j));//每次寻找一条最长的路径
}
}
printf("%d", target);
}
int dfs(int x, int y) {
if (memstate[x][y]) {//如果这一点被探索过的话,返回该节点能产生的最大值
return memstate[x][y];
}
memstate[x][y] = 1;//该点算一个长度(初始长度)
for (int i = 0; i < 4; i++) {
int dx = droad[i][0] + x;//行的变化
int dy = droad[i][1] + y;//列的变化
if (dx > 0 && dx <= r && dy > 0 && dy <= c && maps[x][y] > maps[dx][dy]) {//如果越界或是上坡的话,不满足
dfs(dx, dy);//满足条件,沿着该路径继续探索
memstate[x][y] = max(memstate[x][y], memstate[dx][dy] + 1);//更新记忆的节点最大值,+1是为了补探索的当前点
}
}
return memstate[x][y];//返回节点的最大值(其实最后一次才有用)
}