#include <bits/stdc++.h>
#define DIM 310
#define DIMM 90010
using namespace std;
struct cell{
int cod,val,x,y;
} v[DIMM];
struct queryy{
int x,y,x2,y2,sol,poz;
} qry[DIMM];
int t[DIMM],a[DIM][DIM],ans[DIMM];
int di[] = {-1,1,0,0};
int dj[] = {0,0,-1,1};
int n,i,j,x,y,q,k;
inline int cmp (cell a, cell b){
return a.val > b.val;
}
inline int cmp2 (queryy a, queryy b){
return a.sol > b.sol;
}
inline int inmat (int i, int j){
if (i >= 1 && j >= 1 && i <= n && j <= n)
return 1;
return 0;
}
int cod (int i, int j){
return (i-1) * n + j;
}
int get_rad (int x){
while (t[x] > 0)
x = t[x];
return x;
}
void _union (int x, int y){
int radx = get_rad (x), rady = get_rad (y);
if (radx != rady){
if (t[radx] > t[rady])
swap (radx,rady);
t[radx] += t[rady];
t[rady] = radx;
}
}
void add (int idx, int val){
int ic = v[idx].x, jc = v[idx].y;
for (int dir=0;dir<=3;dir++){
int iv = ic + di[dir];
int jv = jc + dj[dir];
if (inmat (iv,jv) && a[iv][jv] >= val)
_union (v[idx].cod,cod(iv,jv));
}
}
int main (){
ifstream cin ("matrice2.in");
ofstream cout ("matrice2.out");
cin>>n>>q;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++){
cin>>a[i][j];
v[++k] = {cod(i,j),a[i][j],i,j};
}
sort (v+1,v+k+1,cmp);
for (i=1;i<=q;i++){
cin>>qry[i].x>>qry[i].y>>qry[i].x2>>qry[i].y2;
qry[i].poz = i;
}
for (int nr=(1<<20);nr;nr>>=1){ /// incerc sa adaug valoarea asta la toate query urile
sort (qry+1,qry+q+1,cmp2);
/// refac padurile in acelasi timp in care parcud query urile
memset (t,-1,sizeof t);
int idx = 1;
for (int i=1;i<=q;i++){
int val = qry[i].sol + nr;
while (idx <= k && v[idx].val >= val){
/// adaug celula asta in padure
add (idx,val);
idx++;
}
if (get_rad( cod(qry[i].x,qry[i].y) ) == get_rad(cod(qry[i].x2,qry[i].y2)))
qry[i].sol += nr;
}
}
for (i=1;i<=q;i++)
ans[qry[i].poz] = qry[i].sol;
for (i=1;i<=q;i++)
cout<<ans[i]<<"\n";
return 0;
}