#include <cstdio>
#include <algorithm>
using namespace std;
const int auxx[4]={-1,0,1,0},auxy[4]={0,1,0,-1};
struct matrice
{
int x,y,val;
bool operator <(const matrice &aux) const
{
return val>aux.val;
}
}v1[100000];
struct query
{
int x1,y1,x2,y2,poz,val;
bool operator <(const query &aux) const
{
return val>aux.val;
}
}q[20010];
int v[310][310],rad[100000],sol[20010],n;
int radacina(int x,int y)
{
x=n*(x-1)+y;
int i=x,j=x;
for(;rad[i]!=i;i=rad[i]);
while(j!=i)
{
int a=rad[j];
rad[j]=i;
j=a;
}
return i;
}
void unire(int x1,int y1,int x2,int y2)
{
int x=radacina(x1,y1),y=radacina(x2,y2);
if(x!=y) rad[y]=x;
}
int main()
{
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
int m,nr=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&v[i][j]);
v1[++nr].x=i;
v1[nr].y=j;
v1[nr].val=v[i][j];
}
sort(v1+1,v1+1+nr);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2);
q[i].poz=i;
}
for(int step=19;step>=0;step--)
{
for(int i=1;i<=nr;i++) rad[i]=i;
sort(q+1,q+1+m);
for(int i=1,j=1;i<=m;i++)
{
for(;j<=nr && v1[j].val>=q[i].val+(1<<step);j++)
for(int k=0;k<4;k++)
{
int x=v1[j].x+auxx[k],y=v1[j].y+auxy[k];
if(x<1 || x>n || y<1 || y>n) continue;
if(v[x][y]>=q[i].val+(1<<step)) unire(v1[j].x,v1[j].y,x,y);
}
if(radacina(q[i].x1,q[i].y1)==radacina(q[i].x2,q[i].y2)) q[i].val+=1<<step;
}
}
for(int i=1;i<=m;i++) sol[q[i].poz]=q[i].val;
for(int i=1;i<=m;i++) printf("%d\n",sol[i]);
return 0;
}