#include <bits/stdc++.h>
using namespace std;
using lli = long long int;
void YESNO(bool), YesNo(bool);
template <class T1, class T2>
bool chmin(T1 &l, const T2 &r);
template <class T1, class T2>
bool chmax(T1 &l, const T2 &r);
template <class T1, class T2>
void vadd(vector<T1> &v, T2 x);
struct ufind {
  struct node {
    long long int par, rank, size;
    void init(long long int i) {
      par = i;
      rank = 0;
      size = 1;
    }
  };
  vector<node> nodes;
  ufind(long long int n) {
    nodes.resize(n);
    for (lli i = 0; i < (n); i++) nodes[i].init(i);
  }
  long long int find(long long int x) {
    return nodes[x].par == x ? x : (nodes[x].par = find(nodes[x].par));
  }
  void unite(long long int x, long long int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (nodes[x].rank < nodes[y].rank) {
      nodes[x].par = y;
      nodes[y].size += nodes[x].size;
    } else {
      nodes[y].par = x;
      if (nodes[x].rank == nodes[y].rank) nodes[x].rank++;
      nodes[x].size += nodes[y].size;
    }
  }
  bool same(long long int x, long long int y) { return find(x) == find(y); }
  long long int size(long long int x) { return nodes[find(x)].size; }
};
long long int f[505 * 505] = {};
long long int N;
void dump_grid() { return; }
signed main() {
  cin >> N;
  auto get = [=](long long int x, long long int y) {
    if (x < 0 || x >= N || y >= N || y < 0) return N * N;
    return x * N + y;
  };
  ufind uf(N * N + 1);
  vector<long long int> P(N * N + 1);
  vector<long long int> used(N * N + 1);
  for (lli i = 0; i < (N); i++)
    for (lli j = 0; j < (N); j++) {
      f[get(i, j)] = min({i, j, N - i - 1, N - j - 1});
    }
  long long int ret = 0;
  used[N * N] = true;
  long long int dx[4] = {-1, 0, 1, 0};
  long long int dy[4] = {0, 1, 0, -1};
  map<long long int, long long int> hoge;
  for (lli i = 0; i < (N * N); i++) {
    cin >> P[i];
    P[i]--;
  }
  for (lli i = 0; i < (N * N); i++) {
    long long int X = P[i] / N;
    long long int Y = P[i] % N;
    long long int score = f[uf.find(get(X, Y))];
    for (lli j = 0; j < (4); j++) {
      long long int nx1 = dx[j] + X;
      long long int ny1 = dy[j] + Y;
      long long int id1 = uf.find(get(nx1, ny1));
      long long int score1 = f[id1];
      if (used[get(nx1, ny1)]) {
        chmin(score, score1);
      } else {
        chmin(score, score1 + 1);
      }
    }
    ret += score;
    for (lli j = 0; j < (4); j++) {
      long long int nx1 = dx[j] + X;
      long long int ny1 = dy[j] + Y;
      long long int id1 = uf.find(get(nx1, ny1));
      long long int score1 = f[id1];
      bool used1 = used[get(nx1, ny1)];
      for (lli k = 0; k < (4); k++) {
        long long int nx2 = dx[k] + X;
        long long int ny2 = dy[k] + Y;
        long long int id2 = uf.find(get(nx2, ny2));
        long long int score2 = f[id2];
        bool used2 = used[get(nx2, ny2)];
        if (used1 && used2) {
          f[id1] = min(score1, score2);
          f[id2] = min(score1, score2);
          uf.unite(id1, id2);
          continue;
        }
        if (used2) {
          f[id2] = min(score1 + 1, score2);
          f[id1] = min(score1, score2);
        }
        if (used1) {
          f[id1] = min(score1, score2 + 1);
          f[id2] = min(score1, score2);
        }
      }
    }
    used[P[i]] = true;
    dump_grid();
  }
  cout << ret << endl;
}
void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
template <class T1, class T2>
bool chmin(T1 &l, const T2 &r) {
  return (l > r) ? (l = r, true) : false;
}
template <class T1, class T2>
bool chmax(T1 &l, const T2 &r) {
  return (l < r) ? (l = r, true) : false;
}
template <class T1, class T2>
void vadd(vector<T1> &v, T2 x) {
  for (auto &s : v) s += T2(x);
}
