// SmartCoder
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>  // Including tree_order_statistics_node_update

using namespace __gnu_pbds;
using namespace std;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(), (c).end()
#define tr(c, i) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c, x) ((c).find(x) != (c).end())
#define cpresent(c, x) (find(all(c), x) != (c).end())
#define minei(x) min_element(x.begin(), x.end()) - (x).begin()
#define maxei(x) max_element(x.begin(), x.end()) - (x).begin()
#define LSOne(S) (S & (-S))

#define uns(v) sort((v).begin(), (v).end()), v.erase(unique(v.begin(), v.end()), v.end())
#define acusum(x) accumulate(x.begin(), x.end(), 0)
#define acumul(x) accumulate(x.begin(), x.end(), 1, multiplies<int>());
#define bits(x) __builtin_popcount(x)
#define oo INT_MAX
#define inf 1000000000
#define MAXN 505
#define MOD 1000000007

const double pi = acos(-1.0);
const double eps = 1e-11;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
int mat[MAXN][MAXN];
int CST[MAXN][MAXN][MAXN];
int dirI[4] = {0, 0, 1, -1};
int dirJ[4] = {1, -1, 0, 0};
int n;
int iter = 0;
pair<int, int> getCell(int c) {
    c--;
    return {c / n, c % n};
}
bool outSide(int x, int y) {
    return x < 0 || y < 0 || x >= n || y >= n;
}
int dijkstra(int x, int y) {
    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> Q;
    Q.push({0, {x, y}});
    while (!Q.empty()) {
        pair<int, pair<int, int>> tp = Q.top();
        Q.pop();
        int cc = tp.first;
        int xx = tp.second.first;
        int yy = tp.second.second;
        if (outSide(xx, yy)) {
            return cc;
        }
        CST[iter][xx][yy] = min(CST[iter][xx][yy], cc);
        for (int k = 0; k < 4; k++) {
            int nx = xx + dirI[k];
            int ny = yy + dirJ[k];
            if (outSide(nx, ny)) {
                Q.push({cc, {nx, ny}});
            } else if (CST[iter][nx][ny] > cc + (mat[nx][ny] != 0)) {
                CST[iter][nx][ny] = cc + (mat[nx][ny] != 0);
                Q.push({cc + (mat[nx][ny] != 0), {nx, ny}});
            }
        }
    }
    return 0;
}
void clearIt() {
    for (int i = 0; i < MAXN; i++) {
        for (int j = 0; j < MAXN; j++) {
            for (int k = 0; k < MAXN; k++) {
                CST[i][j][k] = inf;
            }
        }
    }
}
int main() {
    std::ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    clearIt();
    cin >> n;
    int cnt = 0;
    int v;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            mat[i][j] = ++cnt;
        }
    }
    int res = 0;
    for (int i = 0; i < n * n; i++) {
        cin >> v;
        pair<int, int> pos = getCell(v);
        mat[pos.first][pos.second] = 0;
        res += dijkstra(pos.first, pos.second);
        iter++;
        if (i % 500 == 0) {
            clearIt();
            iter = 0;
        }
    }
    cout << res << endl;

    return 0;
}
