#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 310;
const int Q = 21000;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
int n, qq, x[N][N], nr, sol[Q], q[Q], poz[Q], val[N * N], e[N * N], X[N * N], Y[N * N], ver[N][N], p[N * N];
int x1[Q], y11[Q], x2[Q], y2[Q];
//parsare
const int BUFF = 1200000;
char a[BUFF];
int pp;
int rad(int nod) {
if(!p[nod])
return nod;
return p[nod] = rad(p[nod]);
}
bool cmp(int a, int b) {
return val[a] > val[b];
}
bool cmp2(int a, int b) {
return q[a] > q[b];
}
inline int conv(const int &x, const int &y) {
return (x - 1) * n + y;
}
inline void add(int el) {
int i, nx, ny;
ver[X[el]][Y[el]] = 1;
for(i = 0; i<4; ++i) {
nx = X[el] + dx[i];
ny = Y[el] + dy[i];
if(ver[nx][ny]) {
int r1 = rad(conv(nx, ny)), r2 = rad(el);
if(r1 != r2)
p[r1] = el;
}
}
}
inline bool verQ(int nr) {
int r1 = rad(conv(x1[nr], y11[nr])), r2 = rad(conv(x2[nr], y2[nr]));
return r1 == r2;
}
inline int ter() {
int r = 0;
while(a[pp] >= '0' && a[pp] <= '9')
r = r * 10 + a[pp++] - '0';
++pp;
return r;
}
int main() {
int i, j, pas = 1;
freopen("matrice2.in", "r", stdin);
freopen("matrice2.out", "w", stdout);
cin >> n >> qq;
cin.get();
for(i = 1; i<=n; ++i) {
cin.getline(a, BUFF); pp = 0;
for(j = 1; j<=n; ++j) {
x[i][j] = ter();
++nr;
e[nr] = nr;
val[nr] = x[i][j];
X[nr] = i; Y[nr] = j;
}
}
sort(e + 1, e + nr + 1, cmp);
for(i = 1; i<=qq; ++i) {
cin.getline(a, BUFF); pp = 0;
x1[i] = ter();
y11[i] = ter();
x2[i] = ter();
y2[i] = ter();
}
while(pas * 2 < x[X[e[1]]][Y[e[1]]]) pas *= 2;
while(pas) {
for(i = 1; i<=qq; ++i) {
q[i] = sol[i] + pas;
poz[i] = i;
}
sort(poz + 1, poz + qq + 1, cmp2);
//init
for(i = 1; i<=n; ++i)
for(j = 1; j<=n; ++j)
ver[i][j] = 0;
for(i = 1; i<=nr; ++i)
p[i] = 0;
//end init
for(i = 1, j = 1; i<=nr && j<=qq;) {
while(i<=nr && val[e[i]] >= q[poz[j]]) {
add(e[i]);
++i;
}
if(verQ(poz[j]))
sol[poz[j]] += pas;
++j;
}
pas>>=1;
}
for(i = 1; i<=qq; ++i)
cout << sol[i] << "\n";
return 0;
}