#include <bits/stdc++.h> 
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
#include<cmath>
#define pb push_back
#define ll long long
#define ull unsigned long long
#define deb(x) cerr<<#x<<" "<<x<<"\n"
#define debi cerr<<"hey sparky\n"
#define x first
#define y second
#define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define newline cout<<"\n"
#define yes cout<<"Yes"<<"\n"
//#define no cout<<"No"<<"\n"
#define INF (ll)1e18+5
#define nax (int)2e5+3
#define eps (double)1e-9
#define all(x) x.begin(),x.end()
#define MAX_N (int)1e6+2
using namespace std;
using namespace __gnu_pbds; 
typedef tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> pdbs;

void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

// look for  all edge cases
//search for a pattern






int main(){
	fast;
	int n;
	cin >> n;
	vector<int> order;
	
	for(int i =0 ; i < n*n; i++){
		int temp;
		cin >> temp;
		order.pb(temp);
	}
	
	
	bool mat[n+1][n+1];
	memset(mat,true,sizeof(mat));
	
	int ans = 0;
	for(int i =0 ;i < n*n ; i++ ){
		order[i]--;
		//int no = order[i];
		int row = order[i]/(n);
		int col = order[i]%(n);
		int cnt = 0;
		int temp = INT_MAX;
		for(int j =row - 1 ; j >=  0 ; j-- ){
			if(mat[j][col] == true){
				cnt++;
			}
		}
		temp =  min(temp,cnt);
		cnt =0 ;
		for(int j = row+1 ; j <= n-1 ;j++){
			if(mat[j][col] == true){
				cnt++;
			}
		}
		temp =  min(temp,cnt);
		cnt =0 ;
		for(int j = col+1 ; j <= n-1 ;j++){
			if(mat[row][j] == true){
				cnt++;
			}
		}
		temp =  min(temp,cnt);
		cnt =0 ;
		for(int j = col -1  ; j >= 0 ;j--){
			if(mat[row][j] == true){
				cnt++;
			}
		}
		temp =  min(temp,cnt);
		
		ans += temp;
		
		mat[row][col] = false;
	}
	cout<<ans;
	
	
	return 0;
}

	
