#include<stdio.h>
#include<algorithm>
using namespace std;
#define pi pair<int,int>
#define pii pair< pi , int>
#define piii pair< pair< pi,pi > ,int>
#define mp make_pair
#define f first
#define s second
#define x f.f
#define y f.s
#define z second
#define px1 f.f.f
#define py1 f.f.s
#define px2 f.s.f
#define py2 f.s.s
#define NMAX 305
#define NNMAX 90005
#define QMAX 20005
pi b[NNMAX];
pi tata[NMAX][NMAX];
pii event[NNMAX],newevent[NNMAX];
int grad[NMAX][NMAX],a[NMAX][NMAX];
int sol[QMAX],nr,newnr,n,m,nr0,nr1;
piii q[QMAX],vect0[QMAX],vect1[QMAX];
char g[NMAX][NMAX],viz[NNMAX];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
pi find(pi a)
{
if(tata[a.f][a.s]==a)
return a;
tata[a.f][a.s]=find(tata[a.f][a.s]);
return tata[a.f][a.s];
}
void baga(pi p)
{
int sx,sy;
g[p.f][p.s]=1;
for(int i=0;i<4;i++)
{
sx=p.f+dx[i];
sy=p.s+dy[i];
if(sx<1 || sx>n || sy<1 || sy>n || !g[sx][sy])
continue;
pi t1=find(mp(p.f,p.s));
pi t2=find(mp(sx,sy));
if(t1==t2)
continue;
if(grad[t1.f][t1.s]>grad[t2.f][t2.s])
{
tata[t2.f][t2.s]=t1;
grad[t1.f][t1.s]+=grad[t2.f][t2.s];
}
else
{
tata[t1.f][t1.s]=t2;
grad[t2.f][t2.s]+=grad[t1.f][t1.s];
}
}
}
int verifica(int pq)
{
pi t1=find(mp(q[pq].px1,q[pq].py1));
pi t2=find(mp(q[pq].px2,q[pq].py2));
return t1==t2;
}
inline int cmp(const pi& p1,const pi& p2)
{
return a[p1.f][p1.s]>a[p2.f][p2.s];
}
int main ()
{
int i,j,last,stop=0;
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&q[i].px1,&q[i].py1,&q[i].px2,&q[i].py2);
q[i].z=i;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
b[(i-1)*n+j]=mp(i,j);
sort(b+1,b+n*n+1,cmp);
event[0].z=0;
event[2].z=n*n+1;
event[nr=1]=mp(mp(1,m),(n*n+1)/2);
while(!stop)
{
/*printf("Am un nou nr=%d si am:",nr);
for(i=1;i<=m;i++)
printf("%d ",sol[i]);
printf("\n"); */
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
tata[i][j]=mp(i,j);
grad[i][j]=1;
g[i][j]=0;
}
newnr=0;
last=0;
stop=1;
for(i=1;i<=nr;i++)
{
if(viz[event[i].z])
{
newevent[++newnr]=event[i];
continue;
}
stop=0;
//printf("Calculez pt %d mai exact pt valoare %d\n",event[i].z,a[b[event[i].z].f][b[event[i].z].s]);
viz[event[i].z]=1;
for(j=last+1;j<=event[i].z;j++)
{
baga(b[j]);
// if(event[i].z==9)
// printf("Am bagat elementul %d %d cu valoarea %d\n",b[j].f,b[j].s,a[b[j].f][b[j].s]);
}
last=event[i].z;
nr0=0;
nr1=0;
for(j=event[i].x;j<=event[i].y;j++)
if(verifica(j))
{
vect1[++nr1]=q[j];
//printf("Cel deal %d-lea query a trecut\n",q[j].z);
}
else
{
//printf("%d nu a trecut\n",q[j].z);
vect0[++nr0]=q[j];
}
for(j=1;j<=nr1;j++)
sol[vect1[j].z]=a[b[event[i].z].f][b[event[i].z].s];
if(nr1)
{
for(j=event[i].y-nr1+1;j<=event[i].y;j++)
q[j]=vect1[j-event[i].y+nr1];
newevent[++newnr]=mp(mp(event[i].y-nr1+1,event[i].y),(event[i].z+event[i-1].z)/2);
}
newevent[++newnr]=event[i];
if(nr0)
{
for(j=event[i].x;j<=event[i].x+nr0-1;j++)
q[j]=vect0[j-event[i].x+1];
newevent[++newnr]=mp(mp(event[i].x,event[i].x+nr0-1),(event[i+1].z+event[i].z)/2);
}
}
for(i=1;i<=newnr;i++)
event[i]=newevent[i];
nr=newnr;
event[nr+1].z=n*n+1;
}
for(i=1;i<=m;i++)
printf("%d\n",sol[i]);
return 0;
}