#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T SQR(T x) {
  return x * x;
}
template <typename T>
inline T MIN(T x, T y) {
  return (x < y) ? x : y;
}
template <typename T>
inline T MAX(T x, T y) {
  return (x > y) ? x : y;
}
template <typename T>
inline T ABS(T x) {
  return (x > 0) ? x : -x;
}
template <typename T>
inline void UPDATE_MIN(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <typename T>
inline void UPDATE_MAX(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
template <typename T>
inline int ARGMAX(T cont) {
  return max_element(cont.begin(), cont.end()) - cont.begin();
}
template <typename T>
inline int ARGMIN(T cont) {
  return min_element(cont.begin(), cont.end()) - cont.begin();
}
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c)) v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args>
inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (__typeof(n - 1) i = (0), __tmpvar__end87 = (n - 1); i < __tmpvar__end87;
       i++)
    s << arr[i] << ",";
  s << arr[n - 1] << "]";
  return s.str();
}
template <class T>
inline string TOSTR(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline void PR(void) {}
inline void PR(int x) { printf("%d", x); }
inline void PR(long long x) { printf("%lld", x); }
inline void PR(char *s) { printf("%s", s); }
inline void PR(const char *s) { printf("%s", s); }
inline void PR(double f) { printf("%.10lf", f); }
inline void PR(long double f) { printf("%.10llf", f); }
inline void PR(vector<int> &vec) {
  for (auto x : vec) {
    PR(x);
    putc(0x20, stdout);
  }
}
template <typename T>
inline void PRS(T x) {
  PR(x);
  putc(0x20, stdout);
}
template <typename T>
inline void PRN(T x) {
  PR(x);
  putc(0x0a, stdout);
}
void PRN(void) { putc(0x0a, stdout); }
inline int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
inline long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
inline long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
struct pairhash {
  template <typename T, typename U>
  std::size_t operator()(const std::pair<T, U> &x) const {
    return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
  }
};
template <typename K, typename V>
V GetWithDef(const std::map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  if (it == m.end()) m[key] = defval;
}
template <typename K, typename V>
V GetWithDef(const std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::unordered_map<K, V> &m, const K &key, const V &defval) {
  auto it = m.find(key);
  if (it == m.end()) m[key] = defval;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
inline void addto(int &a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
}
inline int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void subto(int &a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
}
inline int sub(int a, int b) {
  a -= b;
  if (a < 0) a += MOD;
  if (a >= MOD) a -= MOD;
  return a;
}
inline void multo(int &a, int b) { a = (long long)a * b % MOD; }
inline int mul(int a, int b) { return (long long)a * b % MOD; }
inline int mulmod(int a, int b, int mod) { return (long long)a * b % mod; }
inline int powmod(int a, int e, int mod) {
  int x;
  for (x = 1; e > 0; e >>= 1) {
    if (e & 1) x = mulmod(x, a, mod);
    a = mulmod(a, a, mod);
  }
  return x;
}
inline int invmod_prime(int a, int mod) { return powmod(a, mod - 2, mod); }
inline long long invmod_LL(long long p) {
  long long q = p;
  for (long long a = p * p; a != 1; a *= a) q *= a;
  return q;
}
const int ZERO = 1e9;
struct Node;
Node *allocNode(int l, int r);
struct Node {
  int my_l, my_r;
  Node *pleft = NULL;
  Node *pright = NULL;
  int my_val;
  int my_lazy;
  Node() {}
  inline bool inside(int l, int r) { return (l <= my_l) && (my_r <= r); }
  inline bool outside(int l, int r) { return (r < my_l) || (l > my_r); }
  inline bool single() { return (my_l == my_r); }
  inline int length() { return (my_r - my_l + 1); }
  inline void check_fork() {
    if (pleft) return;
    assert(!single());
    pleft = allocNode(my_l, (my_l + my_r) / 2);
    pright = allocNode((my_l + my_r) / 2 + 1, my_r);
  }
  inline Node *left() {
    check_fork();
    return pleft;
  }
  inline Node *right() {
    check_fork();
    return pright;
  }
  void clear() {
    if (pleft) {
      pleft->clear();
      delete pleft;
    }
    if (pright) {
      pright->clear();
      delete pright;
    }
  }
  inline static int combine(int a, int b) { return min(a, b); }
  int sum_range(int l, int r) {
    push();
    if (outside(l, r)) return ZERO;
    if (inside(l, r)) return my_val;
    return combine(left()->sum_range(l, r), right()->sum_range(l, r));
  }
  int get_single(int l) { return sum_range(l, l); }
  void set_single(int x, int new_val) {
    push();
    if (outside(x, x)) return;
    if ((my_l == my_r) && (my_l == x)) {
      my_val = new_val;
      return;
    }
    left()->set_single(x, new_val);
    right()->set_single(x, new_val);
    my_val = combine(left()->my_val, right()->my_val);
  }
  void modify_single(int x, int new_val) {
    push();
    if (outside(x, x)) return;
    if ((my_l == my_r) && (my_l == x)) {
      my_val = combine(my_val, new_val);
      return;
    }
    left()->modify_single(x, new_val);
    right()->modify_single(x, new_val);
    my_val = combine(left()->my_val, right()->my_val);
  }
  void modify_range(int l, int r, int new_val) {
    push();
    if (outside(l, r)) return;
    if (inside(l, r)) {
      my_lazy = combine(my_lazy, new_val);
      return;
    }
    left()->modify_range(l, r, new_val);
    right()->modify_range(l, r, new_val);
    my_val = combine(left()->my_val, right()->my_val);
  }
  void push() {
    return;
    if (!single()) {
      left()->my_lazy = combine(left()->my_lazy, my_lazy);
      right()->my_lazy = combine(right()->my_lazy, my_lazy);
    }
    my_val = combine(my_val, my_lazy);
    my_lazy = ZERO;
  }
};
struct WideNode;
WideNode *allocWideNode(int l, int r, int l2, int r2);
struct WideNode {
  int my_l, my_r;
  WideNode *pleft = NULL;
  WideNode *pright = NULL;
  Node *my_val = NULL;
  WideNode() {}
  inline bool inside(int l, int r) { return (l <= my_l) && (my_r <= r); }
  inline bool outside(int l, int r) { return (r < my_l) || (l > my_r); }
  inline bool single() { return (my_l == my_r); }
  inline int length() { return (my_r - my_l + 1); }
  inline void check_fork() {
    if (pleft) return;
    assert(!single());
    pleft = allocWideNode(my_l, (my_l + my_r) / 2, my_val->my_l, my_val->my_r);
    pright =
        allocWideNode((my_l + my_r) / 2 + 1, my_r, my_val->my_l, my_val->my_r);
  }
  inline WideNode *left() {
    check_fork();
    return pleft;
  }
  inline WideNode *right() {
    check_fork();
    return pright;
  }
  void clear() {
    if (pleft) {
      pleft->clear();
      delete pleft;
    }
    if (pright) {
      pright->clear();
      delete pright;
    }
    my_val->clear();
  }
  int sum_range(int l, int r, int l2, int r2) {
    if (outside(l, r)) return ZERO;
    if (inside(l, r)) return my_val->sum_range(l2, r2);
    return Node::combine(left()->sum_range(l, r, l2, r2),
                         right()->sum_range(l, r, l2, r2));
  }
  int get_single(int l, int l2) { return sum_range(l, l, l2, l2); }
  void set_single(int x, int y, int new_val) {
    if (outside(x, x)) return;
    if ((my_l == my_r) && (my_l == x)) {
      my_val->set_single(y, new_val);
      return;
    }
    left()->set_single(x, y, new_val);
    right()->set_single(x, y, new_val);
    my_val->modify_single(y, new_val);
  }
  void modify_single(int x, int y, int new_val) {
    if (outside(x, x)) return;
    if ((my_l == my_r) && (my_l == x)) {
      my_val->set_single(y, Node::combine(my_val->get_single(y), new_val));
      return;
    }
    left()->modify_single(x, y, new_val);
    right()->modify_single(x, y, new_val);
    merge_at(y);
  }
  void merge_at(int y) {
    my_val->set_single(y, Node::combine(left()->my_val->get_single(y),
                                        right()->my_val->get_single(y)));
  }
};
Node memNode[5123123];
int ptrNode = 0;
Node *allocNode(int l, int r) {
  Node &node = memNode[ptrNode++];
  assert(ptrNode < 5123123);
  node.my_l = l;
  node.my_r = r;
  node.my_val = ZERO;
  node.my_lazy = ZERO;
  node.pleft = NULL;
  node.pright = NULL;
  return &node;
}
WideNode memWideNode[123123];
int ptrWideNode = 0;
WideNode *allocWideNode(int l, int r, int l2, int r2) {
  WideNode &node = memWideNode[ptrWideNode++];
  assert(ptrWideNode < 123123);
  node.my_l = l;
  node.my_r = r;
  node.my_val = allocNode(l2, r2);
  node.pleft = NULL;
  node.pright = NULL;
  return &node;
}
int N, M, K, L, E, Q, P, SY, SX;
int arr[301] = {};
int mp[301][301] = {};
int mp_rot[4][301][301] = {};
vector<pair<int, int>> by_val[301 * 301];
int min_dist[500][500] = {};
int cx;
int cy;
bool funcless(pair<int, int> yx1, pair<int, int> yx2) {
  int y1 = yx1.first;
  int x1 = yx1.second;
  int y2 = yx2.first;
  int x2 = yx2.second;
  return abs(cx - x1) + abs(cy - y1) < abs(cx - x2) + abs(cy - y2);
}
inline void rotate90cw(int &y, int &x, int sy, int sx) {
  int x2 = sy - 1 - y;
  y = x;
  x = x2;
}
template <typename T>
void rotate90cw(T src[301][301], T dst[301][301], int sy, int sx) {
  for (__typeof(sx) x = (0), __tmpvar__end475 = (sx); x < __tmpvar__end475;
       x++) {
    for (__typeof(sy) y = (0), __tmpvar__end476 = (sy); y < __tmpvar__end476;
         y++) {
      int y2 = x;
      int x2 = sy - 1 - y;
      dst[y2][x2] = src[y][x];
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  scanf("%d%d%d", &SY, &SX, &P);
  for (__typeof(SY) y = (0), __tmpvar__end491 = (SY); y < __tmpvar__end491;
       y++) {
    for (__typeof(SX) x = (0), __tmpvar__end492 = (SX); x < __tmpvar__end492;
         x++) {
      scanf("%d", &mp[y][x]);
      by_val[mp[y][x]].push_back(make_pair(y, x));
      min_dist[y][x] = 1e9;
    }
  }
  rotate90cw(mp, mp_rot[0], SY, SX);
  rotate90cw(mp_rot[0], mp_rot[1], SX, SY);
  rotate90cw(mp_rot[1], mp_rot[2], SY, SX);
  rotate90cw(mp_rot[2], mp_rot[3], SX, SY);
  rotate90cw(mp_rot[3], mp_rot[0], SY, SX);
  int ans = 1e9;
  for (auto &yx : by_val[1]) {
    int y = yx.first;
    int x = yx.second;
    min_dist[y][x] = y + x;
    if (P == 1) UPDATE_MIN(ans, x + y);
  }
  for (__typeof(P) val = (1), __tmpvar__end510 = (P); val < __tmpvar__end510;
       val++) {
    1;
    WideNode *nodes[4] = {
        allocWideNode(0, 301, 0, 301), allocWideNode(0, 301, 0, 301),
        allocWideNode(0, 301, 0, 301), allocWideNode(0, 301, 0, 301)};
    for (auto &yx : by_val[val]) {
      int y = yx.first;
      int x = yx.second;
      int dist = min_dist[y][x];
      int sy = SY;
      int sx = SX;
      for (__typeof(4) r = (0), __tmpvar__end521 = (4); r < __tmpvar__end521;
           r++) {
        nodes[r]->set_single(x, y, dist + x + y);
        rotate90cw(y, x, sy, sx);
        swap(sy, sx);
      }
    }
    for (auto &yx2 : by_val[val + 1]) {
      int y2 = yx2.first;
      int x2 = yx2.second;
      int sy = SY;
      int sx = SX;
      int xorig = x2;
      int yorig = y2;
      for (__typeof(4) r = (0), __tmpvar__end536 = (4); r < __tmpvar__end536;
           r++) {
        int dist2 = nodes[r]->sum_range(x2, sx, y2, sy) - x2 - y2;
        UPDATE_MIN(min_dist[yorig][xorig], dist2);
        if (val + 1 == P) UPDATE_MIN(ans, dist2);
        rotate90cw(y2, x2, sy, sx);
        swap(sy, sx);
      }
    }
    ptrNode = 0;
    ptrWideNode = 0;
    1;
  }
  PRN(ans);
  return 0;
  priority_queue<pair<int, pair<int, int>>> pq;
  for (auto &yx : by_val[1]) {
    int y = yx.first;
    int x = yx.second;
    int dist = y + x;
    pq.push(make_pair(-dist, yx));
    min_dist[y][x] = dist;
    1;
  }
  while (!pq.empty()) {
    auto s = pq.top();
    pq.pop();
    int dist = -s.first;
    if (dist >= ans) break;
    int y = s.second.first;
    int x = s.second.second;
    if (dist != min_dist[y][x]) continue;
    int val = mp[y][x];
    for (auto &yx2 : by_val[val + 1]) {
      int y2 = yx2.first;
      int x2 = yx2.second;
      int dist2 = dist + abs(y2 - y) + abs(x2 - x);
      int val2 = mp[y2][x2];
      1;
      if (val2 == P)
        UPDATE_MIN(ans, dist2);
      else if (dist2 < ans && dist2 < min_dist[y2][x2]) {
        min_dist[y2][x2] = dist2;
        pq.push(make_pair(-dist2, yx2));
      }
    }
  }
  PRN(ans);
  return 0;
}
