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: Accepted)

fn main() {
    let ss = io::read_string();
    let mut sc = io::Scanner::new(&ss);
    let h:usize = sc.next();
    let w:usize = sc.next();
    let d:usize = sc.next();
    let mut a:[(usize, usize); 90001] = [(0,0);90001];
    let mut dd: [usize; 90001] = [0;90001];
    
    for i in 0..h {
        for k in 0..w {
            let aki:usize = sc.next();
            a[aki] = (i,k);
        }
    }

    for i in d+1..h*w + 1 {
        dd[i] = dd[i-d] + manhattan(a[i], a[i-d]);
    }

    let q = sc.next();

    let qs:Vec<(usize, usize)> = (0..q).map(|_| (sc.next(), sc.next())).collect();

    for (l, r) in qs {
        println!("{}", dd[r] - dd[l]);
    }
}

fn manhattan(a:(usize, usize), b:(usize, usize)) -> usize {
    let x = a.0 as isize - b.0 as isize;
    let y = a.1 as isize - b.1 as isize;

    (x.abs() + y.abs()) as usize
}
pub mod io {
    use std;
    use std::str::FromStr;

    pub struct Scanner<'a> {
        iter: std::str::SplitWhitespace<'a>,
    }

    impl<'a> Scanner<'a> {
        pub fn new(s: &'a str) -> Scanner<'a> {
            Scanner {
                iter: s.split_whitespace(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T {
            let s = self.iter.next().unwrap();
            if let Ok(v) = s.parse::<T>() {
                v
            } else {
                panic!("Parse error")
            }
        }

        pub fn next_vec_len<T: FromStr>(&mut self) -> Vec<T> {
            let n: usize = self.next();
            self.next_vec(n)
        }

        pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.next()).collect()
        }
    }

    pub fn read_string() -> String {
        use std::io::Read;

        let mut s = String::new();
        std::io::stdin().read_to_string(&mut s).unwrap();
        s
    }

    pub fn read_line() -> String {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        s.trim_right().to_owned()
    }
}

pub mod num {
    use std::ops::{Add, Div, Mul, Neg, Rem, Sub};

    pub trait NumOps<Rhs = Self, Output = Self>:
        Add<Rhs, Output = Output>
        + Sub<Rhs, Output = Output>
        + Mul<Rhs, Output = Output>
        + Div<Rhs, Output = Output>
        + Rem<Rhs, Output = Output>
        + Neg<Output = Output>
    {
}

    impl<T, Rhs, Output> NumOps<Rhs, Output> for T
    where
        T: Add<Rhs, Output = Output>
            + Sub<Rhs, Output = Output>
            + Mul<Rhs, Output = Output>
            + Div<Rhs, Output = Output>
            + Rem<Rhs, Output = Output>
            + Neg<Output = Output>,
    {
    }

    pub trait Num: PartialEq + NumOps + From<i32> {}

    pub trait Float: Num + Copy + PartialOrd + Neg<Output = Self> {}

    #[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
    pub struct Complex<T> {
        /// Real portion of the complex number
        pub re: T,
        /// Imaginary portion of the complex number
        pub im: T,
    }

    impl<T: Clone + Num> Complex<T> {
        /// Create a new Complex
        #[inline]
        pub fn new(re: T, im: T) -> Complex<T> {
            Complex { re: re, im: im }
        }

        #[inline]
        pub fn i() -> Complex<T> {
            Self::new(0.into(), 1.into())
        }

        #[inline]
        pub fn norm_sqr(&self) -> T {
            self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
        }
    }

    impl<T: Clone + Num> Complex<T> {
        /// Returns the complex conjugate. i.e. `re - i im`
        #[inline]
        pub fn conj(&self) -> Complex<T> {
            Complex::new(self.re.clone(), -self.im.clone())
        }

        /// Returns `1/self`
        #[inline]
        pub fn inv(&self) -> Complex<T> {
            let norm_sqr = self.norm_sqr();
            Complex::new(
                self.re.clone() / norm_sqr.clone(),
                -self.im.clone() / norm_sqr,
            )
        }
    }

    pub fn gcd<T: Num + Copy>(a: T, b: T) -> T {
        if a % b == 0.into() {
            a
        } else {
            gcd(b, a % b)
        }
    }

    pub fn lcm<T: Num + Copy>(a: T, b: T) -> T {
        let g = gcd(a, b);
        a / g * b
    }
}

pub mod modular {
    const M: i64 = 1000000007;

    #[derive(Debug, Clone, Copy, Default, PartialOrd, Ord, PartialEq, Eq)]
    pub struct Modular(i64);

    impl ::std::fmt::Display for Modular {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }

    impl Modular {
        pub fn new(v: i64) -> Modular {
            Modular(v % M)
        }

        pub fn pow(self, mut r: i64) -> Modular {
            let mut k = self;
            let mut ret = 1.into();

            while r > 0 {
                if r % 2 != 0 {
                    ret = ret * k;
                }
                r /= 2;
                k = k * k;
            }

            ret
        }

        // This requires M is prime
        pub fn recip(self) -> Modular {
            self.pow(M - 2)
        }
    }

    use std::ops::*;

    impl<T: Into<Modular>> Add<T> for Modular {
        type Output = Modular;
        fn add(self, rhs: T) -> Self::Output {
            Modular::new(self.0 + rhs.into().0)
        }
    }
    impl<T: Into<Modular>> AddAssign<T> for Modular {
        fn add_assign(&mut self, rhs: T) {
            *self = *self + rhs;
        }
    }

    impl<T: Into<Modular>> Sub<T> for Modular {
        type Output = Modular;
        fn sub(self, rhs: T) -> Self::Output {
            Modular::new(self.0 - rhs.into().0 + M)
        }
    }
    impl<T: Into<Modular>> SubAssign<T> for Modular {
        fn sub_assign(&mut self, rhs: T) {
            *self = *self - rhs;
        }
    }

    impl<T: Into<Modular>> Mul<T> for Modular {
        type Output = Modular;
        fn mul(self, rhs: T) -> Self::Output {
            Modular::new(self.0 * rhs.into().0)
        }
    }
    impl<T: Into<Modular>> MulAssign<T> for Modular {
        fn mul_assign(&mut self, rhs: T) {
            *self = *self * rhs;
        }
    }

    impl<T: Into<Modular>> Div<T> for Modular {
        type Output = Modular;
        fn div(self, rhs: T) -> Self::Output {
            self * rhs.into().recip()
        }
    }
    impl<T: Into<Modular>> DivAssign<T> for Modular {
        fn div_assign(&mut self, rhs: T) {
            *self = *self / rhs;
        }
    }

    impl Neg for Modular {
        type Output = Modular;
        fn neg(self) -> Self::Output {
            Modular(0) - self
        }
    }

    impl<T: ::std::convert::Into<i64>> ::std::convert::From<T> for Modular {
        fn from(v: T) -> Self {
            Modular::new(v.into())
        }
    }
}

pub mod union_find {
    pub struct UnionFind(Vec<usize>);

    impl UnionFind {
        pub fn new(n: usize) -> UnionFind {
            UnionFind((0..n).collect())
        }

        pub fn find(&mut self, i: usize) -> usize {
            if self.0[i] == i {
                i
            } else {
                let p = self.0[i];
                self.0[i] = self.find(p);
                self.0[i]
            }
        }

        pub fn union(&mut self, i: usize, j: usize) {
            let ni = self.find(i);
            let nj = self.find(j);
            self.0[ni] = nj;
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn scanner_test() {
        use io::Scanner;

        let mut sc = Scanner::new("1 3.14 Hello");

        assert_eq!(sc.next::<i32>(), 1);
        assert_eq!(sc.next::<f64>(), 3.14);
        assert_eq!(sc.next::<String>(), "Hello");

        // let v: Vec<f64> = (0..10).map(|_| sc.next()).collect();

        // let mut sc = Scanner::new("1 2 3 4 5");
        // let v: Vec<i32> = vec![sc.next(); 5];
        // println!("{:?}", v);
    }

    #[test]
    fn test_modular() {
        use modular::*;

        let x: Modular = 12345678.into();
        let y: Modular = 87654321.into();
        assert_eq!(y * x * x.recip(), y);
    }

    #[test]
    fn union_find_test() {
        use union_find::UnionFind;

        let mut uf = UnionFind::new(5);
        uf.union(0, 1);
        uf.union(2, 3);
        uf.union(0, 4);

        assert_eq!(uf.find(0), uf.find(1));
        assert_eq!(uf.find(2), uf.find(3));
        assert_eq!(uf.find(0), uf.find(4));
        assert_eq!(uf.find(1), uf.find(4));
        assert_ne!(uf.find(0), uf.find(2));
        assert_ne!(uf.find(3), uf.find(4));
    }
}