import java.awt.geom.Point2D;
import java.awt.geom.Line2D;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;

public class ANARC_2010_I_alt
{
	BufferedReader in;
	Scanner inr;
	PrintWriter out;

	void initIO() throws IOException
	{
		inr = new Scanner(System.in);
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(new OutputStreamWriter(System.out));
	}

	int n, C;

	int res;

	int[] x, y;

	int[][] c;

	int[] a;
	
	Line2D[][] segments;
	
	boolean intersects[][][][];

	public boolean next_permutation2(int a[])
	{
		for (int i = a.length - 2, j; i >= 0; i--)
		{
			if (a[i+1] > a[i])
			{
				for (j = a.length - 1; a[j] <= a[i]; j--);
				swap(a, i, j);
				for (j = 1; j <= (a.length - i) / 2; j++)
					swap(a, i + j, a.length - j);
				return true;
			}
		}
		return false;
	}

	public void swap(int a[], int i, int j)
	{
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}

	int det(int p11, int p12, int p21, int p22)
	{
		return p11 * p22 - p21 * p12;
	}
	
	int[] to_line(int x1, int y1, int x2, int y2)
	{
		int[] r = new int[3];
		r[0] = y1 - y2;
		r[1] = x2 - x1;
		r[2] = - (r[0] * x1 + r[1] * y1);
		return r;
	}
	
	int gcd(int a, int b)
	{
		a = Math.abs(a);
		b = Math.abs(b);
		while (a != 0 && b != 0)
			if (a > b)
				a %= b;
			else
				b %= a;
		return a + b;
	}
	
	int[] intersect(int p11, int p12, int p21, int p22)
	{
		int[] r = new int[2];
		int[] L1 = to_line(x[p11], y[p11], x[p12], y[p12]);
		int[] L2 = to_line(x[p21], y[p21], x[p22], y[p22]);
		r[0] = -det(L1[2], L1[1], L2[2], L2[1]);
		r[1] = -det(L1[0], L1[2], L2[0], L2[2]);
		int g = gcd(r[0], r[1]);
		if (g > 0)
		{
			r[0] /= g;
			r[1] /= g;
		}
		if (r[1] < 0) {r[1] = -r[1]; r[0] = -r[0];}
		return r;
	}
	
	void calc()
	{
		res = Integer.MAX_VALUE;
		int[] p = new int[n-1];
		a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = i;
		for (int i = 0; i < n-1; i++)
			p[i] = i;
		do
		{
			for (int i = 0; i < n-1; i++)
				a[i] = p[i];
			int cost = 0;
			for (int i = 0; i < n; i++)
				cost += c[a[i]][a[(i+1)%n]];
			Map<Long, HashSet<Integer>> pts = new HashMap<Long, HashSet<Integer>>();
			int add = 0;
			if (cost < res)
			{
    			for (int i1 = 0; i1 < n; i1++)
    				for (int i2 = 0; i2 < n; i2++)
    				{
    					int p11 = a[i1];
    					int p12 = a[(i1+1)%n];
    					if (p11 > p12) {int t = p11; p11 = p12; p12 = t;}
    					int p21 = a[i2];
    					int p22 = a[(i2+1)%n];
    					if (p21 > p22) {int t = p21; p21 = p22; p22 = t;}
    					if (p11 == p21 || p11 == p22)
    						continue;
    					if (p12 == p21 || p12 == p22)
    						continue;
    					if (!intersects[p11][p12][p21][p22])
    						continue;
    					int[] pt = intersect(p11, p12, p21, p22);
    					Long key = pt[0] * 1000000000L + pt[1];
    					HashSet<Integer> already = pts.get(key);
    					if (already == null)
    						already = new HashSet<Integer>();
    					already.add(p11 * 10 + p12);
    					already.add(p21 * 10 + p22);
    					pts.put(key, already);
    				}
    			for (Long key : pts.keySet())
    			{
    				HashSet<Integer> set = pts.get(key);
    				int k = set.size();
    				add += k * (k - 1) * C / 2;
    			}
			}
			cost += add;
			if (cost < res)
			{
				res = cost;
			}
		}
		while (next_permutation2(p));
	}

	void solve() throws Exception
	{
		int nt = 0;
		while (true)
		{
			n = nextInt();
			if (n == 0)
				break;
			C = nextInt();
			x = new int[n];
			y = new int[n];
			c = new int[n][n];
			for (int i = 0; i < n; i++)
			{
				x[i] = nextInt();
				y[i] = nextInt();
			}
			segments = new Line2D[n][n];
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					segments[i][j] = new Line2D.Double(new Point2D.Double(1.0 * x[i], 1.0 * y[i]), new Point2D.Double(1.0 * x[j], 1.0 * y[j]));
			intersects = new boolean[n][n][n][n];
			for (int i1 = 0; i1 < n; i1++)
				for (int i2 = 0; i2 < n; i2++)
					for (int i3 = 0; i3 < n; i3++)
						for (int i4 = 0; i4 < n; i4++)
							intersects[i1][i2][i3][i4] = segments[i1][i2].intersectsLine(segments[i3][i4]);
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					c[i][j] = nextInt();
			calc();
			out.println("" + (++nt) + ". " + res);
			out.flush();
		}
	}

	void run() throws Exception
	{
		initIO();
		solve();
		out.flush();
	}

	int nextInt()
	{
		return inr.nextInt();
	}

	String nextLine()
	{
		return inr.nextLine();
	}

	String nextString()
	{
		return inr.next();
	}

	public static void main(String[] args) throws Exception
	{
		new ANARC_2010_I_alt().run();
	}
}
