#include <bits/stdc++.h>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
const int MAXN = 3e2;
const int MAXQ = 2e4;
const int di[] = {-1, 0, 1, 0}, dj[] = {0, 1, 0, -1};
int a[1 + MAXN + 1][1 + MAXN + 1], rev[1 + MAXN * MAXN], sol[1 + MAXQ];
pair<short, short> cells[1 + MAXN * MAXN];
vector<pair<short, short>> pos[1 + MAXN * MAXN];
pair<int, int> q[1 + MAXQ];
struct DSU {
vector<int> p, sz;
DSU(int n) {
p.resize(n + 1);
iota(p.begin(), p.end(), 0);
sz.assign(n + 1, 1);
}
int root(int x) {
if (x == p[x]) {
return x;
}
return p[x] = root(p[x]);
}
bool unite(int u, int v) {
int x = root(u), y = root(v);
if (x == y) {
return false;
}
if (sz[x] > sz[y]) {
swap(x, y);
}
p[x] = y;
sz[y] += sz[x];
return true;
}
};
bool cmp(const pair<short, short> &x, const pair<short, short> &y) {
return a[x.first][x.second] < a[y.first][y.second];
}
void test_case() {
int n, Q;
fin >> n >> Q;
auto id = [&](int i, int j) -> int {
return (i - 1) * n + j;
};
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
fin >> a[i][j];
cells[id(i, j)] = make_pair(i, j);
}
}
int N = n * n;
sort(cells + 1, cells + N + 1, cmp);
int m = 0, last = 0;
for (int i = 1; i <= N; ++i) {
int l, c;
tie(l, c) = cells[i];
if (a[l][c] != last) {
rev[++m] = a[l][c];
last = a[l][c];
}
pos[m].emplace_back(l, c);
}
for (int i = 1; i <= Q; ++i) {
int x1, y1, x2, y2;
fin >> x1 >> y1 >> x2 >> y2;
q[i] = make_pair(id(x1, y1), id(x2, y2));
}
int step = 1;
while ((step << 1) <= m) {
step <<= 1;
}
while (step >= 1) {
vector<int> aux(Q + 1), qt[m + 1];
for (int i = 1; i <= Q; ++i) {
if (sol[i] + step <= m) {
aux[i] = sol[i] + step;
qt[aux[i]].emplace_back(i);
}
}
DSU t(N);
for (int p = m; p >= 1; --p) {
for (auto it : pos[p]) {
int i, j;
tie(i, j) = it;
int curr_id = id(i, j);
for (int k = 0; k < 4; ++k) {
int iv = i + di[k], jv = j + dj[k];
if (a[i][j] <= a[iv][jv]) {
t.unite(curr_id, id(iv, jv));
}
}
}
for (int i : qt[p]) {
if (t.root(q[i].first) == t.root(q[i].second)) {
sol[i] = aux[i];
}
}
}
step >>= 1;
}
for (int i = 1; i <= Q; ++i) {
fout << rev[sol[i]] << '\n';
}
}
int main() {
int t = 1;
for (int tc = 1; tc <= t; ++tc) {
test_case();
}
fin.close();
fout.close();
return 0;
}