#include <fstream>
#include <algorithm>
using namespace std;
int N,Q;
int a[301][301];
int X[20001];
const int dl[] = {0,0,-1,1};
const int dc[] = {1,-1,0,0};
struct Query {
int x1,x2,y1,y2;
int id;
Query() {}
Query(int _id,int _x1,int _y1,int _x2,int _y2) {
id = _id;
x1 = _x1;
y1 = _y1;
x2 =_x2;
y2 = _y2;
}
};
bool compQuery(Query a,Query b)
{
return X[a.id] < X[b.id];
}
struct Coord {
int x,y;
Coord() {}
Coord(int _x,int _y) {
x = _x;
y = _y;
}
};
bool compCoord(Coord A,Coord B)
{
return a[A.x][A.y] < a[B.x][B.y];
}
Query q[20001];
Coord c[300*300+1];
int P[301][301],h[301][301];
inline int xcoord(int n) {
return n / 1000;
}
inline int ycoord(int n) {
return n % 1000;
}
int root(int x,int y) {
return (P[x][y] == x*1000+y) ? P[x][y] : (P[x][y] = root(xcoord(P[x][y]),ycoord(P[x][y])));
}
void unite(int x1,int y1,int x2,int y2) {
int r1 = root(x1,y1);
int r2 = root(x2,y2);
x1 = xcoord(r1);
x2 = xcoord(r2);
y1 = ycoord(r1);
y2 = ycoord(r2);
if (h[x1][y1] > h[x2][y2])
h[x1][y1] += h[x2][y2],
P[x2][y2] = x1*1000+y1;
else
h[x2][y2] += h[x1][y1],
P[x1][y1] = x2*1000+y2;
}
int main()
{
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
fin >> N >> Q;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
fin >> a[i][j];
for (int i = 1; i <= Q; i++) {
int x1,x2,y1,y2;
fin >> x1 >> y1 >> x2 >> y2;
q[i] = Query(i,x1,y1,x2,y2);
}
int cn = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
c[++cn] = Coord(i,j);
fill_n(X+1,Q,0);
sort(c+1,c+cn+1,compCoord);
reverse(c+1,c+cn+1);
int step = 1<<19;
for (;step; step /= 2)
{
sort(q+1,q+Q+1,compQuery);
reverse(q+1,q+Q+1);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++) {
h[i][j] = 1;
P[i][j] = i * 1000 + j;
}
int at = 1;
for (int i = 1; i <= Q; i++) {
int lim = X[q[i].id] + step;
for (; at <= cn && a[c[at].x][c[at].y] >= lim; at++) {
for (int k = 0; k < 4; k++) {
int nx = c[at].x + dl[k];
int ny = c[at].y + dc[k];
if (nx > 0 && nx <= N && ny > 0 && ny <= N && a[nx][ny] >= lim && root(nx,ny) != root(c[at].x,c[at].y))
unite(nx,ny,c[at].x,c[at].y);
}
}
if (root(q[i].x1,q[i].y1) == root(q[i].x2,q[i].y2))
X[q[i].id] += step;
}
}
for (int i = 1; i <= Q; i++)
fout << X[i] << "\n";
}