#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#define MAXN 350
#define MAXQ 20050
#define MAXVAL 1000050
using namespace std;
int n, q, a[MAXN][MAXN];
struct query
{
int x1, y1, x2, y2;
query(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) : x1(x1), y1(y1), x2(x2), y2(y2) { }
};
struct elem
{
int x, y, val;
elem(int x = 0, int y = 0, int val = 0) : x(x), y(y), val(val) { }
bool operator()(elem e, elem f)
{
return e.val > f.val;
}
};
query stion[MAXQ];
int state[MAXQ], trial[MAXQ], ind[MAXQ];
elem mat1d[MAXN*MAXN], parent[MAXN][MAXN];
void citire()
{
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
for (int i = 1; i <= q; i++)
scanf("%d %d %d %d", &stion[i].x1, &stion[i].y1, &stion[i].x2, &stion[i].y2);
for (int i = 1, k = 0; i <= n; i++)
for (int j = 1; j <= n; j++)
mat1d[++k] = elem(i, j, a[i][j]);
sort(mat1d+1, mat1d+1+n*n, elem());
}
bool cmp(int i, int j)
{
return trial[i] > trial[j];
}
elem getParent(int x, int y)
{
if (parent[x][y].x == x && parent[x][y].y == y)
return parent[x][y];
else
return parent[x][y] = getParent(parent[x][y].x, parent[x][y].y);
}
void unify(int x1, int y1, int x2, int y2)
{
elem g = getParent(x1, y1);
parent[g.x][g.y] = getParent(x2, y2);
}
void percolate(elem e)
{
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
for (int i = 0; i < 4; i++) {
int nx = e.x + dx[i];
int ny = e.y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && a[nx][ny] >= a[e.x][e.y])
unify(e.x, e.y, nx, ny);
}
}
int united(query s)
{
elem e = getParent(s.x1, s.y1);
elem f = getParent(s.x2, s.y2);
return e.x == f.x && e.y == f.y;
}
void ssq()
{
for (int i = 1; i <= q; i++)
ind[i] = i;
sort(ind+1, ind+q+1, cmp);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
parent[i][j] = elem(i, j, 0);
for (int i = 1, j = 1; i <= q; i++) {
int minVal = trial[ind[i]];
for (j; j <= n*n && mat1d[j].val >= minVal; j++)
percolate(mat1d[j]);
if (united(stion[ind[i]]))
state[ind[i]] = trial[ind[i]];
}
}
void solve()
{
int step = 1;
for (step; (step<<1) <= MAXVAL; step <<= 1);
for (step; step; step >>= 1) {
for (int i = 1; i <= q; i++)
trial[i] = state[i] + step;
ssq();
}
}
void afisare()
{
for (int i = 1; i <= q; i++)
printf("%d\n", state[i]);
}
int main()
{
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
citire();
solve();
afisare();
return 0;
}