#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 310
#define NMAX2 91000
#define LGMAX 20
#define MP make_pair
#define ff first
#define ss second
int N, M, lgmax;
int dx[] = {0, 0, 1,-1};
int dy[] = {1,-1, 0, 0};
vector <int> leg[NMAX2];
int a[NMAX][NMAX];
int pz[NMAX][NMAX];
pair <int, pair<int, int> > b[NMAX2];
int val[NMAX2];
int tata[LGMAX][NMAX2];
int tt[NMAX2];
int niv[NMAX2];
int father(int x)
{
if (tt[x] == x) return x;
return tt[x] = father(tt[x]);
}
void unite(int x, int y)
{
if (val[x] > val[y]) tata[0][x] = y, leg[y].push_back(x), tt[x] = y;
else tata[0][y] = x, leg[x].push_back(y), tt[y] = x;
}
void back(int x)
{
for (vector <int> :: iterator it = leg[x].begin(); it != leg[x].end(); ++it) {
niv[*it] = niv[x] + 1;
back(*it);
}
}
int lca(int x, int y)
{
int k;
for (k = lgmax; k >= 0 && niv[x] > niv[y]; k--)
if (niv[ tata[k][x] ] >= niv[y])
x = tata[k][x];
for (k = lgmax; k >= 0 && niv[y] > niv[x]; k--)
if (niv[ tata[k][y] ] >= niv[x])
y = tata[k][y];
for (k = lgmax; k >= 0 && x != y; k--)
if (tata[k][x] != tata[k][y])
x = tata[k][x], y = tata[k][y];
if (x == y) return x;
return tata[0][x];
}
int main()
{
int i, j, x, y, xx, yy, dir, k, nb = 0;
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
scanf("%d %d", &N, &M);
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
scanf("%d", &a[i][j]);
b[++nb].ff = a[i][j];
b[nb].ss = MP(i, j);
}
}
int N2 = N * N;
sort(b + 1, b + N2 + 1);
reverse(b + 1, b + N2 + 1);
for (i = 1; i <= N2; i++) {
x = b[i].ss.ff; y = b[i].ss.ss;
// printf("%d %d\n", x, y);
tata[0][i] = i;
val[i] = b[i].ff;
pz[x][y] = i;
tt[i] = i;
for (dir = 0; dir < 4; dir++) {
xx = x + dx[dir]; yy = y + dy[dir];
if (!(1 <= xx && xx <= N && 1 <= yy && yy <= N)) continue;
if (!pz[xx][yy]) continue;
int q = father(i), w = father(pz[xx][yy]);
// printf("%d %d - %d %d | %d %d\n", x, y, xx, yy, q, w);
if (q == w) continue;
unite(q, w);
}
}
for (i = 1; i <= N2; i++) if (tata[0][i] == i) back(i);
for (k = 1; (1 << (k - 1)) <= N2; k++)
for (i = 1; i <= N2; i++) tata[k][i] = tata[k - 1][tata[k - 1][i]];
// printf("\n");
// for (i = 1; i <= N2; i++) printf("%d %d\n", i, tata[0][i]);
lgmax = k - 1;
for (i = 1; i <= M; i++) {
scanf("%d %d %d %d", &x, &y, &xx, &yy);
x = pz[x][y]; y = pz[xx][yy];
int q = lca(x, y);
printf("%d\n", val[q]);
}
return 0;
}