#include <bits/stdc++.h>
using namespace std;
const int NMAX = 303;
int n, q;
int v[NMAX][NMAX], Start[NMAX], End[NMAX], ans[NMAX], ind[NMAX], ax[NMAX], ay[NMAX];
bool used[NMAX * NMAX], answered[NMAX * NMAX];
pair<int, int> a[NMAX * NMAX];
vector<int> g[NMAX];
int cod(int i, int j) {
return n * (i-1) + j;
}
class DSU {
private:
int t[NMAX * NMAX];
public:
DSU() {
for(int i = 1; i <= NMAX * NMAX; i++)
t[i] = i;
}
int Find(int node) {
int root = node;
while(root != t[root]) {
root = t[root];
}
while(node != t[node]) {
int aux = t[node];
t[node] = root;
node = aux;
}
return root;
}
void unite(int x, int y) {
x = Find(x);
y = Find(y);
if(x == y) return ;
t[x] = y;
}
void clear() {
for(int i = 1; i <= NMAX * NMAX; i++)
t[i] = i, used[i] = 0;
}
}ds;
void add_edge(int x, int y) {
g[x].push_back(y);
g[y].push_back(x);
}
void add_node(int node) {
for(int son : g[node])
if(used[son])
ds.unite(node, son);
used[node] = 1;
}
int main() {
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
scanf("%d %d", &n, &q);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
scanf("%d", &v[i][j]);
a[cod(i, j)].first = v[i][j];
a[cod(i, j)].second = cod(i, j);
}
int nr = n*n;
sort(a+1, a+nr+1);
reverse(a+1, a+nr+1);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(i < n)
add_edge(cod(i, j), cod(i+1, j));
if(j < n)
add_edge(cod(i, j), cod(i, j+1));
}
for(int i = 1; i <= q; i++) {
int a, b, x, y;
scanf("%d %d %d %d", &a, &b, &x, &y);
Start[i] = cod(a, b);
End[i] = cod(x, y);
ind[i] = i;
}
for(int p = 19; p >= 0; p--) {
ds.clear();
int add = 1<<p, idx = 1;
for(int i = 1; i <= q; i++) {
while(idx <= nr && a[idx].first >= ans[ind[i]] + add)
add_node(a[idx++].second);
if(ds.Find(Start[ind[i]]) == ds.Find(End[ind[i]]))
ans[ind[i]] += add, answered[i] = 1;
else
answered[i] = 0;
}
int lx = 0, ly = 0, py = 1, cnt = 0;
for(int i = 1; i <= q; i++) {
if(answered[i])
ax[++lx] = ind[i];
else
ay[++ly] = ind[i];
}
for(int i = 1; i <= lx; i++) {
while(py <= ly && ans[ay[py]] >= ans[ax[i]])
ind[++cnt] = ay[py++];
ind[++cnt] = ax[i];
}
while(py <= ly)
ind[++cnt] = ay[py++];
////printf("%d: ", add);
////for(int i = 1; i <= q; i++)
////printf("%d ", ind[i]);
////printf("\n");
}
for(int i = 1; i <= q; i++)
printf("%d\n", ans[i]);
return 0;
}