#include <cstdio>
#include <cstring>
using namespace std;
FILE *f=fopen("matrice2.in","r");
FILE *g=fopen("matrice2.out","w");
#define nmax 305
int A[nmax][nmax],n,q,hmax;
bool M[nmax][nmax];
int x1,y1,x2,y2;
inline int min(int a,int b)
{
if(a<b) return a;
return b;
}
void read()
{
int i,j;
fscanf(f,"%d %d",&n,&q);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
fscanf(f,"%d",&A[i][j]);
if(hmax<A[i][j])
hmax=A[i][j];
}
}
bool lee(int l1,int c1,int l2,int c2,int val)
{
if(l1==l2&&c1==c2)
return true;
bool ok=false;
M[l1][c1]=true;
if(!ok&&A[l1-1][c1]>=val&&!M[l1-1][c1])
ok=lee(l1-1,c1,l2,c2,val);
if(!ok&&A[l1+1][c1]>=val&&!M[l1+1][c1])
ok=lee(l1+1,c1,l2,c2,val);
if(!ok&&A[l1][c1+1]>=val&&!M[l1][c1+1])
ok=lee(l1,c1+1,l2,c2,val);
if(!ok&&A[l1][c1-1]>=val&&!M[l1][c1-1])
ok=lee(l1,c1-1,l2,c2,val);
//M[l1][c1]=false;
return ok;
}
void init()
{
for(int i=1;i<=n;i++)
memset(M[i],false,sizeof(M[i]));
}
int cbin()
{
int l,r,m,ret;
bool ok;
l=1;
r=min(A[x2][y2],A[x1][y1]);
m=(l+r)>>1;
while(l<=r)
{
ok=false;
init();
ok=lee(x1,y1,x2,y2,m);
if(ok) //daca a mers
{
l=m+1;
ret=m;
}
else
r=m-1;
m=(l+r)>>1;
}
return ret;
}
int main()
{
read();
int i;
for(i=1;i<=q;i++)
{
fscanf(f,"%d %d %d %d",&x1,&y1,&x2,&y2);
fprintf(g,"%d\n",cbin());
}
return 0;
}