Problem:
Score : 400 points

Problem Statement

We have a grid with H rows and W columns. The square at the i-th row and the j-th column will be called Square (i,j).

The integers from 1 through H×W are written throughout the grid, and the integer written in Square (i,j) is A_{i,j}.

You, a magical girl, can teleport a piece placed on Square (i,j) to Square (x,y) by consuming |x-i|+|y-j| magic points.

You now have to take Q practical tests of your ability as a magical girl.

The i-th test will be conducted as follows:

Initially, a piece is placed on the square where the integer L_i is written.

Let x be the integer written in the square occupied by the piece. Repeatedly move the piece to the square where the integer x+D is written, as long as x is not R_i. The test ends when x=R_i.

Here, it is guaranteed that R_i-L_i is a multiple of D.

For each test, find the sum of magic points consumed during that test.

Constraints

1 \leq H,W \leq 300

1 \leq D \leq H×W

1 \leq A_{i,j} \leq H×W

A_{i,j} \neq A_{x,y} ((i,j) \neq (x,y))

1 \leq Q \leq 10^5

1 \leq L_i \leq R_i \leq H×W

(R_i-L_i) is a multiple of D.

Input

Input is given from Standard Input in the following format:

H W D
A_{1,1} A_{1,2} ... A_{1,W}
:
A_{H,1} A_{H,2} ... A_{H,W}
Q
L_1 R_1
:
L_Q R_Q

Output

For each test, print the sum of magic points consumed during that test.

Output should be in the order the tests are conducted.

Sample Input 1

3 3 2
1 4 3
2 5 7
8 9 6
1
4 8

Sample Output 1

5

4 is written in Square (1,2).

6 is written in Square (3,3).

8 is written in Square (3,1).

Thus, the sum of magic points consumed during the first test is (|3-1|+|3-2|)+(|3-3|+|1-3|)=5.

Sample Input 2

4 2 3
3 7
1 4
5 2
6 8
2
2 2
2 2

Sample Output 2

0
0

Note that there may be a test where the piece is not moved at all, and there may be multiple identical tests.

Sample Input 3

5 5 4
13 25 7 15 17
16 22 20 2 9
14 11 12 1 19
10 6 23 8 18
3 21 5 24 4
3
13 13
2 10
13 13

Sample Output 3

0
5
0

Solution in Rust (1.42.0) (judge verdict: Accepted)

#![allow(non_snake_case)]
#![allow(unused_imports)]
use ascii::AsciiChar;
use ascii::AsciiStr;
use itertools::Itertools as _;
use permutohedron::LexicalPermutation as _;
use petgraph::algo::dijkstra;
use petgraph::algo::min_spanning_tree;
use petgraph::data::FromElements;
use petgraph::graph::NodeIndex;
use petgraph::graph::UnGraph;
use petgraph::unionfind::UnionFind;
use proconio::fastout;
use proconio::input;
use proconio::marker::Chars;
use proconio::marker::Usize1;
use std::cmp::max;
use std::cmp::min;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
use superslice::Ext as _;

#[allow(dead_code)]
fn calc_mp(val_to_grid: &HashMap<i64, (isize, isize)>, prev_val: i64, cur_val: i64, D: i64) -> i64 {
    if cur_val <= D {
        return 0;
    }

    let (prev_h, prev_w) = val_to_grid.get(&prev_val).unwrap();
    let (cur_h, cur_w) = val_to_grid.get(&cur_val).unwrap();
    let mp = ((prev_h - cur_h).abs() + (prev_w - cur_w).abs()) as i64;

    return mp;
}

#[fastout]
fn main() {
    input! {
        H: usize,
        W: usize,
        D: i64,
        Asz: [[i64; W]; H],
        Q: usize,
        LRs: [(i64, i64); Q],
    }

    // Asz -> 座標 は10^5オーダで分かる
    // なので、2つのマスに書かれた整数が与えられた時、ワープに必要な魔力はすぐ計算できる

    let mut val_to_grid: HashMap<i64, (isize, isize)> = HashMap::new();
    for h in 0..H {
        for w in 0..W {
            let a = Asz[h][w];
            val_to_grid.insert(a, (h as isize, w as isize));
        }
    }

    // 雰囲気としては、累積和の列がいくつもある感じ

    // 1, 1+D, 1+2D... → 必要な魔力の累積和にする
    // 2, 2+D, 2+2D...
    // 3, 3+D, 3+2D...
    // 0, 0+D, 0+2D... (便宜的に0から始まることにしよう)

    // あれ、イイとこ突いてそうだけど、なんで気付けた?
    // ・進む方向が一方向しかないので、レールがいくつかあってそれのどれかに乗るイメージ

    // 累積和の最初の0、初項の0 (0~D-1)
    let mut acc = vec![vec![0i64, 0]; D as usize];
    for group in 0..D as usize {
        for cur_val_usize in (group + D as usize..=H * W).step_by(D as usize) {
            let cur_val = cur_val_usize as i64;
            let prev_val = cur_val - D;
            let mp = calc_mp(&val_to_grid, prev_val, cur_val, D);
            let cur_ind = (cur_val / D) as usize;

            let acc_mp = acc[group as usize][cur_ind] + mp;
            acc[group as usize].push(acc_mp);
        }
    }

    // dbg!(&acc);

    for &(l, r) in LRs.iter() {
        // let mut consumed_mp: i64 = 0;

        // このループ、mpの計算がO(1)で済むとしても最悪O(HW)かかる
        // for x in (l..=r).step_by(D as usize) {
        //     consumed_mp += calc_mp(x, x + D);
        // }

        // FIXME : group = 0 の時に特殊処理が必要なのはキレイじゃないなー
        let group: usize = (l % D) as usize;
        let l_ind: usize = ((l - group as i64) / D) as usize;
        let r_ind: usize = ((r - group as i64) / D) as usize;
        // dbg!(group);
        // dbg!(l_ind);
        // dbg!(r_ind);

        let consumed_mp: i64 = acc[group][r_ind + 1] - acc[group][l_ind + 1];

        println!("{}", consumed_mp);
    }
}