#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int N = 3<<17;
int a[N], nxt[N][20], hei[N], Par[N], Mx[N], X[N], Num[N];
vector<int> nei[N];
set<int> lst[N];
vector<pair<int, int>> vc;
vector<pair<int, pair<int, int>>> E;
void dfs(int u, int p){
hei[u] = hei[p] + 1;
nxt[u][0] = p;
for (int i=0;i<18;i++)
nxt[u][i+1] = nxt[nxt[u][i]][i];
for (int i : nei[u])
dfs(i, u);
}
int root(int v){
return (Par[v] == 0 ? v : Par[v] = root(Par[v]));
}
int main(){
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int n, m, A, q, s = 0;
cin>>n>>m>>A;
for (int i=1;i<=n * m;i++){
Mx[i] = i;
cin>>a[i];
vc.push_back({a[i], i});
if (i > m)
E.push_back({max(a[i], a[i - m]), {i, i - m}});
if ((i-1) % m)
E.push_back({max(a[i], a[i - 1]), {i, i - 1}});
}
sort(begin(E), end(E));
sort(begin(vc), end(vc));
for (auto [vl , id] : vc){
while (s < E.size() and E[s].first <= vl + A){
auto [u, v] = E[s++].second;
int U = root(u), V = root(v);
if (U == V)
continue;
Par[U] = V;
if (a[Mx[V]] < a[Mx[U]])
Mx[V] = Mx[U];
}
nxt[id][0] = Mx[root(id)];
if (nxt[id][0] != id)
nei[nxt[id][0]].push_back(id);
}
for (int i=1;i<=n * m;i++){
if (nxt[i][0] == i)
dfs(i, 0);
}
cin>>q;
for (int i=1;i<=q;i++){
int a, b, c, d, u, v;
cin>>a>>b>>c>>d;
u = a * m + b - m, v = c * m + d - m;
lst[v].insert(i);
lst[u].insert(i);
X[i] = u;
}
for (int i=1;i<=n*m;i++)
Par[i] = 0;
for (auto [vl, pr] : E){
auto [u, v] = pr;
u = root(u), v = root(v);
if (u == v)
continue;
Par[v] = u;
if (lst[u].size() < lst[v].size())
swap(lst[u], lst[v]);
for (int i : lst[v]){
if (lst[u].find(i) != lst[u].end())
Num[i] = vl, lst[u].erase(i);
else
lst[u].insert(i);
}
}
for (int i=1;i<=q;i++){
int u = X[i], ans = 1;
for (int j=18;j+1;j--){
if (nxt[u][j] > 0 and a[nxt[u][j]] < Num[i])
u = nxt[u][j], ans += (1<<j);
}
if (a[u] >= Num[i] or nxt[u][0] != 0)
cout<<ans<<'\n';
else
cout<<"-1\n";
}
}