// Arup Guha
// 2/23/2017
// Solution to USACO February Gold Problem: Why did the Cow Cross the Road I? (Visit FJ)

import java.util.*;
import java.io.*;

public class visitfj {

	// Weirdest DX, DY array I've ever had - trick is that you can move 1 square by going back and forth 3 times.
	final public static int[] DX = {-3,-2,-2,-1,-1,0,0,1,1,2,2,3,-1,0,0,1};
	final public static int[] DY = {0,-1,1,-2,2,-3,3,-2,2,-1,1,0,0,-1,1,0};
	final public static long NOSOL = 1000000000000000000L;

	public static int n;
	public static int[][] grid;
	public static int time;

	public static void main(String[] args) throws Exception {

		// Read in grid.
		BufferedReader stdin = new BufferedReader(new FileReader("visitfj.in"));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		n = Integer.parseInt(tok.nextToken());
		time = Integer.parseInt(tok.nextToken());
		grid = new int[n][n];
		for (int i=0; i<n; i++) {
			tok = new StringTokenizer(stdin.readLine());
			for (int j=0; j<n; j++)
				grid[i][j] = Integer.parseInt(tok.nextToken());
		}

		// Go from top left.
		edge[][] est = dijkstras(0, 0);

		// Now, we only have to consider moving at most 2 spots from the last place we ate grass.
		long res = NOSOL;
		for (int i=n-3; i<n; i++) {
			for (int j=n-3; j<n; j++) {

				// Too far away or out of bounds.
				if (i+j < 2*n-4) continue;
				if (i < 0 && j < 0) continue;

				// Not a valid square to build off of.
				if (est[i][j].w == NOSOL) continue;

				// Best answer building off square (i,j).
				long tmp = est[i][j].w + time*(2*n-2-i-j);
				res = Math.min(res, tmp);
			}
		}

		// Ta da!
		PrintWriter out = new PrintWriter(new FileWriter("visitfj.out"));
		out.println(res);
		out.close();
		stdin.close();
	}

	public static edge[][] dijkstras(int r, int c) {

		// Put in default distances.
		edge[][] list = new edge[n][n];
		for (int i=0; i<n; i++)
			for (int j=0; j<n; j++)
				list[i][j] = new edge(n*i+j, NOSOL);
		list[r][c] = new edge(n*r+c, 0);
		boolean[][] used = new boolean[n][n];

		// Set up PQ for Dijkstra's.
		PriorityQueue<edge> pq = new PriorityQueue<edge>();
		for (int i=0; i<n; i++)
			for (int j=0; j<n; j++)
				pq.offer(list[i][j]);

		// Run Dijkstra's
		while (pq.size() > 0) {

			// Get next.
			edge cur = pq.poll();
			int curX = cur.to/n;
			int curY = cur.to%n;

			// Look at neighbors - update distance if necessary.
			for (int i=0; i<DX.length; i++) {
				int nextX = curX + DX[i];
				int nextY = curY + DY[i];
				if (!inbounds(nextX, nextY)) continue;
				int nextW = grid[nextX][nextY] + 3*time;

				// Update shortest distance for this node.
				if (cur.w+nextW < list[nextX][nextY].w) {
					pq.remove(list[nextX][nextY]);
					list[nextX][nextY].w = cur.w+nextW;
					pq.offer(list[nextX][nextY]);
				}
			}
		}

		return list;
	}

	public static boolean inbounds(int x, int y) {
		return x >= 0 && x < n && y >= 0 && y < n;
	}
}

class edge implements Comparable<edge> {

	public int to;
	public long w;

	public edge(int myV, long myW) {
		to = myV;
		w = myW;
	}

	public int compareTo(edge other) {
		if (this.w < other.w) return -1;
		if (this.w > other.w) return 1;
		return 0;
	}
}
