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
#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;
}
