import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
//使用记忆化数组 记录每个点的最大滑动长度
//遍历每个点作为起点
//然后检测该点四周的点 如果可以滑动到其他的点
//那么该点的最大滑动长度 就是其他可以滑到的点的滑动长度+1
//dp[i][j] = max(dp[i][j-1], dp[i][j+1],dp[i-1][j],dp[i+1][j])
public class Main {
static int N = 410;
static int n,m;
static int[][] h = new int[N][N],f = new int[N][N];//h是输入的数组,f是记忆化搜索数组;
static int[] dx = new int[]{-1,0,1,0};
static int[] dy = new int[]{0,1,0,-1};
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
h[i][j] = sc.nextInt();
}
}
for(int i=0;i<n;i++) Arrays.fill(f[i],-1);//初始化一个f[][],计算的时候如果f[i][j]是-1,那么代表没计算过,如果计算过直接return
int res = 0;
for(int i=0;i<n;i++)//每个都枚举一个,看看在哪里走取最大值//找到从当前位置往下走的最大路径,再取最大值,
{
for(int j=0;j<m;j++)
{
res = Math.max(res,dp(i,j));
}
}
System.out.println(res);
}
static int dp(int x,int y)
{
if(f[x][y]!=-1) return f[x][y];
f[x][y] = 1;
for(int i=0;i<4;i++)
{
int a = x+dx[i];
int b = y+dy[i];
if(a>=0 && a<n && b>=0 && b<m && h[a][b]<h[x][y])//检测该点四周的点 如果可以滑动到其他的点
{
f[x][y] = Math.max(f[x][y],dp(a,b)+1);//那么该点的最大滑动长度 就是其他可以滑到的点的滑动长度+1
}
}
return f[x][y];
}
}