#include <fstream>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
struct poz {
int x,y,v;
poz (int xx, int yy, int vv) { x=xx; y=yy; v=vv; }
};
int n, q, a[305][305];
vector<pair<int, int>> t[100001];
vector<poz> aux;
bool viz[305][305];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool cmp(const poz& a, const poz& b) {
return a.v>b.v;
}
int index(int x, int y) {
return (x-1)*n+y;
}
void getXY(int idx, int *x, int *y){
if (idx%n==0) { *x = idx/n; *y = n; }
else { *x = idx/n + 1; *y = idx%n; }
}
int radacina(int idx, int i) {
int r = idx, aux;
while (t[r][t[r].size()-1].second != r) r = t[r][t[r].size()-1].second;
while (t[idx][t[idx].size()-1].second != idx) {
aux = t[idx][t[idx].size()-1].second;
t[idx].push_back(make_pair(i, r));
idx = aux;
}
return r;
}
int lowerBound(const vector<pair<int, int>> &arr, int maxi) {
int l = 1, r = arr.size();
while (l<=r) {
int mid = (l+r)/2;
if (arr[mid-1].first > maxi) r = mid-1;
else l = mid+1;
}
return r-1;
}
int radacina2(int idx, int maxi) {
int r = idx, aux;
while (t[r][lowerBound(t[r], maxi)].second != r)
r = t[r][lowerBound(t[r], maxi)].second;
/*while (t[idx][lowerBound(t[idx], maxi)].second != idx) {
aux = t[idx][lowerBound(t[idx], maxi)].second;
t[idx][lowerBound(t[idx], maxi)].second = r;
idx = aux;
}*/
return r;
}
bool isConnected(int id1, int id2, int maxi) {
return radacina2(id1, maxi) == radacina2(id2, maxi);
}
int main() {
//ifstream cin("/usr/local/google/home/catavlas/ClionProjects/cf_training/subsecvente.in");
ifstream cin("matrice2.in");
ofstream cout("matrice2.out");
cin>>n>>q;
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j) {
cin>>a[i][j];
aux.push_back(poz(i,j,a[i][j]));
}
sort(aux.begin(), aux.end(), cmp);
// init t
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j) t[index(i,j)].push_back(make_pair(-1, index(i,j)));
// build t
for (int i=0; i<aux.size(); ++i) {
int x = aux[i].x, y = aux[i].y, r;
viz[x][y]=1;
for (int j=0; j<4; ++j)
if (viz[x+dx[j]][y+dy[j]]) {
r = radacina(index(x+dx[j],y+dy[j]), i);
if (r!=index(x,y)) t[r].push_back(make_pair(i, index(x,y)));
}
}
for (; q; --q) {
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
int id1 = index(x1, y1), id2 = index(x2,y2);
int l = 1, r = aux.size();
while (l<=r) {
int mid = (l+r)/2;
if (isConnected(id1, id2, mid-1)) r=mid-1;
else l = mid+1;
}
cout<<aux[r].v<<"\n";
}
return 0;
}