#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
const long long INF = 100100100100;
const long long MOD = 1000000007;
long long mod_pow(long long N, long long M) {
  if (M == 0) return 1;
  long long res = mod_pow((N * N) % MOD, M / 2);
  if (M & 1) res = (res * N) % MOD;
  return res %= MOD;
}
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a * b / gcd(a, b); }
int parent[250005];
int tall[250005];
int searchRoot(int V) {
  if (parent[V] == V) {
    return V;
  } else {
    return parent[V] = searchRoot(parent[V]);
  }
}
bool same(int X, int Y) {
  if (searchRoot(X) == searchRoot(Y))
    return true;
  else
    return false;
}
void unite(int X, int Y) {
  int Xroot = searchRoot(X);
  int Yroot = searchRoot(Y);
  if (Xroot == Yroot) return;
  if (tall[X] > tall[Y]) {
    parent[Yroot] = Xroot;
  } else if (tall[Xroot] == tall[Y]) {
    parent[Yroot] = Xroot;
    tall[Y]++;
  } else
    parent[Xroot] = Yroot;
}
int main() {
  int N;
  cin >> N;
  vector<int> retu(N * N);
  vector<vector<int>> ban(N, vector<int>(N));
  int count = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      count++;
      ban.at(i).at(j) = count;
    }
  }
  for (int i = 0; i < N * N; i++) cin >> retu.at(i);
  vector<bool> edge(N * N + 1, false);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (i == 0 || i == N - 1)
        edge.at(i * N + j + 1) = true;
      else if (j == 0 || j == N - 1)
        edge.at(i * N + j + 1) = true;
    }
  }
  for (int i = 1; i <= N * N; i++) {
    parent[i] = i;
    tall[i] = 1;
  }
  int ans = 0;
  vector<bool> already(N * N + 1, false);
  for (int i = 0; i < N * N; i++) {
    int V = retu.at(i);
    int RR = searchRoot(V);
    int plus = 1;
    if (!edge.at(RR)) {
      plus = 1;
      plus = min(N - (RR % N), RR % N - 1);
      plus = max(plus, 0);
      plus = min({N - (RR - 1) / N, (RR - 1) / N, plus});
      plus = max(plus, 0);
    } else {
      plus = 0;
    }
    int U = V - N, D = V + N, L = V - 1, Right = V + 1;
    int r;
    int Plus = 0;
    if (V % N != 1 && already.at(L)) {
      r = searchRoot(L);
      Plus = min(N - (r % N), r % N - 1);
      Plus = max(Plus, 0);
      Plus = min({N - (r - 1) / N, (r - 1) / N, Plus});
      Plus = max(Plus, 0);
      if (Plus > plus) continue;
      plus = Plus;
      unite(V, L);
    }
    if (V > N && already.at(U)) {
      r = searchRoot(U);
      Plus = min(N - (r % N), r % N - 1);
      Plus = max(Plus, 0);
      Plus = min({N - (r - 1) / N, (r - 1) / N, Plus});
      Plus = max(Plus, 0);
      if (Plus > plus) continue;
      plus = Plus;
      unite(V, U);
    }
    if (V % N != 0 && already.at(Right)) {
      r = searchRoot(Right);
      Plus = min(N - (r % N), r % N - 1);
      Plus = max(Plus, 0);
      Plus = min({N - (r - 1) / N, (r - 1) / N, Plus});
      Plus = max(Plus, 0);
      if (Plus > plus) continue;
      plus = Plus;
      unite(V, Right);
    }
    if (V <= N * N - N && already.at(D)) {
      r = searchRoot(D);
      Plus = min(N - (r % N), r % N - 1);
      Plus = max(Plus, 0);
      Plus = min({N - (r - 1) / N, (r - 1) / N, Plus});
      Plus = max(Plus, 0);
      if (Plus > plus) continue;
      plus = Plus;
      unite(V, D);
    }
    ans += Plus;
    already.at(V) = true;
  }
  cout << ans << endl;
}
