#include <bits/stdc++.h>
using namespace std;
ifstream fin ("matrice2.in");
ofstream fout ("matrice2.out")
struct drum
{
int xs,ys,xf,yf;
};
struct qs
{
int id, val;
qs(int id, int val)
{
this->id=id;
this->val=val;
}
bool operator<(qs b) const
{
return val<b.val;
}
};
struct pos
{
int val;
pair<int, int> p;
pos(int val, pair<int, int> p)
{
this->val=val;
this->p=p;
}
bool operator<(pos b) const
{
return val>b.val;
}
};
int n,q,maxi;
pair<int, int> dsu[305][305];
int sz[305][305];
bool on[305][305];
drum a[20005];
int st[20005];
int dr[20005];
int mij[20005];
int last[20005];
bool rez[20005];
vector<pos> v;
void dsu_init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
dsu[i][j]={i, j};
on[i][j]=false;
sz[i][j]=1;
}
}
pair<int, int> dsu_par(int x, int y)
{
if(dsu[x][y] != make_pair(x, y))
dsu[x][y]=dsu_par(dsu[x][y].first, dsu[x][y].second);
return dsu[x][y];
}
void dsu_merge(int a, int b, int c, int d)
{
auto it=dsu_par(a, b);
a=it.first;
b=it.second;
it=dsu_par(c, d);
c=it.first;
d=it.second;
if(a==c && b==d)
return;
if(sz[a][b]>sz[c][d])
{
swap(a, c);
swap(b, d);
}
dsu[a][b]={c, d};
sz[c][d]+=sz[a][b];
}
void dsu_on(int i, int j)
{
//cout<<"on "<<i<<' '<<j<<'\n';
on[i][j]=true;
if(on[i+1][j])
dsu_merge(i, j, i+1, j);
if(on[i-1][j])
dsu_merge(i, j, i-1, j);
if(on[i][j+1])
dsu_merge(i, j, i, j+1);
if(on[i][j-1])
dsu_merge(i, j, i, j-1);
}
void solve(vector<qs> qv)
{
dsu_init();
for(auto it : v)
{
while(!qv.empty() && qv.back().val>it.val)
{
int id=qv.back().id;
qv.pop_back();
if(dsu_par(a[id].xs, a[id].ys) == dsu_par(a[id].xf, a[id].yf))
rez[id]=true;
else
rez[id]=false;
}
dsu_on(it.p.first, it.p.second);
}
while(!qv.empty())
{
int id=qv.back().id;
qv.pop_back();
if(dsu_par(a[id].xs, a[id].ys) == dsu_par(a[id].xf, a[id].yf))
rez[id]=true;
else
rez[id]=false;
}
}
int main()
{
/*
n=5;
dsu_on(1, 1);
dsu_on(1, 2);
dsu_on(1, 3);
dsu_on(1, 4);
dsu_on(1, 5);
dsu_on(2, 5);
dsu_on(3, 5);
dsu_on(4, 5);
dsu_on(5, 5);
dsu_on(5, 4);
dsu_on(5, 3);
dsu_on(4, 3);
dsu_on(3, 3);
cout<<(dsu_par(1, 1) == dsu_par(3, 3));
return 0;
*/
fin>>n>>q;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
int x;
fin>>x;
maxi=max(maxi, x);
v.push_back(pos(x, {i, j}));
}
sort(v.begin(), v.end());
for(int i=1; i<=q; i++)
{
fin>>a[i].xs>>a[i].ys>>a[i].xf>>a[i].yf;
st[i]=1;
dr[i]=maxi;
}
bool ok=true;
vector<qs> qv;
while(ok)
{
ok=false;
qv.clear();
for(int i=1; i<=q; i++)
{
if(st[i]<=dr[i])
{
ok=true;
mij[i]=(st[i]+dr[i])/2;
qv.push_back(qs(i, mij[i]));
}
}
sort(qv.begin(), qv.end());
solve(qv);
cout<<st[1]<<' '<<mij[1]<<' '<<dr[1]<<' '<<rez[1]<<'\n';
for(int i=1; i<=q; i++)
{
if(st[i]<=dr[i])
{
if(rez[i])
{
last[i]=mij[i];
st[i]=mij[i]+1;
}
else
{
dr[i]=mij[i]-1;
}
}
}
}
for(int i=1; i<=q; i++)
fout<<last[i]<<'\n';
return 0;
}