#include <cstdio>
#define MAXQ 20000
#define MAXN 300
#define MAXK (MAXN+2)*(MAXN+2)
#define NRDIR 4
int dl[NRDIR]={-1, 0, 1, 0};
int dc[NRDIR]={0, 1, 0, -1};
int n, u, k, t[MAXK], r[MAXK];
bool viz[MAXK], exist[MAXK];
int a[MAXQ], b[MAXQ], v[MAXQ];
int aux[MAXQ], ans[MAXQ];
int find(int x){
if(x==t[x]) return x;
else return t[x]=find(t[x]);
}
void dfs(int x){
int y;
viz[x]=0;
for(int i=0; i<NRDIR; i++){
y=x+dl[i]*(n+1)+dc[i];
if(viz[y]){
t[find(x)]=find(y);
dfs(y);
}
}
}
inline void init(int val){
for(int i=u; i<=k; i++) if(exist[i]){
t[i]=i;
if(r[i]>=val)
viz[i]=1;
}
for(int i=u; i<=k; i++) if(viz[i]) dfs(i);
}
void furie(int l, int r, int rez, int pas){
if(pas==0) for(int i=l; i<r; i++) ans[v[i]]=rez;
else if(l<r){
init(rez+pas);
int p=l, q=r;
for(int i=l; i<r; i++){
if(find(a[v[i]])==find(b[v[i]])) aux[--q]=v[i];
else aux[p++]=v[i];
}
for(int i=l; i<r; i++) v[i]=aux[i];
furie(l, p, rez, pas/2);
furie(p, r, rez+pas, pas/2);
}
}
int main(){
int q, x, y, z, t;
FILE *fin, *fout;
fin=fopen("matrice2.in", "r");
fout=fopen("matrice2.out", "w");
fscanf(fin, "%d%d", &n, &q);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
fscanf(fin, "%d", &r[i*(n+1)+j]), exist[i*(n+1)+j]=1;
u=1*(n+1)+1;
k=(n+1)*(n+1);
for(int i=0; i<q; i++){
fscanf(fin, "%d%d%d%d", &x, &y, &z, &t);
a[i]=x*(n+1)+y;
b[i]=z*(n+1)+t;
v[i]=i;
}
furie(0, q, 0, 1<<19);
for(int i=0; i<q; i++)
fprintf(fout, "%d\n", ans[i]);
fclose(fin);
fclose(fout);
return 0;
}