#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> nxt;
  vector<int> numm;
  void init(int x) {
    nxt.clear();
    numm.assign(x, 1);
    nxt.resize(x);
    for (int i = 0; i < x; i++) {
      nxt[i] = i;
    }
  }
  int find(int x) {
    if (nxt[x] == x) return x;
    return nxt[x] = find(nxt[x]);
  }
  int size(int x) { return numm[x]; }
  inline void unite(int x, int y) {
    if (x == y) return;
    numm[find(x)] += numm[find(y)];
    nxt[find(y)] = find(x);
  }
};
long long N, P[1000 * 1000];
UnionFind uf;
long long mk[1000 * 1000];
long long mk2[1000 * 1000];
long long g[8];
long long i, j, k;
int main() {
  scanf("%lld", &N);
  for (i = 0; i < N * N; ++i) {
    scanf("%lld", &P[i]);
    P[i]--;
  }
  for (i = 0; i < N; ++i) {
    for (j = 0; j < N; ++j) {
      mk[i * N + j] = min(min(i, N - i - 1), min(j, N - j - 1));
    }
  }
  g[0] = 1;
  g[1] = N;
  g[2] = -1;
  g[3] = -N;
  uf.init(N * N + 5);
  long long ans = 0;
  for (i = 0; i < N * N; ++i) {
    for (j = 0; j < 4; ++j) {
      long long nx = P[i] + g[j];
      if (nx < 0 || N * N <= nx || (P[i] % N != nx % N && P[i] / N != nx / N))
        continue;
      if (!mk2[nx]) continue;
      mk[P[i]] = min(mk[P[i]], mk[uf.find(nx)]);
      uf.unite(P[i], nx);
    }
    ans += mk[uf.find(P[i])];
    mk2[P[i]] = 1;
  }
  printf("%lld\n", ans);
  return 0;
}
