#include <bits/stdc++.h>
#define X first
#define Y second
using namespace std;
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
priority_queue<iii> q;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
std::vector<ii> adj[90001];
int root[90001],h[90001],l[90001][20],par[90001][20];
int a[90001];
int n;
int findroot(int u)
{
if(root[u]==u) return u;
return root[u]=findroot(root[u]);
}
void dung_canh()
{
int i,j,d,x,y;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
for(d=0;d<4;d++)
{
x=i+dx[d];
y=j+dy[d];
if(x>n||y>n||x<1|y<1) continue;
q.push(iii(min(a[(x-1)*n+y],a[(i-1)*n+j]),ii((x-1)*n+y,(i-1)*n+j)));
}
}
}
}
void make_mst()
{
int i,d,u,v;
for(i=1;i<=n*n;i++) root[i]=i;
while(q.size())
{
d=q.top().X;
u=q.top().Y.X;
v=q.top().Y.Y;
q.pop();
if(findroot(u)!=findroot(v))
{
root[findroot(u)]=findroot(v);
adj[u].push_back(ii(d,v));
adj[v].push_back(ii(d,u));
}
}
}
void dfs(int u)
{
int i,v,d;
for(i=0;i<adj[u].size();i++)
{
d=adj[u][i].X;
v=adj[u][i].Y;
if(par[u][0]==v) continue;
par[v][0]=u;
h[v]=h[u]+1;
l[v][0]=d;
dfs(v);
}
}
void pre_lca()
{
int u,i;
for(i=1;i<20;i++)
{
for(u=1;u<=n*n;u++)
{
par[u][i]=par[par[u][i-1]][i-1];
l[u][i]=min(l[u][i-1],l[par[u][i-1]][i-1]);
}
}
}
int lca(int u,int v)
{
int i,res=1e9;
res=min(res,min(a[u],a[v]));
for(i=19;i>=0;i--)
{
if(h[par[u][i]]>=h[v])
{
res=min(res,l[u][i]);
u=par[u][i];
}
}
for(i=19;i>=0;i--)
{
if(h[par[v][i]]>=h[u])
{
res=min(res,l[v][i]);
v=par[v][i];
}
}
if(u==v) return res;
for(i=19;i>=0;i--)
{
if(par[u][i]!=par[v][i])
{
res=min(res,min(l[u][i],l[v][i]));
u=par[u][i];
v=par[v][i];
}
}
res=min(res,min(l[u][0],l[v][0]));
return res;
}
int main()
{
freopen("matrice2.in","r",stdin);
freopen("matrice2.out","w",stdout);
int q,x,y,u,v,i,j;
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&a[(i-1)*n+j]);
}
}
memset(l,0x3f,sizeof(l));
dung_canh();
make_mst();
dfs(1);
pre_lca();
while(q--)
{
scanf("%d%d%d%d",&x,&y,&u,&v);
printf("%d\n",lca((x-1)*n+y,(u-1)*n+v));
}
}