#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N=1e6+10,LG=20;
int par[N],val[N];
int pp[N][LG];
int rp[N][LG];
vector<int> ma[N];
int tin[N],tout[N],tmp=0;
int get(int x)
{
return (par[x]==x)?x:par[x]=get(par[x]);
}
void dfs(int x)
{
tin[x]=tmp++;
for(auto y:ma[x])
{
dfs(y);
}
tout[x]=tmp;
}
bool isunc(int x,int y)
{
return tin[x]<=tin[y] and tout[y]<=tout[x];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m,l;
cin>>n>>m>>l;
int a[n][m];
vector<vector<int>> edge;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
int v=i*m+j;
val[v]=a[i][j];
if(i)
{
edge.push_back({max(a[i][j],a[i-1][j]),v,v-m});
}
if(j)
{
edge.push_back({max(a[i][j],a[i][j-1]),v,v-1});
}
}
}
sort(begin(edge),end(edge));
int lst=n*m;
for(int i=0;i<lst;i++)par[i]=i,pp[i][0]=i;
for(auto tp:edge)
{
int w=tp[0],x=tp[1],y=tp[2];
int px=get(x);
int py=get(y);
if(px==py)
{
// cout<<"Same"<<endl;
}
else
{
int nn=lst++;
val[nn]=w;
pp[nn][0]=nn;
par[nn]=nn;
par[px]=nn;
par[py]=nn;
pp[px][0]=nn;
pp[py][0]=nn;
// cout<<nn<<' '<<px<<endl;
// cout<<nn<<' '<<py<<endl;
// cout<<"Value "<<w<<endl;
}
}
for(int j=1;j<LG;j++)
{
for(int i=0;i<lst;i++)
{
pp[i][j]=pp[pp[i][j-1]][j-1];
}
}
for(int i=0;i<lst;i++)
{
if(pp[i][0]!=i)
ma[pp[i][0]].push_back(i);
int y=i;
for(int j=LG-1;j>=0;j--)
{
int x=pp[y][j];
if(val[x]<=val[i]+l)
{
y=x;
}
}
rp[i][0]=y;
// cout<<"one jump "<<i<<' '<<y<<endl;
// if can take it with one jump from i
}
dfs(lst-1);
for(int j=1;j<LG;j++)
{
for(int i=0;i<lst;i++)
{
rp[i][j]=rp[rp[i][j-1]][j-1];
}
}
int q;
cin>>q;
while(q--)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
x1--;y1--;x2--;y2--;
int v1=x1*m+y1,v2=x2*m+y2;
int ans=0;
for(int j=LG-1;j>=0;j--)
{
if(!isunc(rp[v1][j],v2))
{
v1=rp[v1][j];
ans+=(1<<j);
}
}
if(!isunc(rp[v1][0],v2))
{
cout<<-1<<endl;
}
else
{
cout<<ans+1<<endl;
}
}
}