#include <bits/stdc++.h>
using namespace std;
struct Fast {Fast(){std::cin.tie(0);ios::sync_with_stdio(false);cout.precision(20);}} fast;

/* define */
#define FOR(I,X,Y) for(long long (I)=(X);(I)<(Y);(I)++)
#define REP(I,X,Y) for(long long (I)=(Y)-1;(I)>=(X);(I)--)
#define ALL(X) (X).begin(),(X).end()
#define pb push_back
#define COUNT(V,X) (upper_bound((V).begin(),(V).end(),X)-lower_bound((V).begin(),(V).end(),X))
#define debug(x) cerr<<#x<<':'<<x<<endl;
#define DEBUG(v) cerr<<#v<<':';for(auto xXx:v)cerr<<xXx<<' ';cerr<<endl;
#define Yes(X) if(X){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
#define YES(X) if(X){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}
#define ctoi(C) (C-'0')
#define pow2(x) ((long long)((long long)1<<x))

/* alias */
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vii = vector<vector<int>>;
using vl = vector<long long>;
using vll = vector<vector<long long>>;
using pi = pair<int,int>;
using pl = pair<long long,long long>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using minPQ = priority_queue<T, vector<T>, greater<T>>;

/* const */
const long long dx[] = {1,0,-1,0};
const long long dy[] = {0,1,0,-1};
const long long dx8[] = {1,1,0,-1,-1,-1,0,1};
const long long dy8[] = {0,1,1,1,0,-1,-1,-1};
const long long dx9[] = {1,1,0,-1,-1,-1,0,1,0};
const long long dy9[] = {0,1,1,1,0,-1,-1,-1,0};
const int INF = 1000000007;
const long long LINF = 1000000000000000007;

/* func */
template <typename T> inline bool chmin(T& a, const T& b) {if (a > b) a = b; return a > b;}
template <typename T> inline bool chmax(T& a, const T& b) {if (a < b) a = b; return a < b;}
long long max(long long x,int y){return max(x,(long long)y);}
long long max(int x,long long y){return max((long long)x,y);}
long long min(long long x,int y){return min(x,(long long)y);}
long long min(int x,long long y){return min((long long)x,y);}

/* liblary */

struct WeightedUnionFind{
  vector<long long> data;
  vector<long long> dif;
  void boot(long long n){
    for(long long i = 0;i < n;i++)data.push_back(-1);
    for(long long i = 0;i < n;i++)dif.push_back(0);
    return;
  }
  long long root(long long x){
    if(data[x] < 0)return x;
    long long r = root(data[x]);
    dif[x] += dif[data[x]];
    return data[x] = root(data[x]);
  }
  long long weight(long long x){
    root(x);
    return dif[x];
  }
  bool same(long long x,long long y){
    return root(x) == root(y);
  }
  void unite(long long x,long long y,long long w){
    if(!same(x,y)){
      w += weight(x);
      w -= weight(y);
      x = root(x);
      y = root(y);
      if(data[x] < data[y]){
        data[x] += data[y];
        data[y] = x;
        dif[y] = w;
      }
      else{
        data[y] += data[x];
        data[x] = y;
        dif[x] = -w;
      }
    }
    return;
  }
  long long getsize(long long x){
    return -data[root(x)];
  }
  long long diff(long long x,long long y){
    return dif[y] - dif[x];
  }
};

/* main */

ll H,W,D;

map<ll,pl> m;
ll dist(ll A1,ll A2){
	return abs(m[A1].first-m[A2].first) + abs(m[A1].second-m[A2].second);
}

WeightedUnionFind UF;

void preprocess(){
	UF.boot(H*W+100);
	FOR(i,1,H*W+1){
		if(i+D>H*W)break;
		UF.unite(i,i+D,dist(i,i+D));
	}
}

ll func(ll L,ll R){
	return UF.diff(L,R);
}

signed main(){
	cin >> H >> W >> D;
	FOR(i,0,H)FOR(j,0,W){
		ll A;
		cin >> A;
		m[A] = make_pair(i,j);
	}
	preprocess();
	ll Q;
	cin >> Q;
	FOR(i,0,Q){
		ll L,R;
		cin >> L >> R;
		cout << func(L,R) << endl;
	}
}

Measured memory_bytes: 8308