#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template< typename T >
using Edges = vector< edge< T > >;
template< typename T >
using WeightedGraph = vector< Edges< T > >;
using UnWeightedGraph = vector< vector< int > >;
template< typename T >
using Matrix = vector< vector< T > >;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);

  
  int n;
  cin >> n;
  vector<ll> p(n*n);
  rep(i,n*n){
    cin >> p[i];
    --p[i];
  }
  WeightedGraph< int > g(n*n*2+1);
  int di[4] = {0,1,0,-1};
  int dj[4] = {1,0,-1,0};
  rep(i,n){
    rep(j,n){
      g[i*n+j].push_back(edge(i*n+j+n*n,1));
      rep(k,4){
        int ni = i+di[k];
        int nj = j+dj[k];
        if(ni>=0 && ni<n&& nj>=0 && nj<n){
          g[i*n+j+n*n].push_back(edge(ni*n+nj,0));
        }
      }
      if(i==n-1 || j==n-1 || i==0 || j==0){
        g[2*n*n].push_back(edge(i*n+j,0));
      }
    }
  }
  int ans = 0;
  const auto INF = numeric_limits< int >::max();
  vector< int > dist(g.size(), INF);
  int s = 2*n*n;
  using Pi = pair< int, int >;
  priority_queue< Pi, vector< Pi >, greater< Pi > > que;
  dist[s] = 0;
  que.emplace(dist[s], s);
  while(!que.empty()) {
    int cost;
    int idx;
    tie(cost, idx) = que.top();
    que.pop();
    if(dist[idx] < cost) continue;
    for(auto &e : g[idx]) {
      auto next_cost = cost + e.cost;
      if(dist[e.to] <= next_cost) continue;
      dist[e.to] = next_cost;
      que.emplace(dist[e.to], e.to);
    }
  }
  rep(l,n*n){
    int i = p[l]/n;
    int j = p[l]%n;
    ans += dist[i*n+j];
    g[i*n+j].clear();
    g[i*n+j].push_back(edge(i*n+j+n*n,0));
    que.emplace(dist[i*n+j],i*n+j);
    while(!que.empty()) {
      int cost;
      int idx;
      tie(cost, idx) = que.top();
      que.pop();
      if(dist[idx] < cost) continue;
      for(auto &e : g[idx]) {
        auto next_cost = cost + e.cost;
        if(dist[e.to] <= next_cost) continue;
        dist[e.to] = next_cost;
        que.emplace(dist[e.to], e.to);
      }
    }
  }
  cout << ans << endl;
  return 0;
    

}
