#![allow(unused)]

use proconio::input;
use proconio::marker::{Bytes, Chars, Usize1};
use std::cmp::{Reverse, min, max};
use itertools::Itertools;

fn cost(
    n: usize,
    exittimes: &Vec<Vec<i64>>,
    (istart, jstart): (usize, usize),
) -> i64 {
    let mut pq = std::collections::BinaryHeap::new();
    let mut ds = vec![vec![std::i64::MAX; n]; n];
    let mut ans = std::i64::MAX;

    ds[istart][jstart] = 0;
    pq.push((Reverse(0), istart, jstart));

    while let Some((Reverse(d), i, j)) = pq.pop() {
        if d > ds[i][j] {
            continue;
        }

        if i == 0 || i == n - 1 || j == 0 || j == n - 1 {
            ans = min(ans, ds[i][j]);
        } else {
            for &(i_, j_) in &[(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)] {
                let exittimes = exittimes;
                let d = if exittimes[i_][j_] < exittimes[istart][jstart] {
                    ds[i][j]
                } else {
                    ds[i][j] + 1
                };

                if d < ds[i_][j_] {
                    ds[i_][j_] = d;
                    pq.push((Reverse(d), i_, j_));
                }
            }
        }
    }

    return ans;
}

#[proconio::fastout]
fn main() {
    input! {
        n: usize,
        ps: [Usize1; n * n],
    }

    let mut exittimes = vec![vec![0; n]; n];
    for t in 0..ps.len() {
        exittimes[ps[t] / n][ps[t] % n] = t as i64;
    }

    let ans: i64 = (1..(n - 1))
        .flat_map(|i| std::iter::repeat(i).zip(1..(n - 1)))
        .map(|p| cost(n, &exittimes, p))
        .sum();
    println!("{}", ans);
}
