#include <bits/stdc++.h>
using namespace std;
ifstream in("matrice2.in");
ofstream out("matrice2.out");
const int lim1=305;
const int lim2=9e4+5;
vector<pair<int,int> > s;
int mat[lim1][lim1];
int v[lim2],cnt;
bool rev(pair<int,int> p1,pair<int,int> p2)
{
return p1>p2;
}
int link[lim2];
int dim[lim2];
int tata(int x)
{
int cpy=x,aux;
while(x!=link[x]) x=link[x];
while(cpy!=link[cpy]) aux=cpy,cpy=link[cpy],link[aux]=x;
return x;
}
pair<int,int> papa[lim2];
vector<int> fii[lim2];
int nivel[lim2];
void unite(int x,int y,int lat)
{
x=tata(x);
y=tata(y);
if(x==y) return;
if(dim[x]<dim[y]) swap(x,y);
fii[x].push_back(y);
papa[y]={x,lat};
dim[x]+=dim[y];
link[y]=x;
}
void df(int nod)
{
for(int x:fii[nod])
{
nivel[x]=nivel[nod]+1;
df(x);
}
}
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
bool interior(int x,int y,int n)
{
if(1<=x and x<=n and 1<=y and y<=n)
return true;
return false;
}
bool consider[lim1][lim1];
int root;
void build(int n)
{
sort(s.begin(),s.end(),rev);
for(pair<int,int> p:s)
{
int val=p.first;
int x=(p.second-1)/n+1;
int y=(p.second-1)%n+1;
consider[x][y]=1;
for(int d=0;d<4;++d)
{
int xx=x+dx[d];
int yy=y+dy[d];
if(interior(xx,yy,n) and consider[xx][yy])
unite(p.second,mat[xx][yy],val);
}
}
root=tata(1);
df(root);
}
int main()
{
int n,q,x1,y1,x2,y2;
in>>n>>q;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
++cnt;
in>>v[cnt];
link[cnt]=cnt;
dim[cnt]=1;
s.push_back({v[cnt],cnt});
mat[i][j]=cnt;
}
build(n);
while(q--)
{
in>>x1>>y1>>x2>>y2;
int a=mat[x1][y1];
int b=mat[x2][y2];
int la=v[a],lb=v[b];
while(a!=b)
{
if(nivel[a]<nivel[b])
lb=min(lb,papa[b].second),b=papa[b].first;
else if(nivel[a]>nivel[b])
la=min(la,papa[a].second),a=papa[a].first;
else
la=min(la,papa[a].second),lb=min(lb,papa[b].second),
a=papa[a].first,b=papa[b].first;
}
out<<min(la,lb)<<'\n';
}
return 0;
}