#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
const int dirx[4] = {-1, 0, 1, 0}, diry[4] = {0, 1, 0, -1};
const int lim = 3e5 + 5;
const int LG = 19;
int n, m, k, q, a[lim], b[lim], c[lim], d[lim], lab[lim];
vector<int>up[LG];
vector<vector<int>>h;
vector<int>ah;
int square2id(int x, int y){
return (x - 1) * m + y - 1;
}
int find_set(int i){
while(i != lab[i]){
i = lab[i] = lab[lab[i]];
}
return i;
}
void merge(int i, int j){
if((i = find_set(i)) != (j = find_set(j))){
if(ah[i] < ah[j]){
swap(i, j);
}
lab[j] = i;
}
}
const int INF = 1e9 + 36;
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if(fopen(taskname".inp", "r")){
freopen(taskname".inp", "r", stdin);
}
cin >> n >> m >> k;
h.assign(n + 1, vector<int>(m + 1));
ah.resize(n * m + 1);
vector<pair<int, int>>srt_h;
for(int i = 1, id = 0; i <= n; i++){
for(int j = 1; j <= m; srt_h.push_back(make_pair(i, j++))){
cin >> h[i][j];
ah[id++] = h[i][j];
}
}
cin >> q;
for(int i = 0; i < q; i++){
cin >> a[i] >> b[i] >> c[i] >> d[i];
}
vector<int>low(q, 0), high(q, INF), min_val(q, INF);
while(true){
bool flag = true;
vector<pair<int, int>>event;
for(int i = 0; i < q; i++){
if(low[i] <= high[i]){
event.push_back(make_pair((low[i] + high[i]) >> 1, i));
}
}
if(event.empty()){
break;
}
sort(event.begin(), event.end());
sort(srt_h.begin(), srt_h.end(), [&] (pair<int, int>i, pair<int, int>j){
return h[i.first][i.second] < h[j.first][j.second];
});
int pe = 0;
iota(lab, lab + n * m, 0);
for(auto& [x, y] : srt_h){
while(pe < event.size() && event[pe].first < h[x][y]){
int i = event[pe].second;
if(find_set(square2id(a[i], b[i])) == find_set(square2id(c[i], d[i]))){
high[i] = (min_val[i] = event[pe].first) - 1;
}
else{
low[i] = event[pe].first + 1;
}
pe++;
}
for(int i = 0, id = square2id(x, y); i < 4; i++){
int nx = x + dirx[i], ny = y + diry[i];
if(nx > 0 && nx <= n && ny > 0 && ny <= m && h[nx][ny] <= h[x][y]){
merge(square2id(nx, ny), id);
}
}
}
while(pe < event.size()){
int i = event[pe].second;
if(find_set(square2id(a[i], b[i])) == find_set(square2id(c[i], d[i]))){
high[i] = (min_val[i] = event[pe].first) - 1;
}
else{
low[i] = event[pe].first + 1;
}
pe++;
}
}
for(int i = 0; i < LG; i++){
up[i].resize(n * m);
}
int ps = 0;
iota(lab, lab + n * m, 0);
for(auto& [x, y] : srt_h){
while(ps < srt_h.size()){
auto& [cx, cy] = srt_h[ps];
if(h[cx][cy] + k >= h[x][y]){
break;
}
int id = square2id(cx, cy);
up[0][id] = find_set(id);
ps++;
}
for(int i = 0, id = square2id(x, y); i < 4; i++){
int nx = x + dirx[i], ny = y + diry[i];
if(nx > 0 && nx <= n && ny > 0 && ny <= m && h[nx][ny] <= h[x][y]){
merge(square2id(nx, ny), id);
}
}
}
while(ps < srt_h.size()){
auto& [cx, cy] = srt_h[ps++];
int id = square2id(cx, cy);
up[0][id] = find_set(id);
}
for(int i = 1; i < LG; i++){
for(int j = n * m - 1; j > -1; j--){
up[i][j] = up[i - 1][up[i - 1][j]];
}
}
for(int i = 0; i < q; i++){
int sid = square2id(a[i], b[i]), ans = 0;
for(int bit = LG - 1; bit > -1; bit--){
int nsid = up[bit][sid];
if(ah[nsid] < min_val[i]){
sid = nsid;
ans |= 1 << bit;
}
}
cout << (++ans == (1 << LG) ? -1 : ans) << "\n";
}
}