#include <cstdio>
#include <algorithm>
using namespace std;
struct Query {
int x1, y1, x2, y2, ans;
int ind;
};
struct Node {
int x, y, val;
};
class MyComp2 {
public :
bool operator () (const Query &A, const Query &B) {
return A.ans > B.ans;
}
};
class MyComp {
public :
bool operator () (const Node &A, const Node &B) {
return A.val > B.val;
}
};
const int N = 301, Q = 20002;
Node nodes [N * N];
Query a [Q];
int n, q, u, h [N * N], f [N * N], valori [N][N], ind [N][N], sol [Q];
int dx [] = {-1, 0, 1, 0};
int dy [] = {0, 1, 0, -1};
void init () {
int i;
for (i = 1; i <= u; i ++) {
h [i] = 0;
f [i] = i;
}
}
int getFather (int x) {
int father, t;
for (t = x; f [t] != t; t = f [t]);
father = t;
t = x;
while (f [t] != t) {
x = f [t];
f [t] = father;
t = x;
}
return t;
}
void unite (const int &x, const int &y) {
if (h [y] > h [x])
f [x] = y;
else f [y] = x;
if (h [y] == h [x])
h [x] ++;
}
bool inBox (const Node &A) {
return (A.x >= 1 && A.x <= n && A.y >= 1 && A.y <= n);
}
void add (const Node &A) {
int i, fA, fB;
Node B;
for (i = 0; i < 4; i ++) {
B.x = A.x + dx [i];
B.y = A.y + dy [i];
if (inBox (B))
if (valori [B.x][B.y] >= A.val) {
B.val = valori [B.x][B.y];
fA = getFather (ind [A.x][A.y]);
fB = getFather (ind [B.x][B.y]);
if (fA != fB)
unite (fA, fB);
}
}
}
int main () {
int i, j, step, last, st, dr;
freopen ("matrice2.in", "r", stdin);
freopen ("matrice2.out", "w", stdout);
scanf ("%d%d", &n, &q);
u = 0;
for (i = 1; i <= n; i ++)
for (j = 1; j <= n; j ++) {
scanf ("%d", &nodes [++ u].val);
nodes [u].x = i;
nodes [u].y = j;
valori [i][j] = nodes [u].val;
}
sort (nodes + 1, nodes + 1 + u, MyComp ());
for (i = 1; i <= u; i ++)
ind [nodes [i].x][nodes [i].y] = i;
for (i = 1; i <= q; i ++) {
scanf ("%d%d%d%d", &a [i].x1, &a [i].y1, &a [i].x2, &a [i].y2);
a [i].ans = 0;
a [i].ind = i;
}
for (step = (1 << 19); step; step >>= 1) {
init ();
for (i = 1; i <= q; i ++)
a [i].ans = a [i].ans + step;
last = 1;
sort (a + 1, a + 1 + q, MyComp2 ());
for (i = 1; i <= q; i ++) {
st = dr = 0;
while (nodes [last].val >= a [i].ans) {
add (nodes [last]);
++ last;
}
st = getFather (ind [a [i].x1][a [i].y1]);
dr = getFather (ind [a [i].x2][a [i].y2]);
if (st == dr)
continue;
else a [i].ans -= step;
}
}
for (i = 1; i <= q; i ++)
sol [a [i].ind] = a [i].ans;
for (i = 1; i <= q; i ++)
printf ("%d\n", sol [i]);
return 0;
}