#[allow(unused_imports)]
use proconio::{input, marker::*};

#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};

#[allow(unused_imports)]
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*).unwrap();
    }
}

fn main() {
    input! {
        n: usize,
        p: [usize; n*n],
    }

    macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ z : expr ) ,+ ) => { { std :: cmp :: min ( $ x , min ! ( $ ( $ z ) ,* ) ) } } }

    let mut cost = vec![vec![0usize; n]; n];
    for i in 0..n {
        for j in 0..n {
            cost[i][j] = min!(i, j, n - 1 - i, n - 1 - j);
        }
    }
    let mut exist = vec![vec![true; n]; n];
    let dx = [0, 0, 1, -1];
    let dy = [1, -1, 0, 0];
    let mut res = 0usize;
    for e in p {
        let x = (e - 1) % n;
        let y = (e - 1) / n;
        let mut queue = VecDeque::new();
        queue.push_back((x, y));
        res += cost[x][y];
        exist[x][y] = false;
        while let Some((x, y)) = queue.pop_front() {
            for i in 0..4 {
                let nx = x as isize + dx[i];
                let ny = y as isize + dy[i];
                if nx < 0 || ny < 0 || nx as usize >= n || ny as usize >= n {
                    continue;
                }
                let nx = nx as usize;
                let ny = ny as usize;
                if cost[nx][ny] > cost[x][y] + exist[x][y] as usize {
                    cost[nx][ny] = cost[x][y];
                    queue.push_back((nx, ny));
                }
            }
        }
    }
    println!("{}", res);
}
