#include <bits/stdc++.h>
using namespace std;
const int N = 330;
const int M = 4 * N;
const int Inf = 1e8;
int n, m, p;
int a[N][N];
int Dp[N][N];
vector<pair<int, int> > Idx[N * N];
int Dist(pair<int, int> x, pair<int, int> y) {
  return abs(x.first - y.first) + abs(x.second - y.second);
}
struct SegTree {
  int Tree[M];
  void Merge(int Node) {
    Tree[Node] = min(Tree[(Node << 1)], Tree[(Node << 1 | 1)]);
  }
  void Build(int Node = 1, int L = 1, int R = m) {
    if (L == R) return void(Tree[Node] = Inf);
    Build((Node << 1), L, ((L + R) >> 1));
    Build((Node << 1 | 1), ((L + R) >> 1) + 1, R);
    Merge(Node);
  }
  void Update(int i, int x, int Node = 1, int L = 1, int R = m) {
    if (L == R) return void(Tree[Node] = min(Tree[Node], x));
    if (i <= ((L + R) >> 1))
      Update(i, x, (Node << 1), L, ((L + R) >> 1));
    else
      Update(i, x, (Node << 1 | 1), ((L + R) >> 1) + 1, R);
    Merge(Node);
  }
  int Query(int i, int j, int Node = 1, int L = 1, int R = m) {
    if (j < L || R < i) return Inf;
    if (i <= L && R <= j) return Tree[Node];
    return min(Query(i, j, (Node << 1), L, ((L + R) >> 1)),
               Query(i, j, (Node << 1 | 1), ((L + R) >> 1) + 1, R));
  }
};
SegTree myTree1;
SegTree myTree2;
int main() {
  cin >> n >> m >> p;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      scanf("%d", &a[i][j]), Idx[a[i][j]].emplace_back(i, j);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) Dp[i][j] = Inf;
  for (pair<int, int> x : Idx[p]) Dp[x.first][x.second] = 0;
  for (int x = p - 1; x > 0; x--) {
    vector<pair<int, int> > A(Idx[x].size() + Idx[x + 1].size());
    merge(Idx[x].begin(), Idx[x].end(), Idx[x + 1].begin(), Idx[x + 1].end(),
          A.begin());
    myTree1.Build();
    myTree2.Build();
    for (pair<int, int> y : A) {
      int i = y.first;
      int j = y.second;
      if (a[i][j] == x) {
        Dp[i][j] = min(Dp[i][j], i + j + myTree1.Query(1, j));
        Dp[i][j] = min(Dp[i][j], i - j + myTree2.Query(j, m));
      } else {
        myTree1.Update(j, -i - j + Dp[i][j]);
        myTree2.Update(j, -i + j + Dp[i][j]);
      }
    }
    myTree1.Build();
    myTree2.Build();
    reverse(A.begin(), A.end());
    for (pair<int, int> y : A) {
      int i = y.first;
      int j = y.second;
      if (a[i][j] == x) {
        Dp[i][j] = min(Dp[i][j], -i + j + myTree1.Query(1, j));
        Dp[i][j] = min(Dp[i][j], -i - j + myTree2.Query(j, m));
      } else {
        myTree1.Update(j, i - j + Dp[i][j]);
        myTree2.Update(j, i + j + Dp[i][j]);
      }
    }
  }
  int Ans = Inf;
  for (pair<int, int> x : Idx[1])
    Ans = min(Ans, Dist(pair<int, int>(1, 1), x) + Dp[x.first][x.second]);
  cout << Ans << endl;
}
