#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pii pair<int, int>
#define all(a) a.begin(), a.end()
using namespace std;
#ifdef LOCAL
#include "C:\Users\Dell\Downloads\template\template\icpc-notebook\Utilities\debug.h"
#else
#define debug(...) 42
#endif
const int mn = 2e6 + 5, mod = 1e9 + 7, inf = 2e18;
int n, m, l, cnt;
vector <vector <int>> a;
vector <pii> mov = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
bool check(int x, int y) {
return x >= 1 && x <= m && y >= 1 && y <= n;
}
int convert(int x, int y) {
return n * (x - 1) + y;
}
int par_[mn], val[mn], d[mn], st[mn], ft[mn], euler[mn], timer_dfs = 0, up[mn][22], up_par[mn][22], lg2[mn], par[mn];
vector <int> adj[mn], nxt[mn];
void dfs(int u) {
st[u] = ++ timer_dfs; euler[timer_dfs] = u;
for(auto v : adj[u]) {
d[v] = d[u] + 1;
par[v] = u;
dfs(v);
euler[++ timer_dfs] = u;
}
ft[u] = timer_dfs;
}
int higher(int u, int v) {
return (d[u] < d[v] ? u : v);
}
void build() {
for(int i = 1; i <= timer_dfs; i++) up[i][0] = euler[i], up_par[i][0] = par[i];
for(int j = 1; (1 << j) <= timer_dfs; j++) {
for(int i = 1; i <= timer_dfs; i++) {
up[i][j] = higher(up[i][j - 1], up[i + (1 << (j - 1))][j - 1]);
}
}
for(int j = 1; j < 22; j++){
for(int i = 1; i <= cnt; i++){
up_par[i][j] = up_par[up_par[i][j - 1]][j - 1];
}
}
lg2[0] = -1;
for(int i = 1; i <= timer_dfs; i++) lg2[i] = lg2[i >> 1] + 1;
}
int lca(int u, int v) {
int l = st[u], r = st[v];
if(l > r) swap(l, r);
int kc = lg2[r - l + 1];
return higher(up[l][kc], up[r - (1 << kc) + 1][kc]);
}
int kc(int u, int v) {
return val[lca(u, v)];
}
void init() {
cnt = m * n;
for(int i = 1; i <= m * n; i++) par_[i] = i;
}
int find(int u) {
if(u == par_[u]) return u;
return par_[u] = find(par_[u]);
}
void join(int u, int v, int w) {
u = find(u), v = find(v);
if(u == v) return;
cnt ++;
par_[u] = par_[v] = par_[cnt] = cnt;
adj[cnt].push_back(u);
adj[cnt].push_back(v);
val[cnt] = w;
}
int jump(int u, int p){
if(u == 0) return 0;
if(val[u] >= p) return u;
for(int j = 21; j >= 0; --j){
int anc = up_par[u][j];
if(anc != 0 && val[anc] <= p){
u = anc;
}
}
return u;
}
int st2[mn][22];
void dfs2(int u) {
for(auto v : adj[u]) {
st2[v][0] = jump(v, val[v] + l);
dfs2(v);
}
}
bool is_anc(int u, int v) {
return st[u] <= st[v] && st[v] <= ft[u];
}
int ans[3005][3005];
void solve() {
cin >> m >> n >> l;
a.resize(m + 1, vector <int> (n + 1));
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
cin >> a[i][j];
val[convert(i, j)] = a[i][j];
}
}
vector <array<int, 3>> edge;
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
for(auto [di, dj] : mov) {
int ni = i + di, nj = j + dj;
if(check(ni, nj)) {
edge.push_back({max(a[i][j], a[ni][nj]), convert(i, j), convert(ni, nj)});
}
}
}
}
sort(all(edge));
init();
for(auto [w, u, v] : edge) join(u, v, w);
dfs(cnt); build();
val[0] = 2e18;
dfs2(cnt);
for(int j = 1; j < 22; j++){
for(int i = 1; i <= cnt; i++){
st2[i][j] = st2[st2[i][j - 1]][j - 1];
}
}
int q; cin >> q;
while(q--) {
int x, y, u, v; cin >> x >> y >> u >> v;
int a_ = convert(x, y), b_ = convert(u, v);
if(a_ == b_) { cout << 0 << '\n'; continue; }
int curr = jump(a_, val[a_] + l);
if(is_anc(curr, b_)) {
cout << 1 << '\n';
continue;
}
int res = 1;
for(int j = 21; j >= 0; j--) {
int nxt = st2[curr][j];
if (nxt != 0 && !is_anc(nxt, b_)) {
curr = nxt;
res += (1 << j);
}
}
curr = st2[curr][0];
res++;
if(is_anc(curr, b_)){
cout << res << '\n';
}
else cout << -1 << '\n';
}
}
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
#define task "Kawabata"
if (fopen(task".INP", "r")) {
freopen(task".INP", "r", stdin);
freopen(task".OUT", "w", stdout);
}
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}
// Don't wanna lose anymore T_T
// Never let me go - Kazuo Ishiguro