#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int x, y, next;
} edge[305 * 305];
int e, ft[305 * 305], cnt[305 * 305];
int N;
long long inf, dp[305][305], d[305][305];
bool flag[305][305];
int r, c, p, maze[305][305];
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
struct Node {
  int x, y;
  Node() {}
  Node(int x, int y) : x(x), y(y) {}
  bool operator<(const Node &other) const {
    return d[x][y] > d[other.x][other.y];
  }
} deq[305 * 305 * 2];
int head, tail, top;
bool in(int x, int y) { return x >= 0 && x < r && y >= 0 && y < c; }
void init() {
  N = r * c;
  inf = (long long)N * (long long)N + 1;
  e = 0;
  memset(ft, -1, sizeof(int) * (p + 2));
  memset(cnt, 0, sizeof(int) * (p + 2));
}
void insert_edge(int u, int x, int y) {
  cnt[u]++;
  edge[e].x = x;
  edge[e].y = y;
  edge[e].next = ft[u];
  ft[u] = e++;
}
int main() {
  while (scanf("%d%d%d", &r, &c, &p) == 3) {
    init();
    int tx, ty;
    for (int i = 0; i < r; i++) {
      for (int j = 0; j < c; j++) {
        scanf("%d", maze[i] + j);
        if (maze[i][j] == 1)
          dp[i][j] = i + j;
        else
          dp[i][j] = inf;
        insert_edge(maze[i][j], i, j);
        if (maze[i][j] == p) {
          tx = i;
          ty = j;
        }
      }
    }
    for (int i = 2; i <= p; i++) {
      if ((long long)cnt[i] * (long long)cnt[i - 1] > N) {
        head = tail = 0;
        for (int j = 0; j < r; j++) {
          for (int k = 0; k < c; k++) {
            if (dp[j][k] < inf && maze[j][k] == i - 1) {
              d[j][k] = dp[j][k];
              flag[j][k] = true;
              deq[tail++] = Node(j, k);
            } else {
              flag[j][k] = false;
              d[j][k] = inf;
            }
          }
        }
        sort(deq, deq + tail);
        while (head != tail) {
          Node node = deq[head++];
          if (head > N + 1) head = 0;
          for (int j = 0; j < 4; j++) {
            int xx = node.x + dx[j];
            int yy = node.y + dy[j];
            if (!in(xx, yy)) continue;
            if (d[xx][yy] > d[node.x][node.y] + 1) {
              d[xx][yy] = d[node.x][node.y] + 1;
              if (!flag[xx][yy]) {
                flag[xx][yy] = true;
                deq[tail++] = Node(xx, yy);
                if (tail > N + 1) tail = 0;
              }
            }
          }
          flag[node.x][node.y] = false;
        }
        for (int j = ft[i]; j != -1; j = edge[j].next) {
          dp[edge[j].x][edge[j].y] = d[edge[j].x][edge[j].y];
        }
      } else {
        for (int j = ft[i]; j != -1; j = edge[j].next) {
          int x = edge[j].x;
          int y = edge[j].y;
          dp[x][y] = inf;
          for (int k = ft[i - 1]; k != -1; k = edge[k].next) {
            int xx = edge[k].x;
            int yy = edge[k].y;
            dp[x][y] = min(dp[x][y], dp[xx][yy] + abs(x - xx) + abs(y - yy));
          }
        }
      }
    }
    cout << dp[tx][ty] << endl;
  }
  return 0;
}
