#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
#define swich(i, j) n * (i - 1) + j
int t[90001], n, q, rez[20001], mat[301][301];
pair <int, int> Begin[20001];
pair <int, int> End[20001];
struct element{
int i, j, val;
bool operator < (const element& aux) const
{
return val > aux.val;
}
} a[90001];
int sz; // a size
struct nod{
int i, x1, y1, x2, y2;
nod *next, *prev;
} * head, * last;
int root(int x)
{
if (t[x] == x)
return x;
return t[x] = root(t[x]);
}
int d1[] = {0, -1, 0, 1, 0};
int d2[] = {0, 0, 1, 0, -1};
int main()
{
fin >> n >> q;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
fin >> mat[i][j];
a[++sz] = {i, j, mat[i][j]};
t[swich(i, j)] = swich(i, j);
}
}
sort(a + 1, a + sz + 1);
int x1, y1, x2, y2;
fin >> x1 >> y1 >> x2 >> y2;
head = new nod;
*head = {1, x1, y1, x2, y2, NULL};
last = head;
for (int i = 2; i <= q; i++)
{
fin >> x1 >> y1 >> x2 >> y2;
last->next = new nod();
last->next->prev = last;
last = last->next;
last->i = i;
last->x1 = x1;
last->y1 = y1;
last->x2 = x2;
last->y2 = y2;
last->next = NULL;
}
nod* p;
int i = 1, x, y, c, r1, r2;
while (i <= sz && head != NULL)
{
c = a[i].val; // iteration constant
while (i <= sz && a[i].val == c)
{
r1 = root(swich(a[i].i, a[i].j));
for (int k = 1; k <= 4; k++)
{
x = a[i].i + d1[k];
y = a[i].j + d2[k];
if (x < 0 || x > n || y < 0 || y > n || mat[x][y] < a[i].val)
continue;
r2 = root(swich(x, y));
t[r2] = r1;
}
i++;
}
p = head;
while (p != NULL)
{
if (root(swich(p->x1, p->y1)) == root(swich(p->x2, p->y2)))
{
rez[p->i] = c;
if (p == head)
{
head = head->next;
p = p->next;
}
else if(p == last)
{
p->prev->next = NULL;
last = p->prev;
break;
}
else
{
p->prev->next = p->next;
p->next->prev = p->prev;
p = p->next;
}
}
else
p = p->next;
}
}
for (int k = 1; k <= q; k++)
fout << rez[k] << '\n';
return 0;
}