int val[maxn][maxn],dp[maxn][maxn][9][9],mm[maxn];
void Rmq_init( int n , int m )
{
mm[0] = -1;
for ( int i=1 ; i<maxn ; i++ )
mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
for ( int i=1 ; i<=n ; i++ )
for ( int j=1 ; j<=m ; j++ )
dp[i][j][0][0] = val[i][j];
for ( int ii=0 ; ii<=mm[n] ; ii++ )
for ( int jj=0 ; jj<=mm[m] ; jj++ )
if ( ii+jj )
{
for ( int i=1 ; i+(1<<ii)-1<=n ; i++ )
for ( int j=1 ; j+(1<<jj)-1<=m ; j++ )
{
if ( ii ) dp[i][j][ii][jj] = Max( dp[i][j][ii-1][jj] , dp[i+(1<<(ii-1))][j][ii-1][jj] );
else dp[i][j][ii][jj] = Max( dp[i][j][ii][jj-1] , dp[i][j+(1<<(jj-1))][ii][jj-1] );
}
}
}
int Rmq_query( int x1 , int y1 , int x2 , int y2 )
{
int k1 = mm[x2-x1+1];
int k2 = mm[y2-y1+1];
x2 = x2-(1<<k1)+1;
y2 = y2-(1<<k2)+1;
return Max( Max( dp[x1][y1][k1][k2] , dp[x2][y1][k1][k2] ) , Max( dp[x1][y2][k1][k2] , dp[x2][y2][k1][k2] ) );
}