#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second
#define arr3 array<int, 3>
struct dsu{
vector<vector<int>> tt, vv;
vector<int> sz, p, pos;
vector<pii> mx;
int n, cc;
dsu(int ns, vector<int> a){
n = ns;
sz.resize(n + 1);
p.resize(n + 1);
mx.resize(n + 1);
for (int i = 1; i <= n; i++){
sz[i] = 1;
p[i] = i;
mx[i] = {a[i], i};
}
pos.resize(n + 1);
tt.resize(n + 1);
vv.resize(n + 1);
for (int i = 1; i <= n; i++){
tt[i].pb(0);
vv[i].pb(i);
}
cc = 0;
}
int get(int v){
if (p[v] != v){
return get(p[v]);
}
return v;
}
void unite(int x, int y){
x = get(x); y = get(y);
if (x == y) return;
if (sz[x] > sz[y]) swap(x, y);
tt[x].pb(cc);
vv[x].pb(y);
p[x] = y;
sz[y] += sz[x];
mx[y] = max(mx[y], mx[x]);
}
void nw(int v){
pos[v] = ++cc;
}
vector<int> :: iterator it;
int get(int x, int v){
it = upper_bound(tt[v].begin(), tt[v].end(), x);
int j = (int) (it - tt[v].begin()) - 1, p = vv[v][j];
if (p != v){
return get(x, p);
}
return v;
}
int f(int x, int y){
return get(pos[x], x) == get(pos[x], y);
}
};
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m, X; cin>>n>>m>>X;
vector<vector<int>> a(n + 1, vector<int>(m + 1));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cin>>a[i][j];
}
}
const int N = n * m;
vector<vector<int>> p(n + 1, vector<int>(m + 1));
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
p[i][j] = (i - 1) * m + j;
}
}
vector<int> adj[N + 1];
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (i != 1) adj[p[i][j]].pb(p[i - 1][j]);
if (j != 1) adj[p[i][j]].pb(p[i][j - 1]);
if (i != n) adj[p[i][j]].pb(p[i + 1][j]);
if (j != m) adj[p[i][j]].pb(p[i][j + 1]);
}
}
vector<int> A(N + 1);
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
A[p[i][j]] = a[i][j];
}
}
vector<pii> all;
for (int i = 1; i <= N; i++){
all.pb({A[i], i});
}
sort(all.begin(), all.end());
int j = 0;
dsu T(N, A);
vector<bool> act(N + 1);
vector<int> P(N + 1);
for (int i = 0; i < N; i++){
T.nw(all[i].ss);
while (j < N && all[j].ff <= (all[i].ff + X)){
act[all[j].ss] = 1;
for (int v: adj[all[j].ss]){
if (act[v]){
T.unite(v, all[j].ss);
}
}
j++;
}
P[all[i].ss] = T.mx[T.get(all[i].ss)].ss;
}
for (int i = 1; i <= N; i++){
if (A[P[i]] == A[i]){
P[i] = i;
}
}
auto f = [&](int x, int y){
return T.f(x, y);
};
const int lg = log2(N);
vector<vector<int>> sp(N + 1, vector<int>(lg + 1));
for (int i = 1; i <= N; i++) sp[i][0] = P[i];
for (int j = 1; j <= lg; j++){
for (int i = 1; i <= N; i++){
sp[i][j] = sp[sp[i][j - 1]][j - 1];
}
}
int q; cin>>q;
while (q--){
int x1, y1, x2, y2; cin>>x1>>y1>>x2>>y2;
int a = p[x1][y1], b = p[x2][y2], cc = 1;
if (f(a, b)){
cout<<1<<"\n";
continue;
}
for (int i = lg; i >= 0; i--){
if (!f(sp[a][i], b)){
a = sp[a][i];
cc += (1 << i);
}
}
if (f(P[a], b)){
cout<<cc + 1<<"\n";
continue;
}
cout<<-1<<"\n";
}
}