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.15.1) (judge verdict: Time Limit Exceeded)

#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(non_upper_case_globals)]

#[allow(unused_macros)]
macro_rules! invec {
    ( $ t : ty ) => {{
        let mut s = String::new();
        match std::io::stdin().read_line(&mut s) {
            Ok(0) => Vec::<$t>::new(),
            Ok(n) => s
                .trim()
                .split_whitespace()
                .map(|s| s.parse::<$t>().unwrap())
                .collect::<Vec<$t>>(),
            Err(_) => Vec::<$t>::new(),
        }
    }};
}

#[allow(unused_macros)]
macro_rules! get {
        ($t:ty) => {
            {
                let mut line: String = String::new();
                std::io::stdin().read_line(&mut line).unwrap();
                line.trim().parse::<$t>().unwrap()
            }
        };
        ($($t:ty),*) => {
            {
                let mut line: String = String::new();
                std::io::stdin().read_line(&mut line).unwrap();
                let mut iter = line.split_whitespace();
                (
                    $(iter.next().unwrap().parse::<$t>().unwrap(),)*
                )
            }
        };
        ($t:ty; $n:expr) => {
            (0..$n).map(|_|
                get!($t)
            ).collect::<Vec<_>>()
        };
        ($($t:ty),*; $n:expr) => {
            (0..$n).map(|_|
                get!($($t),*)
            ).collect::<Vec<_>>()
        };
        ($t:ty ;;) => {
            {
                let mut line: String = String::new();
                std::io::stdin().read_line(&mut line).unwrap();
                line.split_whitespace()
                    .map(|t| t.parse::<$t>().unwrap())
                    .collect::<Vec<_>>()
            }
        };
        ($t:ty ;; $n:expr) => {
            (0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
        };
    }

#[allow(unused_macros)]
macro_rules! input {
        (source = $s:expr, $($r:tt)*) => {
            let mut iter = $s.split_whitespace();
            input_inner!{iter, $($r)*}
        };
        ($($r:tt)*) => {
            let mut s = {
                use std::io::Read;
                let mut s = String::new();
                std::io::stdin().read_to_string(&mut s).unwrap();
                s
            };
            let mut iter = s.split_whitespace();
            input_inner!{iter, $($r)*}
        };
    }

macro_rules! input_inner {
        ($iter:expr) => {};
        ($iter:expr, ) => {};

        ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
            let $var = read_value!($iter, $t);
            input_inner!{$iter $($r)*}
        };
    }

#[allow(unused_macros)]
macro_rules! read_value {
        ($iter:expr, ( $($t:tt),* )) => {
            ( $(read_value!($iter, $t)),* )
        };

        ($iter:expr, [ $t:tt ; $len:expr ]) => {
            (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        };

        ($next:expr, [$t:tt]) => {
            {
                let len = read_value!($next, usize);
                (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
            }
        };
        ($iter:expr, chars) => {
            read_value!($iter, String).chars().collect::<Vec<char>>()
        };

        ($iter:expr, usize1) => {
            read_value!($iter, usize) - 1
        };

        ($iter:expr, $t:ty) => {
            $iter.next().unwrap().parse::<$t>().expect("Parse error")
        };
    }

#[cfg(debug_assertions)]
macro_rules! mydbg {
        //($arg:expr) => (dbg!($arg))
        //($arg:expr) => (println!("{:?}",$arg));
        ($($a:expr),*) => {
            eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
        }
    }
#[cfg(not(debug_assertions))]
macro_rules! mydbg {
    ($($arg:expr),*) => {};
}

use std::cmp;
use std::collections::*;
use std::ops::{Add, Div, Mul, Sub};

#[allow(dead_code)]
static INF_I64: i64 = 9223372036854775807;
#[allow(dead_code)]
static INF_I32: i32 = 2147483647;
#[allow(dead_code)]
static INF_USIZE: usize = 18446744073709551615;

fn main() {
    input! {
    h: usize,
    w:usize,
    d:usize,
    a:[[usize;w];h],
    q:usize,
    l:[(usize,usize);q],
    }

    let mut x = vec![0; h * w + 1];
    let mut y = vec![0; h * w + 1];

    for i in 0..h {
        for j in 0..w {
            x[a[i][j]] = j as i32;
            y[a[i][j]] = i as i32;
        }
    }

    let mut cache: HashMap<(usize, usize), i32> = HashMap::new();
    for &(start, end) in &l {
        let mut p = start;
        let mut cost = 0;
        while p != end {
            let mut p1 = p;
            let mut p2 = end;

            if p1 > p2 {
                std::mem::swap(&mut p1, &mut p2);
            }

            match cache.get(&(p1, p2)).clone() {
                Some(x) => {
                    cost += *x;
                    break;
                }
                None => {}
            }

            let to = p + d;

            let mut p1 = p;
            let mut p2 = to;

            if p1 > p2 {
                std::mem::swap(&mut p1, &mut p2);
            }

            let mut ss = start;
            let mut p2 = to;

            if ss > p2 {
                std::mem::swap(&mut ss, &mut p2);
            }

            let mut c = 0;

            match cache.get(&(p1, p2)).clone() {
                Some(x) => {
                    cost += *x;
                }
                None => {
                    c = (x[p1] - x[p2]).abs() + (y[p1] - y[p2]).abs();
                    cost += c;
                }
            }

            cache.entry((p1, p2)).or_insert(c);
            cache.entry((ss, p2)).or_insert(cost);
            p = to;
        }
        println!("{}", cost);
        mydbg!(cost);
    }
}