#include <bits/stdc++.h>
#define MAXN 300
#define MAXQ 20000
int n, q;
int v[1 + MAXN][1 + MAXN];
struct Query{std::pair <int, int> A, B; int ind, ans;};
std::vector <std::pair <int, int>> V;
bool cmp(std::pair <int, int> A, std::pair <int, int> B){ return v[A.first][A.second] < v[B.first][B.second];}
std::pair <int, int> father[1 + MAXN][1 + MAXN];
int active[1 + MAXN][1 + MAXN];
inline void Union(std::pair <int, int> x, std::pair <int, int> y){
father[y.first][y.second] = x;
}
inline std::pair <int, int> Find(std::pair <int, int> x){
if(father[x.first][x.second] == std::make_pair(0, 0))
return x;
std::pair <int, int> y = Find(father[x.first][x.second]);
father[x.first][x.second] = y;
return y;
}
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
inline void add(std::pair <int, int> x){
active[x.first][x.second] = 1;
for(int k = 0; k < 4; k++){
int l = x.first + dir[k][0], c = x.second + dir[k][1];
if(1 <= l && l <= n && 1 <= c && c <= n && active[l][c])
if(Find(x) != Find({l, c}))
Union(Find(x), Find({l, c}));
}
}
std::vector <Query> Q, S, T;
int ans[1 + MAXQ];
int main(){
FILE*fi,*fo;
fi = fopen("matrice2.in","r");
fo = fopen("matrice2.out","w");
fscanf(fi,"%d%d", &n, &q);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++){
fscanf(fi,"%d", &v[i][j]);
V.push_back({i, j});
}
std::sort(V.begin(), V.end(), cmp);
for(int i = 1; i <= q; i++){
Query tmp;
fscanf(fi,"%d%d%d%d", &tmp.A.first, &tmp.A.second, &tmp.B.first, &tmp.B.second);
tmp.ind = i;
tmp.ans = 0;
Q.push_back(tmp);
}
for(int p = (1 << 19); p; p /= 2){
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
active[i][j] = 0, father[i][j] = {0, 0};
int next = V.size() - 1;
while(!Q.empty()){
while(next >= 0 && v[V[next].first][V[next].second] >= Q.back().ans + p)
add(V[next]), next--;
if(!active[Q.back().A.first][Q.back().A.second] ||
!active[Q.back().B.first][Q.back().B.second] ||
Find(Q.back().A) != Find(Q.back().B))
T.push_back(Q.back());
else
Q.back().ans += p, S.push_back(Q.back());
Q.pop_back();
}
std::reverse(S.begin(), S.end());
std::reverse(T.begin(), T.end());
while(!S.empty() && !T.empty()){
if(S.back().ans > T.back().ans)
Q.push_back(S.back()), S.pop_back();
else
Q.push_back(T.back()), T.pop_back();
}
while(!S.empty()) Q.push_back(S.back()), S.pop_back();
while(!T.empty()) Q.push_back(T.back()), T.pop_back();
std::reverse(Q.begin(), Q.end());
}
for(auto y: Q) ans[y.ind] = y.ans;
for(int i = 1; i <= q; i++)
fprintf(fo,"%d\n", ans[i]);
return 0;
}