#include <fstream>
#include <algorithm>
#include <vector>
#include <set>
#define nmax 300
#define qmax 20001
using namespace std;
ifstream cin("matrice2.in");
ofstream cout("matrice2.out");
int a[nmax+1][nmax+1],t[nmax*nmax+1],n,q,x1,y1,x2,y2,val,sol[qmax],dx[]={-1,0,1,0},dy[]={0,1,0,-1};
struct nod{
int l,c,val;
};
bool cmp(const nod& a,const nod& b){
return a.val>b.val;
}
vector<nod>v;
set<int>l[nmax*nmax+1];
bool inside(int l,int c){
return l>0&&c>0&&l<=n&&c<=n;
}
int get_root(int x){
if(t[x]>0)
return get_root(t[x]);
return x;
}
void join(int x,int y){
x=get_root(x),y=get_root(y);
if(x==y)
return;
if(t[x]>t[y])
swap(x,y);
t[x]+=t[y];
t[y]=x;
for(auto i:l[y])
if(l[x].find(i)!=l[x].end()){
sol[i]=val;
l[x].erase(i);
}else
l[x].insert(i);
}
int main()
{
cin>>n>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
cin>>a[i][j];
v.push_back({i,j,a[i][j]});
}
sort(v.begin(),v.end(),cmp);
for(int i=0;i<n*n;i++){
a[v[i].l][v[i].c]=i;
t[i]=-1;
}
for(int i=1;i<=q;i++){
cin>>x1>>y1>>x2>>y2;
l[a[x1][y1]].insert(i);
l[a[x2][y2]].insert(i);
}
for(int i=0;i<n*n;i++){
int l=v[i].l,c=v[i].c;
val=v[i].val;
for(int j=0;j<4;j++){
int lv=l+dx[j],cv=c+dy[j];
if(inside(lv,cv)&&a[lv][cv]<i)
join(i,a[lv][cv]);
}
}
for(int i=1;i<=q;i++)
cout<<sol[i]<<'\n';
return 0;
}