#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> par, num;
  vector<bool> done;
  vector<int> cost;
  UnionFind(int n) : par(n), num(n, 1), done(n, false), cost(n, 1e5) {
    iota(par.begin(), par.end(), 0);
  }
  int find(int v) { return (par[v] == v) ? v : (par[v] = find(par[v])); }
  void unite(int u, int v) {
    u = find(u), v = find(v);
    if (u == v) return;
    if (num[u] < num[v]) swap(u, v);
    num[u] += num[v];
    par[v] = u;
    done[u] = done[u] | done[v];
    cost[u] = min(cost[u], cost[v]);
  }
  bool same(int u, int v) { return find(u) == find(v); }
  bool ispar(int v) { return v = find(v); }
  int size(int v) { return num[find(v)]; }
};
bool used[500 * 500];
int c[500 * 500];
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<int> p(n * n);
  UnionFind uf(n * n);
  for (int i = 0; i < n * n; i++) {
    cin >> p[i];
    p[i]--;
  }
  long long int res = 0;
  for (int i = 0; i < n * n; i++) {
    uf.cost[i] = min({i % n, n - 1 - i % n, n - 1 - i / n, i / n});
    c[i] = uf.cost[i];
    uf.cost[i]--;
  }
  for (int i = 0; i < n * n; i++) {
    int j = p[i];
    int mi = 1000;
    if (j % n) {
      if (used[j - 1]) {
        mi = min(mi, uf.cost[uf.find(j - 1)]);
      } else {
        mi = min(mi, c[j - 1]);
      }
    }
    if (j % n != n - 1) {
      if (used[j + 1]) {
        mi = min(mi, uf.cost[uf.find(j + 1)]);
      } else {
        mi = min(mi, c[j + 1]);
      }
    }
    if (j / n) {
      if (used[j - n]) {
        mi = min(mi, uf.cost[uf.find(j - n)]);
      } else {
        mi = min(mi, c[j - n]);
      }
    }
    if (j / n != n - 1) {
      if (used[j + n]) {
        mi = min(mi, uf.cost[uf.find(j + n)]);
      } else {
        mi = min(mi, c[j + n]);
      }
    }
    res += min(c[p[i]], mi + 1);
    used[p[i]] = 1;
    mi = 1000;
    if (j % n) {
      if (used[j - 1]) {
        uf.unite(j, j - 1);
      } else {
        mi = min(mi, c[j - 1]);
      }
    }
    if (j % n != n - 1) {
      if (used[j + 1]) {
        uf.unite(j, j + 1);
      } else {
        mi = min(mi, c[j + 1]);
      }
    }
    if (j / n) {
      if (used[j - n]) {
        uf.unite(j, j - n);
      } else {
        mi = min(mi, c[j - n]);
      }
    }
    if (j / n != n - 1) {
      if (used[j + n]) {
        uf.unite(j, j + n);
      } else {
        mi = min(mi, c[j + n]);
      }
    }
    mi = min(mi, uf.cost[uf.find(j)]);
    queue<int> q;
    if (j % n) {
      if (!used[j - 1]) {
        if (c[j - 1] > mi + 1) {
          c[j - 1] = mi + 1;
          q.push(j - 1);
        }
      }
    }
    if (j % n != n - 1) {
      if (!used[j + 1]) {
        if (c[j + 1] > mi + 1) {
          c[j + 1] = mi + 1;
          q.push(j + 1);
        }
      }
    }
    if (j / n) {
      if (!used[j - n]) {
        if (c[j - n] > mi + 1) {
          c[j - n] = mi + 1;
          q.push(j - n);
        }
      }
    }
    if (j / n != n - 1) {
      if (!used[j + n]) {
        if (c[j + n] > mi + 1) {
          c[j + n] = mi + 1;
          q.push(j + n);
        }
      }
    }
    while (q.size()) {
      int jj = q.front();
      q.pop();
      mi = c[jj];
      if (jj % n) {
        if (!used[jj - 1]) {
          if (c[jj - 1] > mi + 1) {
            c[jj - 1] = mi + 1;
            q.push(jj - 1);
          }
        }
      }
      if (jj % n != n - 1) {
        if (!used[jj + 1]) {
          if (c[jj + 1] > mi + 1) {
            c[jj + 1] = mi + 1;
            q.push(jj + 1);
          }
        }
      }
      if (jj / n) {
        if (!used[jj - n]) {
          if (c[jj - n] > mi + 1) {
            c[jj - n] = mi + 1;
            q.push(jj - n);
          }
        }
      }
      if (jj / n != n - 1) {
        if (!used[jj + n]) {
          if (c[jj + n] > mi + 1) {
            c[jj + n] = mi + 1;
            q.push(jj + n);
          }
        }
      }
    }
  }
  cout << res << endl;
}
