// CHAT GPT BRUTE
#include <bits/stdc++.h>
using namespace std;
int H, W, Q;
long long L;
vector<vector<int>> T;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
struct State {
int x, y;
};
int solve(int sx, int sy, int tx, int ty) {
if (sx == tx && sy == ty) return 0;
vector<vector<int>> dist(H, vector<int>(W, -1));
queue<State> q;
q.push({sx, sy});
dist[sx][sy] = 0;
while (!q.empty()) {
State cur = q.front();
q.pop();
int cx = cur.x;
int cy = cur.y;
// startujemy HIGH JUMP z (cx, cy)
queue<pair<int,int>> bfs;
vector<vector<bool>> vis(H, vector<bool>(W, false));
bfs.push({cx, cy});
vis[cx][cy] = true;
while (!bfs.empty()) {
auto [x, y] = bfs.front();
bfs.pop();
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
if (vis[nx][ny]) continue;
if (T[nx][ny] <= T[cx][cy] + L) {
vis[nx][ny] = true;
bfs.push({nx, ny});
}
}
}
// wszystkie osiągalne po 1 jumpie
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if (!vis[i][j]) continue;
if (dist[i][j] != -1) continue;
dist[i][j] = dist[cx][cy] + 1;
q.push({i, j});
}
}
}
return dist[tx][ty];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> H >> W >> L;
T.assign(H, vector<int>(W));
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
cin >> T[i][j];
}
}
cin >> Q;
while (Q--) {
int A, B, C, D;
cin >> A >> B >> C >> D;
A--; B--; C--; D--;
cout << solve(A, B, C, D) << "\n";
}
}