#include<stdio.h>
#include<algorithm>
using namespace std;
struct casy
{
int val, x, y;
};
struct query
{
int x1, y1, x2, y2, s, indice;
};
casy v[90010];
query q[20010];
int vx[] = {0,0,0,1,-1};
int vy[] = {0,1,-1,0,0};
int n, m, l, u[310][20010], indice[310][310], t[90010];
int cmp(casy a, casy b)
{
return a.val > b.val;
}
int cmp2(query a, query b)
{
return a.s > b.s;
}
int cmp3(query a, query b)
{
return a.indice < b.indice;
}
int rad(int x)
{
if(x != t[x])
t[x] = rad(t[x]);
return t[x];
}
int main()
{
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
int i, j, h = 0, x, y, cx, cy, aux, k, pos;
scanf("%d %d", &n, &m);
for(i = 1; i <= n; i ++)
for(j = 1; j <= n; j ++)
{
scanf("%d", &v[++ h].val);
v[h].x = i;
v[h].y = j;
}
l = n * n;
sort(v + 1, v + l + 1, cmp);
for(i = 1; i <= l; i ++)
indice[v[i].x][v[i].y] = i;
for(i = 1; i <= m; i ++)
{
scanf("%d %d %d %d", &q[i].x1, &q[i].y1, &q[i].x2, &q[i].y2);
q[i].indice = i;
}
for(k = 1; k < v[1].val; k <<= 1);
for( ; k > 0; k >>= 1)
{
sort(q + 1, q + m + 1, cmp2);
for(i = 1; i <= n; i ++)
for(j = 1; j <= n; j ++)
u[i][j] = 0;
for(i = 1; i <= l; i ++)
t[i] = i;
j = 1;
for(i = 1; i <= l; )
{
for( ; j <= m && q[j].s + k > v[i].val; j ++)
if(rad(indice[q[j].x1][q[j].y1]) == rad(indice[q[j].x2][q[j].y2]))
q[j].s += k;
pos = i;
for( ; i <= l && v[i].val == v[pos].val; i ++)
{
x = v[i].x;
y = v[i].y;
u[x][y] = 1;
for(j = 1; j <= 4; j ++)
{
cx = x + vx[j];
cy = y + vy[j];
if(cx > 0 && cy > 0 && cx <= n && cy <= n && u[cx][cy])
{
aux = indice[cx][cy];
t[rad(aux)] = rad(i);
}
}
}
}
for( ; j <= m; j ++)
if(rad(indice[q[j].x1][q[j].y1]) == rad(indice[q[j].x2][q[j].y2]))
q[j].s += k;
}
sort(q + 1, q + m + 1, cmp3);
for(i = 1; i <= m; i ++)
printf("%d\n", q[i].s);
}