#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int d1[]={0,0,1,-1,0};
const int d2[]={0,1,0,0,-1};
int l,maxval,i,j,k,x1,y1,x2,y2,p,u,m,i1,q,n,a[302][302],ap[302][302],fr[1000002],v[90002];
queue < pair < int, int > > cc;
int min(int a,int b)
{
if(a<b) return a;
return b;
}
int ok(int m)
{
int i1,j1;
if(a[x1][y1]<m) return 0;
if(a[x2][y2]<m) return 0;
memset(ap,0,sizeof(ap));
ap[x1][y1]=1;
while(!cc.empty()) cc.pop();
cc.push(make_pair(x1,y1));
while(!cc.empty())
{
pair<int,int> xx=cc.front();
for(k=1;k<=4;k++)
{
i1=xx.first+d1[k];
j1=xx.second+d2[k];
if(ap[i1][j1]==0&&a[i1][j1]>=m)
{
cc.push(make_pair(i1,j1));
ap[i1][j1]=1;
if(i1==x2&&j1==y2) return 1;
}
}
cc.pop();
}
return 0;
}
int main()
{
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
scanf("%d",&n);
scanf("%d",&q);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
fr[a[i][j]]++;
if(a[i][j]>maxval) maxval=a[i][j];
}
for(i=1;i<=maxval;i++)
if(fr[i]>0)
{
l++;
v[l]=i;
}
for(i1=1;i1<=q;i1++)
{
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
u=l;
p=1;
while(p<=u)
{
m=(p+u)/2;
if(ok(v[m])==0) u=m-1;
else
{
if(ok(v[m+1])==0||m==u)
{
printf("%d\n",v[m]);
break;
}
p=m+1;
}
}
}
return 0;
}