#include <bits/stdc++.h>
using namespace std;
#define FIO() ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)

typedef long long ll;
typedef long long unsigned lu;
typedef long double ld;
typedef std::pair<int, int> ii;
typedef std::pair<int, ii> iii;
typedef std::pair<ll, ll> ll2;
typedef std::pair<ll, ll2> ll3;
typedef std::pair<double, double> dd;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<string> vs;

template<class T> using min_queue = priority_queue<T, vector<T>, greater<T> >;
template<class T> using max_queue = priority_queue<T>;

#define fi first
#define se second
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define bg begin()

template<class A, class B> ostream& operator << (ostream& out, const pair<A, B>& a) {
    return out << "(" << a.first << ", " << a.second << ") ";
}
template<class T, size_t... I> void print_tuple(ostream& s, T const& a, index_sequence<I...>) {
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0? "" : ", ") << get<I>(a)), 0)...};
}
template<class... A> ostream& operator<<(ostream& s, tuple<A...> const& a) {
  s << '('; print_tuple(s, a, index_sequence_for<A...>{}); return s << ')';
}
template<class T> ostream& print_collection(ostream& out, T const& a) {
    out << "{ "; for (auto& i : a) out << i << " "; return out << " }\n ";
}
template<class A> ostream& operator << (ostream& out, const vector<A>& a) {
    out << "[ "; for(int i=0; i < a.size(); ++i) out << "(" << i << " , " << a[i] << ") "; out << " ]\n ";
    return out;
}
template<class T> ostream& operator<<(ostream& s, queue<T> const& a) { return print_collection(s, a); }
template<class T> ostream& operator<<(ostream& s, stack<T> const& a) { return print_collection(s, a); }
template<class T> ostream& operator<<(ostream& s, priority_queue<T> const& a) { return print_collection(s, a); }
template<class T, class U> ostream& operator<<(ostream& s, multimap<T, U> const& a) { return print_collection(s, a); }
template<class T> ostream& operator<<(ostream& s, multiset<T> const& a) { return print_collection(s, a); }
template<class T, class U> ostream& operator<<(ostream& s, map<T, U> const& a) { return print_collection(s, a); }
template<class T> ostream& operator<<(ostream& s, set<T> const& a) { return print_collection(s, a); }
template<class T, class U> ostream& operator<<(ostream& s, unordered_map<T, U> const& a) { return print_collection(s, a); }
template<class T> ostream& operator<<(ostream& s, unordered_set<T> const& a) { return print_collection(s, a); }

int N; 
vi per;
vi cost;
vector<bool> out;

void update(int curr, int c, bool first=true) {
    if (curr <= 0 || curr > N*N) return; // out of the square
    if (!first && cost[curr] <= c) return; // do not yield improvements
    
    cost[curr] = c;
    // cout << "update "<<curr<<endl;
    c += (out[curr] == false);
    if (curr%N != 0) update(curr+1 , c, false); // cell to the right
    if (curr%N != 1) update(curr-1, c, false); // cell to the left
    update(curr+N, c, false);
    update(curr-N, c, false);
}

void solve() {
    cin >> N;
    per = vi(N*N+1, 0);
    cost = vi(N*N+1, 0);
    out = vector<bool>(N*N+1, false);
    for (int i=1; i<N*N+1; ++i) {
        int p; cin >> p;
        per[i] = p;
    }

    // assign cost
    for (int i=0; i<N; ++i) {
        for (int j=0; j<N; ++j) {
            cost[i*N+j+1] = min(min(i, N-i-1), min(j, N-j-1));
        }
    }

    ll ans = 0;
    for (auto i : per) {
        if (i == 0) continue;
        out[i] = true;
        ans += cost[i];
        // cout << "person "<<i<<" cost "<<cost[i]<<endl;
        update(i, cost[i]);
    }

    cout << ans << "\n";
}

int main () {
    solve();
    return 0;
}

Measured memory_bytes: 12852