#pragma once
#include <string.h>
#include <stdio.h>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <utility>
#include <set>
#include <cctype>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <deque>
using namespace std;
#define INF 1000000007
typedef long long ll;
typedef pair<int, int> pii;
int t[101];
int pri[26];
int res = 0;
ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a % b);
}
int pr[100010];
void uini(int n) {
	for (size_t i = 0; i <= n; i++)
	{
		pr[i] = i;
	}
}

int parent(int x) {
	if (x == pr[x]) return x;
	return pr[x] = parent(pr[x]);
}

bool unit(int x, int y) {
	int px = parent(x);
	int py = parent(y);

	if (px == py) return false;
	if (px < py) {
		pr[y] = px;
	}
	else {
		pr[x] = py;
	}
	return true;
}

// dinic
struct max_flow {
	struct edge { int to, cap, rev;
	edge(int _to, int _cap, int _rev) : to(_to), cap(_cap), rev(_rev) {}
	};
	int V;
	vector<vector<edge>> G;
	vector<int> itr, level;

	max_flow(int V) : V(V) { G.assign(V, vector<edge>()); }

	void add_edge(int from, int to, int cap) {
		G[from].push_back(edge (to, cap, (int)G[to].size() ));
		G[to].push_back(edge (from, 0, (int)G[from].size() - 1 ));
	}

	void bfs(int s) {
		level.assign(V, -1);
		queue<int> q;
		level[s] = 0; q.push(s);
		while (!q.empty()) {
			int v = q.front(); q.pop();
			for (auto &e : G[v]) {
				if (e.cap > 0 and level[e.to] < 0) {
					level[e.to] = level[v] + 1;
					q.push(e.to);
				}
			}
		}
	}

	int dfs(int v, int t, int f) {
		if (v == t) return f;
		for (int& i = itr[v]; i < (int)G[v].size(); ++i) {
			edge& e = G[v][i];
			if (e.cap > 0 && level[v] < level[e.to]) {
				int d = dfs(e.to, t, min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					G[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}

	int run(int s, int t) {
		int ret = 0, f;
		while (bfs(s), level[t] >= 0) {
			itr.assign(V, 0);
			while ((f = dfs(s, t, INF)) > 0) ret += f;
		}
		return ret;
	}
};
vector<vector<int> > calcNext(const string &S) {
	int n = (int)S.size();
	vector<vector<int> > res(n + 1, vector<int>(26, n));
	for (int i = n - 1; i >= 0; --i) {
		for (int j = 0; j < 26; ++j) res[i][j] = res[i + 1][j];
		res[i][S[i] - 'a'] = i;
	}
	return res;
}

const int MOD = 1000000007;
// mod 1000000007 の世界で a += b する関数
void add(long long &a, long long b) {
	a += b;
	if (a >= MOD) a -= MOD;
}


int dx[] = { 1,0,-1,0 };
int dy[] = { 0,1,0,-1 };
int d[55][55];

void solv() {
	int h,w,d;
	cin >> h >> w >> d;
	pair<int, int> cell[100010];
	for (size_t i = 1; i <= h; i++)
	{
		for (size_t j = 1; j <= w; j++)
		{
			int a;
			cin >> a;
			cell[a] = pii(i,j);
		}
	}

	int q;
	cin >> q;
	ll f[100010], t[100010];
	for (size_t i = 0; i < q ;i++)
	{
		cin >> f[i] >> t[i];
	}

	ll cos[100010];
	memset(cos, -1, sizeof(cos));
	for (size_t i = 1; i < 100010; i++)
	{
		if (cos[i] != -1) continue;
		if (cell[i].first == 0) continue;
		int px = cell[i].first;
		int py = cell[i].second;
		int ti = i + d;
		cos[i] = 0;
		while (ti < 100010)
		{
			if (cell[ti].first == 0) break;
			int nx = cell[ti].first;
			int ny = cell[ti].second;
			cos[ti] = cos[ti - d] + abs(px - nx) + abs(py - ny);
			px = nx;
			py = ny;
			ti += d;
		}
	}

	for (size_t i = 0; i < q; i++)
	{
		int fv = f[i];
		int tv = t[i];
		cout << (cos[tv] - cos[fv]) << endl;
	}
}


int main() {
	solv();

	return 0;
}


Measured memory_bytes: 4224