#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define vl vector<long long>
#define vi vector<int>
#define pii pair<int,int>
#define pll pair<long long, long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace std;
//mt19937 mt;void random(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll rand(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;
struct event
{
int time,type,x,y;
bool operator<(const event& other) const
{
if(time != other.time) return time < other.time;
return type < other.type;
}
};
int parent[300'005];
int parent_time[300'005];
pii max_val[300'005];
vi T[300'005];
int TV[300'005];
int subtree[300'005];
int jump[300'005][20];
bool odw[300'005];
pii find_(int v)
{
if(parent[v] == -1)
{
return {v,0};
}
pii w = find_(parent[v]);
return {w.ff,max(w.ss,parent_time[v])};
}
void union_(int a, int b,int t)
{
pii p1 = find_(a);
pii p2 = find_(b);
if(subtree[p1.ff] > subtree[p2.ff]) swap(p1,p2);
if(p1.ff == p2.ff)
{
return;
}
subtree[p2.ff] += subtree[p1.ff];
parent[p1.ff] = p2.ff;
parent_time[p1.ff] = t;
max_val[p2.ff] = max(max_val[p1.ff],max_val[p2.ff]);
}
bool check(int a, int b, int t)
{
int cur_a = a;
odw[cur_a] = 1;
while(parent[cur_a] != -1 && parent_time[cur_a] <= t)
{
cur_a = parent[cur_a];
odw[cur_a] = 1;
}
bool is_ok = 0;
int cur_b = b;
if(odw[cur_b]) is_ok = 1;
while(parent[cur_b] != -1 && parent_time[cur_b] <= t)
{
cur_b = parent[cur_b];
if(odw[cur_b]) is_ok = 1;
}
cur_a = a;
odw[cur_a] = 0;
while(parent[cur_a] != -1 && parent_time[cur_a] <= t)
{
cur_a = parent[cur_a];
odw[cur_a] = 0;
}
return is_ok;
}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//random();
int n,m,L;
cin >> n >> m >> L;
rep(i,n) T[i].resize(m);
rep(i,n) rep(j,m) cin >> T[i][j];
rep(i,n) rep(j,m)
{
int v = i*m+j;
TV[v] = T[i][j];
parent[v] = -1;
subtree[v] = 1;
max_val[v] = {T[i][j],v};
}
vector<event> events;
rep(i,n) rep(j,m)
{
events.pb({T[i][j],0,i,j});
events.pb({T[i][j]+L,1,i,j});
}
sort(all(events));
vector<pii> dir = {{-1,0},{1,0},{0,-1},{0,1}};
forall(it,events)
{
if(it.type == 0)
{
forall(d,dir)
{
if(it.x + d.ff >= 0 && it.x + d.ff < n && it.y + d.ss >= 0 && it.y + d.ss < m && T[it.x+d.ff][it.y+d.ss] <= T[it.x][it.y])
{
union_(it.x*m+it.y,(it.x+d.ff) * m + (it.y + d.ss),it.time);
}
}
}
else
{
pii p = find_(it.x * m + it.y);
jump[it.x*m+ it.y][0] = max_val[p.ff].ss;
}
}
rep2(bit,1,19)
{
rep(v,n*m)
{
jump[v][bit] = jump[jump[v][bit-1]][bit-1];
}
}
int q;
cin >> q;
rep(i,q)
{
int a,b,c,d;
cin >> a >> b >> c >> d;
a--;
b--;
c--;
d--;
int v1 = a*m+b;
int v2 = c*m+d;
if(v1 == v2)
{
cout << "0\n";
continue;
}
if(check(v1,v2,TV[v1]+L))
{
cout << "1\n";
continue;
}
int ans = 0;
if(!check(jump[v1][19],v2,TV[jump[v1][19]]+L))
{
cout << "-1\n";
continue;
}
for(int bit = 18; bit >= 0; bit--)
{
// cout << v1 << " " << v2 << " " << jump[v1][bit] << " " << bit << " jump\n";
int new_v = jump[v1][bit];
if(!check(new_v,v2,TV[new_v]+L))
{
ans += (1 << bit);
v1 = new_v;
}
}
cout << ans+2 << "\n";
}
}