#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ii = pair<int, int>;
void in(int &x);
const int N = 305;
const int INF = 1e9 + 50;
const int MOD = 1e9 + 7;
int n, m, p;
int grid[N][N], dp[N][N], dst[N][N];
vector<ii> pos[N * N];
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};
struct State {
  int row, col, dist;
};
bool cmp(State a, State b) { return a.dist < b.dist; }
int dist(int r1, int c1, int r2, int c2) { return abs(r1 - r2) + abs(c1 - c2); }
bool inside(int r, int c) { return r >= 1 && r <= n && c >= 1 && c <= m; }
void Process(int curTresure) {
  vector<State> elm;
  for (ii point : pos[curTresure - 1]) {
    elm.push_back({point.first, point.second, dp[point.first][point.second]});
  }
  sort(elm.begin(), elm.end(), cmp);
  queue<State> bfs;
  int idx = 1;
  memset(dst, -1, sizeof dst);
  bfs.push(elm[0]);
  dst[elm[0].row][elm[0].col] = elm[0].dist;
  while (bfs.size()) {
    State cur = bfs.front();
    bfs.pop();
    int r = cur.row, c = cur.col, cd = cur.dist;
    while (idx < elm.size() && elm[idx].dist == cd) {
      bfs.push(elm[idx++]);
    }
    for (int i = 0; i < 4; i++) {
      int nr = r + dr[i], nc = c + dc[i];
      if (!inside(nr, nc)) continue;
      if (dst[nr][nc] != -1) continue;
      dst[nr][nc] = cd + 1;
      bfs.push({nr, nc, cd + 1});
    }
  }
  for (ii now : pos[curTresure]) {
    dp[now.first][now.second] = dst[now.first][now.second];
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &p);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &grid[i][j]);
      pos[grid[i][j]].push_back({i, j});
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      dp[i][j] = INF;
      if (grid[i][j] == 1) {
        dp[i][j] = dist(i, j, 1, 1);
      }
    }
  }
  for (int i = 2; i <= p; i++) {
    if (pos[i].size() * pos[i - 1].size() <= n * m) {
      for (ii point : pos[i]) {
        int r = point.first, c = point.second;
        for (ii prevPoint : pos[i - 1]) {
          int pr = prevPoint.first, pc = prevPoint.second;
          dp[r][c] = min(dp[pr][pc] + dist(pr, pc, r, c), dp[r][c]);
        }
      }
    } else {
      Process(i);
    }
  }
  int ans = INF;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (grid[i][j] < p) continue;
      ans = min(ans, dp[i][j]);
    }
  }
  printf(ans >= INF ? "-1\n" : "%d\n", ans);
  return 0;
}
void in(int &x) {
  bool neg = false;
  register int c;
  x = 0;
  c = getchar();
  if (c == '-') {
    neg = true;
    c = getchar();
  }
  for (; c > 47 && c < 58; c = getchar()) x = (x << 1) + (x << 3) + c - 48;
  if (neg) x *= -1;
}
