# include <cstdio>
# include <vector>
# include <algorithm>
# include <time.h>
using namespace std;
# define FIN "matrice2.in"
# define FOUT "matrice2.out"
# define min(a, b) (a < b ? a : b)
# define pb push_back
# define MAXN 90005
# define MAXM 20005
# define MAXL 20
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
int N, M, i, j, CT, Parinte, q, w, r, l, x, y;;
int RMQ[MAXL][MAXN];
vector <int> Arb[MAXN];
int A[MAXN], Ind[MAXN], H[MAXN], T[MAXN], S[MAXN];
int Cmp(int a, int b)
{
return A[a] > A[b];
}
int Codif(int X, int Y)
{
return (X - 1) * N + Y;
}
void Decodif(int &X, int &Y, int Nod)
{
(Nod % N) > 0 ? Y = Nod % N : Y = N;
(Nod % N) > 0 ? X = Nod / N + 1 : X = Nod / N;
}
int Father(int Nod)
{
if (T[Nod] == Nod) return Nod;
return T[Nod] = Father(T[Nod]);
}
void df(int Nod)
{
vector <int> :: iterator it;
for (it = Arb[Nod].begin(); it != Arb[Nod].end(); ++it)
if (!Ind[*it])
{
Ind[*it] = Ind[Nod] + 1;
df(*it);
}
}
void Solve()
{
int i, j, Xi, Yi, Xf, Yf, Nod, F;
for (i = 1; i <= CT; ++i)
{
S[Ind[i]] = 1;
Decodif(Xi, Yi, Ind[i]);
for (j = 0; j < 4; ++j)
{
Xf = Xi + dx[j]; Yf = Yi + dy[j];
if (1 <= Xf && Xf <= N && 1 <= Yf && Yf <= N)
{
Nod = Codif(Xf, Yf);
if (S[Nod])
{
F = Father(Nod);
T[F] = Ind[i]; RMQ[0][F] = Ind[i];
Arb[F].pb(Ind[i]); Arb[Ind[i]].pb(F);
}
}
}
}
}
void swap(int &A, int &B)
{
int aux;
aux = A; A = B; B = aux;
}
int main()
{
double ll = clock();
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
scanf("%d%d", &N, &M);
for (i = 1, CT = 0; i <= N; ++i)
for (j = 1; j <= N; ++j)
{
scanf("%d", &A[++CT]);
Ind[CT] = T[CT] = RMQ[0][CT] = CT;
}
sort(Ind + 1, Ind + CT + 1, Cmp);
Solve();
for (i = 1; i <= CT; ++i)
if (RMQ[0][i] == i) Parinte = i;
memset(Ind, 0, sizeof(Ind)); Ind[Parinte] = 1; df(Parinte);
H[0] = H[1] = 0;
for (i = 2; i <= CT; ++i) H[i] = H[i >> 1] + 1;
RMQ[0][Parinte] = 0;
for (i = 1; i <= H[CT]; ++i)
for (j = 1; j <= CT; ++j)
RMQ[i][j] = RMQ[i - 1][RMQ[i - 1][j]];
for (i = 1; i <= M; ++i)
{
scanf("%d%d", &x, &y); q = (x - 1) * N + y;
scanf("%d%d", &x, &y); w = (x - 1) * N + y;
if (Ind[q] > Ind[w]) swap(q, w);
while (Ind[q] < Ind[w]) w = RMQ[H[Ind[w] - Ind[q]]][w];
if (q != w)
{
l = H[Ind[q] - 1];
while (l >= 0)
{
if (RMQ[l][q] != RMQ[l][w])
{
q = RMQ[l][q];
w = RMQ[l][w];
} else r = RMQ[l][q];
--l;
}
} else r = q;
printf("%d\n", A[r]);
}
//for (i = 1; i <= CT; ++i) printf("%d %d\n", RMQ[0][i], Ind[i]);
//printf("%lf", (clock() - ll) / CLOCKS_PER_SEC);
return 0;
}