Vanya is in the palace that can be represented as a grid n × m. Each room contains a single chest, an the room located in the i-th row and j-th columns contains the chest of type aij. Each chest of type x ≤ p - 1 contains a key that can open any chest of type x + 1, and all chests of type 1 are not locked. There is exactly one chest of type p and it contains a treasure.

Vanya starts in cell (1, 1) (top left corner). What is the minimum total distance Vanya has to walk in order to get the treasure? Consider the distance between cell (r1, c1) (the cell in the row r1 and column c1) and (r2, c2) is equal to |r1 - r2| + |c1 - c2|.

Input

The first line of the input contains three integers n, m and p (1 ≤ n, m ≤ 300, 1 ≤ p ≤ n·m) — the number of rows and columns in the table representing the palace and the number of different types of the chests, respectively.

Each of the following n lines contains m integers aij (1 ≤ aij ≤ p) — the types of the chests in corresponding rooms. It's guaranteed that for each x from 1 to p there is at least one chest of this type (that is, there exists a pair of r and c, such that arc = x). Also, it's guaranteed that there is exactly one chest of type p.

Output

Print one integer — the minimum possible total distance Vanya has to walk in order to get the treasure from the chest of type p.

Examples

Input

3 4 3
2 1 1 1
1 1 1 1
2 1 1 3


Output

5


Input

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


Output

22


Input

3 4 12
1 2 3 4
8 7 6 5
9 10 11 12


Output

11
/**
 * Solution to "Vanya and Treasure"
 * using a 2D segment tree as described in editorial
 * http://codeforces.com/blog/entry/45181
 */
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Treasure2D {
    public static void main(String []av) { new Treasure2D(); }

    int n, m;
    int fromxy(int x, int y) { return x * m + y; }
    int getx(int x) { return x/m; }
    int gety(int x) { return x%m; }

    @SuppressWarnings("unchecked")
    Treasure2D() {
        Scanner s = new Scanner();
        n = s.nextInt();
        m = s.nextInt();
        int p = s.nextInt();
        int [][] a = new int[n][m];

        List<Integer> [] treasurek = new List[p+1];
        for (int i = 0; i < p+1; i++)
            treasurek[i] = new ArrayList<Integer>();

        int goalx = -1, goaly = -1;
        int [][] mindist = new int[n][m];       // minium
        for (int i = 0; i < n; i++) {
            Arrays.fill(mindist[i], Integer.MAX_VALUE);
            for (int j = 0; j < m; j++) {
                a[i][j] = s.nextInt();
                if (a[i][j] == 1)
                    mindist[i][j] = i + j;  // start point is (0, 0)

                treasurek[a[i][j]].add(fromxy(i, j));
                if (a[i][j] == p) {
                    goalx = i;
                    goaly = j;
                }
            }
        }

        final int INF = Integer.MAX_VALUE/4;
        SegmentTree2D NE = new SegmentTree2D(n, m, INF);
        SegmentTree2D NW = new SegmentTree2D(n, m, INF);
        SegmentTree2D SE = new SegmentTree2D(n, m, INF);
        SegmentTree2D SW = new SegmentTree2D(n, m, INF);
        for (int k = 2; k <= p; k++) {
            // DP: compute min dist to reach the treasures containing lock k.
            // Assumes mindist[x][y] already contains the mindist for all locks < k
            // at their locations.  k = 1 was computed above.
            //
            // For each lock k, the optimal dist comes via a path from a treasure 
            // containing lock k-1.  This treasure lies either SW, NW, SE, or NE 
            // relative to the treasure.  We find the best cost separately for each
            // quadrant.  Consider the SW quadrant wlog.
            //
            // We must find, for each (x, y) where a treasure k is located:
            //
            // min(mindist[tk1] + x - tk1_x + y - tk1_y) over all previous 
            // treasures tk1
            //
            // Populate a 2D (set, min) segment tree with
            //
            //      mindist[tk1] - tk1_x - tk1_y
            //
            // Find the min relative to the quadrants created by each treasure tk.
            // Reconstruct the actual cost by adding in x + y. 
            //
            // Analogous for the other quadrants.
            //
            // The 2D segment tree will find the minimum point in O (log n log m).
            //
            for (int src : treasurek[k-1]) {
                int x = getx(src);
                int y = gety(src);
                SW.set(x, y, mindist[x][y]-x-y);
                SE.set(x, y, mindist[x][y]+x-y);
                NW.set(x, y, mindist[x][y]-x+y);
                NE.set(x, y, mindist[x][y]+x+y);
            }

            // now find best points for each quadrant, computing mindist[x][y]
            // for treasure level k 
            for (int dst : treasurek[k]) {
                int x = getx(dst);
                int y = gety(dst);
                mindist[x][y] =                    SW.min(0, x,   0, y  )+x+y;
                mindist[x][y] = min(mindist[x][y], SE.min(x, n-1, 0, y  )-x+y);
                mindist[x][y] = min(mindist[x][y], NW.min(0, x,   y, m-1)+x-y);
                mindist[x][y] = min(mindist[x][y], NE.min(x, n-1, y, m-1)-x-y);
            }

            // reset the trees (reset() is way too slow)
            for (int src : treasurek[k-1]) {
                int x = getx(src);
                int y = gety(src);
                SW.set(x, y, INF);
                SE.set(x, y, INF);
                NW.set(x, y, INF);
                NE.set(x, y, INF);
            }
        }

        System.out.println(mindist[goalx][goaly]);
    }

    // from https://sites.google.com/site/indy256/algo/segment_tree_fast_add_max_2d
    // modified to support (set(x, y), min) operations
    static class SegmentTree2D {
        int [][] t;
        int n, m;
        SegmentTree2D(int n, int m, int def) { 
            this.n = n;
            this.m = m;
            t = new int[2*n][2*m]; 
            reset(def);
        }

        void reset(int def) {
            for (int [] _t : t)
                Arrays.fill(_t, def);
        }

        // find min in [x1,x2] x [y1,y2] (both ends inclusive)
        public int min(int x1, int x2, int y1, int y2) {
            x1 += n;
            x2 += n;
            y1 += m;
            y2 += m;
            int res = Integer.MAX_VALUE;
            for (int lx = x1, rx = x2; lx <= rx; lx = (lx + 1) >> 1, rx = (rx - 1) >> 1)
                for (int ly = y1, ry = y2; ly <= ry; ly = (ly + 1) >> 1, ry = (ry - 1) >> 1) {
                    if ((lx & 1) != 0 && (ly & 1) != 0) res = Math.min(res, t[lx][ly]);
                    if ((lx & 1) != 0 && (ry & 1) == 0) res = Math.min(res, t[lx][ry]);
                    if ((rx & 1) == 0 && (ly & 1) != 0) res = Math.min(res, t[rx][ly]);
                    if ((rx & 1) == 0 && (ry & 1) == 0) res = Math.min(res, t[rx][ry]);
                }
            return res;
        }

        // set value at [x, y] to value
        public void set(int x, int y, int value) {
            x += n;
            y += m;
            t[x][y] = value;
            for (int tx = x; tx > 0; tx >>= 1)
                for (int ty = y; ty > 0; ty >>= 1) {
                    if (tx > 1) t[tx >> 1][ty] = Math.min(t[tx][ty], t[tx ^ 1][ty]);
                    if (ty > 1) t[tx][ty >> 1] = Math.min(t[tx][ty], t[tx][ty ^ 1]);
                }
        }
    }

    //-----------Scanner class for faster input----------
    /* Provides similar API as java.util.Scanner but does not
     * use regular expression engine.  
     */
    public static class Scanner {
        BufferedReader br;
        StringTokenizer st;

        public Scanner(Reader in) {
            br = new BufferedReader(in);
        }

        public Scanner() { this(new InputStreamReader(System.in)); }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() { return Integer.parseInt(next()); }
    }
    //--------------------------------------------------------    
}
