//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define trav(x,a) for (const auto& x: a)
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), x.end()
#define mem(a,v) memset((a), (v), sizeof (a))
#define enl printf("\n")
#define case(t) printf("Case #%d: ", (t))
#define ni(n) scanf("%d", &(n))
#define nl(n) scanf("%lld", &(n))
#define nai(a, n) for (int _i = 0; _i < (n); _i++) ni(a[_i])
#define nal(a, n) for (int _i = 0; _i < (n); _i++) nl(a[_i])
#define pri(n) printf("%d\n", (n))
#define prl(n) printf("%lld\n", (n))
#define pii pair<int, int>
#define pll pair<long long, long long>
#define vii vector<pii>
#define vll vector<pll>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define mp make_pair
#define st first
#define nd second
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef cc_hash_table<int,int,hash<int>> ht;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> oset;
const double pi = acos(-1);
const int mod = 1e9 + 7;
const int inf = 1e9 + 7;
const int N = 1e6 + 5;
const double eps = 1e-9;
int p[N], par[N];
int ans[505][505], vis[505][505], pd[505][505];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, gd[N];
vi adj[N];

int qry(int x) { return x == par[x] ? x : par[x] = qry(par[x]); }
void join(int x, int y) { 
  if ((x = qry(x)) == (y = qry(y)))
    return;
  gd[y] |= gd[x];
  par[x] = y; 
}
pii getP(int v) { return mp((v - 1) / n + 1, (v - 1) % n + 1); }

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n * n; i++) {
    scanf("%d", &p[i]);
    // p[i] = i;
    par[i] = i;
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      pd[i][j] = -1;
      if (min(i, j) == 1 || max(i, j) == n)
        gd[(i - 1) * n + j] = 1;
    }
  int ret = 0;
  for (int i = 1; i <= n * n; i++) {
    int x, y; tie(x, y) = getP(p[i]);
    vis[x][y] = 1;
    deque<pii> pq; pq.pb(mp(x,y));
    vector<pii> ar = {mp(x, y)};
    pd[x][y] = 0;
    int val = N;
    while (sz(pq)) {
      auto cur = pq.front(); pq.pop_front();
      if (min(cur.st, cur.nd) == 1 || max(cur.st, cur.nd) == n) {
        val = min(val, pd[cur.st][cur.nd]);
        break;
      }
      for (int k = 0; k < 4; k++) {
        int nx = cur.st + dx[k], ny = cur.nd + dy[k];
        if (pd[nx][ny] != -1 || nx < 1 || nx > n || ny < 1 || ny > n || val != N)
          continue;
        if (vis[nx][ny] && gd[qry((nx - 1) * n + ny)]) {
          val = pd[cur.st][cur.nd];
          continue;
        }
        ar.pb(mp(nx, ny));
        if (vis[nx][ny])
          pd[nx][ny] = pd[cur.st][cur.nd], pq.push_front(mp(nx, ny));
        else
          pd[nx][ny] = pd[cur.st][cur.nd] + 1, pq.push_back(mp(nx, ny));
      }
    }
    ret += val;
    trav(x, ar) pd[x.st][x.nd] = -1;
    for (int k = 0; k < 4; k++) {
      int nx = x + dx[k], ny = y + dy[k];
      if (nx < 1 || nx > n || ny < 1 || ny > n)
        continue;
      if (vis[nx][ny])
        join((x - 1) * n + y, (nx - 1) * n + ny);
    }
  }
  printf("%d\n", ret);
  return 0;
}
