#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int st,pl,stop,fin,prec,x1,y11,x2,y2,v1,v2,po,val,nr,i,j,k,n,Q,ras[20013],cod[309][309],t[90009],adev[90009],x[20013],y[20013],how[20013];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
char sir[900009];
vector < int > v[90009],init;
vector < int > ::iterator itt;
/////////////////////////////////////////
struct str
{
int v,p;
};
str a[90009];
bool cmp(str a,str b)
{
return a.v<b.v;
}
//////////////////////////////////////////
struct quer
{
int x,y,p,r;
};
quer Qu[20013];
bool cmpQ(quer a,quer b)
{
return a.r>b.r;
}
///////////////////////////////////////////
int tata(int x)
{
if(t[x]!=x) t[x]=tata(t[x]);
return t[x];
}
int main()
{
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
scanf("%d",&n);
scanf("%d\n",&Q);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
nr++;
cod[i][j]=nr;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=0;k<4;k++)
if(cod[i+dx[k]][j+dy[k]]!=0) v[cod[i][j]].push_back(cod[i+dx[k]][j+dy[k]]);
nr=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
nr++;
a[nr].p=nr;
scanf("%d",&a[nr].v);
po++;
}
for(i=1;i<=Q;i++)
{
scanf("%d",&x1);
scanf("%d",&y11);
scanf("%d",&x2);
scanf("%d",&y2);
Qu[i].x=cod[x1][y11];
Qu[i].y=cod[x2][y2];
Qu[i].p=i;
}
sort(a+1,a+nr+1,cmp);
val=0;
prec=0;
for(i=1;i<=nr;i++)
{
if(a[i].v!=prec) val++;
prec=a[i].v;
adev[val]=a[i].v;
a[i].v=val;
}
reverse(a+1,a+nr+1);
pl=1;
while(pl<=val) pl<<=1;
pl>>=1;
for(pl=pl;pl>=1;pl>>=1)
{
sort(Qu+1,Qu+Q+1,cmpQ);
memset(t,0,sizeof(t));
st=1;
for(i=1;i<=Q;i++)
{
while(a[st].v>=Qu[i].r+pl)
{
t[a[st].p]=a[st].p;
for(itt=v[a[st].p].begin();itt!=v[a[st].p].end();itt++)
if(t[*itt]!=0&&tata(*itt)!=tata(a[st].p)) t[tata(a[st].p)]=*itt;
st++;
}
if(t[Qu[i].x]!=0&&t[Qu[i].y]!=0&&tata(Qu[i].x)==tata(Qu[i].y)) Qu[i].r+=pl;
}
}
for(i=1;i<=Q;i++)
ras[Qu[i].p]=Qu[i].r;
for(i=1;i<=Q;i++)
printf("%d\n",adev[ras[i]]);
return 0;
}