#include<fstream>
#define Nmax 100100
#define M 310
#include<vector>
#include<algorithm>
using namespace std;
ifstream f("matrice2.in");
ofstream g("matrice2.out");
int dx[]={0,0,0,-1,1};
int dy[]={0,-1,1,0,0};
vector<int> v[Nmax];
struct cel{ int k,p;}V[Nmax];
struct que{ int a,b,st,dr,ind;}q[Nmax];
int dpa( que A,que B ){return A.a<B.a;};
int dpi( que A,que B ){return A.ind<B.ind;};
int dpk( cel A,cel B ){return A.k<B.k;};
int i,n,m,T[Nmax],VA[Nmax],N,val,k,t1,x,ic,jc,t2,t,vm,po,R[Nmax],xc,A[M][M],j,yc,xu,yu;
void unite(int x,int y)
{
if(R[x]<=R[y])
{
T[x]=y;
if(R[x]==R[y])
R[y]++;
}
else
T[y]=x;
}
int find(int x)
{
int aux=x;
while(x!=T[x])
x=T[x];
int taso=x;
x=aux;
while(x!=taso)
{
aux=T[x];
T[x]=taso;
x=aux;
}
return taso;
}
int main ()
{
f>>n>>m;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
{
f>>V[(i-1)*n+j].k;
V[(i-1)*n+j].p=(i-1)*n+j;
A[i][j]=(i-1)*n+j;
}
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
for(k=1;k<=4;++k)
{
ic=i+dx[k];
jc=j+dy[k];
if(ic<1||jc<1||ic>n||jc>n)
continue;
v[A[i][j]].push_back(A[ic][jc]);
}
N=n*n;
sort(V+1,V+N+1,dpk);
for(i=1;i<=m;++i)
{
f>>xu>>yu>>xc>>yc;
q[i].st=A[xu][yu];
q[i].dr=A[xc][yc];
q[i].ind=i;
}
vm=V[N].k;
for(i=1;i<=N;++i)
VA[V[i].p]=V[i].k;
for(po=1;po<=vm;po<<=1);
po>>=1;
for(;po;po>>=1)
{
if(po==1)
{
po++;
po--;
}
j=N;
sort(q+1,q+m+1,dpa);
for(i=1;i<=N;++i)
R[i]=1,T[i]=i;
for(i=m;i>=1;i--)
{
val=q[i].a+po;
for(;j>=1;--j)
{
if(V[j].k<val)
break;
x=V[j].p;
if(V[j].p==2&&po==1)
{
po++;
po--;
}
t1=find(x);
for(t=0;t<v[x].size();++t)
{
if(VA[v[x][t]]<val)
continue;
t2=find(v[x][t]);
if(t2!=t1)
unite(t1,t2);
t1=find(x);
}
}
t1=find(q[i].st);
t2=find(q[i].dr);
if(t1==t2)
q[i].a+=po;
}
}
sort(q+1,q+m+1,dpi);
for(i=1;i<=m;++i)
g<<q[i].a<<"\n";
return 0;
}