import java.io.*;
import java.util.*;

public class CF {
    FastScanner in;
    PrintWriter out;

    class Road implements Comparable<Road> {
        int to;
        long energy;

        public Road(int to, long energy) {
            super();
            this.to = to;
            this.energy = energy;
        }

        @Override
        public int compareTo(Road arg0) {
            return -Long.compare(energy, arg0.energy);
        }

    }

    void solve() throws IOException {
        int n = in.nextInt();
        int d = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n - 2; i++) {
            a[i + 1] = in.nextInt();
        }
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        int l = 0, r = 4 * (int) 1e7 + 100;
        while (r - l > 1) {
            int me = (l + r) / 2;
            boolean[] was = new boolean[n];
            long[] cost = new long[n];
            Arrays.fill(cost, -1);
            cost[0] = me;
            PriorityQueue<Road> pq = new PriorityQueue<>();
            pq.add(new Road(0, me));
            while (pq.size() > 0) {
                Road ro = pq.remove();
                was[ro.to] = true;
                if (cost[ro.to] > ro.energy)
                    continue;
                if (ro.energy == 0)
                    continue;
                for (int i = 0; i < n; i++) {
                    if (!was[i]) {
                        long newCost = ro.energy
                                - d
                                * (Math.abs(x[i] - x[ro.to]) + Math.abs(y[i]
                                        - y[ro.to]));
                        if (newCost >= 0)
                            newCost += a[i];
                        if (newCost > cost[i]) {
                            pq.add(new Road(i, newCost));
                            cost[i] = newCost;
                        }
                    }
                }
            }
            if (cost[n - 1] >= 0) {
                r = me;
            } else {
                l = me;
            }
        }
        out.println(r);
    }

    void run() throws IOException {
        try {
            in = new FastScanner(new File("test.in"));
            out = new PrintWriter(new File("test.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() throws IOException {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }

    public static void main(String[] args) throws IOException {
        new CF().runIO();
    }
}


import java.io.*;
import java.util.*;

public class CF {
    FastScanner in;
    PrintWriter out;

    class Road implements Comparable<Road> {
        int to;
        long energy;

        public Road(int to, long energy) {
            super();
            this.to = to;
            this.energy = energy;
        }

        @Override
        public int compareTo(Road arg0) {
            return -Long.compare(energy, arg0.energy);
        }

    }

    void solve() throws IOException {
        int n = in.nextInt();
        int d = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n - 2; i++) {
            a[i + 1] = in.nextInt();
        }
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        int l = 0, r = 2 * (int) 1e7 + 100;
        while (r - l > 1) {
            int me = (l + r) / 2;
            boolean[] was = new boolean[n];
            long[] cost = new long[n];
            Arrays.fill(cost, -1);
            cost[0] = me;
            PriorityQueue<Road> pq = new PriorityQueue<>();
            pq.add(new Road(0, me));
            while (pq.size() > 0) {
                Road ro = pq.remove();
                was[ro.to] = true;
                if (cost[ro.to] > ro.energy)
                    continue;
                if (ro.energy == 0)
                    continue;
                for (int i = 0; i < n; i++) {
                    if (!was[i]) {
                        long newCost = ro.energy
                                - d
                                * (Math.abs(x[i] - x[ro.to]) + Math.abs(y[i]
                                        - y[ro.to]));
                        if (newCost >= 0)
                            newCost += a[i];
                        if (newCost > cost[i]) {
                            pq.add(new Road(i, newCost));
                            cost[i] = newCost;
                        }
                    }
                }
            }
            if (cost[n - 1] >= 0) {
                r = me;
            } else {
                l = me;
            }
        }
        out.println(r);
    }

    void run() throws IOException {
        try {
            in = new FastScanner(new File("test.in"));
            out = new PrintWriter(new File("test.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() throws IOException {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }

    public static void main(String[] args) throws IOException {
        new CF().runIO();
    }
}


import java.util.*;
import static java.lang.Math.*;

public class B {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int C = in.nextInt();
		int[] V = new int[N];
		for (int i = 1; i < N - 1; i++)
			V[i] = in.nextInt();

		int[] X = new int[N];
		int[] Y = new int[N];
		for (int i = 0; i < N; i++) {
			X[i] = in.nextInt();
			Y[i] = in.nextInt();
		}

		long[][] D = new long[N][N];
		for (long[] d:D)
			Arrays.fill(d, Integer.MAX_VALUE);
		for (int i = 0; i < N; i++)
			D[i][i] = 0;

		for (int i = 0; i < N; i++) {
			for (int j = i+1; j < N; j++) {
				int dist = abs(X[i]-X[j]) + abs(Y[i]-Y[j]);
				D[i][j] = dist*C - V[j];
				D[j][i] = dist*C - V[i];
			}
		}

		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
				for (int k = 0; k < N; k++)
					D[j][k] = min(D[j][k], D[j][i]+D[i][k]);
		System.out.println(D[0][N-1]);
	}
}


import java.io.*;
import java.util.*;
public class z1 {
	public static void main(String[] args) throws IOException {
		StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int n=(int) in.nval;
		in.nextToken();
		long d=(long) in.nval;
		int[] a=new int[n];
		for (int i=1;i<(n-1);i++) {in.nextToken();a[i]=(int) in.nval;}; a[n-1]=0;
		int[] koordx=new int[n];
		int[] koordy=new int[n];
		for (int i=0;i<n;i++) {in.nextToken();koordx[i]=(int) in.nval;in.nextToken();koordy[i]=(int) in.nval;}
		long b[][]=new long[n][n];
	    for (int i=0;i<n;i++) for(int j=1;j<n;j++) b[i][j]=d*(Math.abs(koordx[i]-koordx[j])+Math.abs(koordy[i]-koordy[j]))-a[j];
	    boolean flag=true;
	    while (flag)
	    {
	    	flag=false;
	    	for (int i=0;i<n;i++) for (int j=1;j<n;j++) for (int k=1;k<n;k++)
	    		if ((i!=k)&&(i!=j)&&(k!=j))
	    			if (b[i][j]>(b[i][k]+b[k][j])) {b[i][j]=b[i][k]+b[k][j];flag=true;}
	    }
	    out.println(b[0][n-1]);
		out.flush();
	}
}


import java.io.*;
import java.util.*;
public class z1 {
	public static void main(String[] args) throws IOException {
		StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int n=(int) in.nval;
		in.nextToken();
		long d=(long) in.nval;
		int[] a=new int[n];
		for (int i=1;i<(n-1);i++) {in.nextToken();a[i]=(int) in.nval;}; a[n-1]=0;
		int[] koordx=new int[n];
		int[] koordy=new int[n];
		for (int i=0;i<n;i++) {in.nextToken();koordx[i]=(int) in.nval;in.nextToken();koordy[i]=(int) in.nval;}
		long b[][]=new long[n][n];
	    for (int i=0;i<n;i++) for(int j=1;j<n;j++) b[i][j]=d*(Math.abs(koordx[i]-koordx[j])+Math.abs(koordy[i]-koordy[j]))-a[j];
	    long[] rast=new long[n];
	    rast[0]=0;
	    for (int i=1;i<n;i++) rast[i]=(long)1e15;
	    int[] st=new int[n];
	    int min;
	    long vmin;
	    int c;
	    for (int i=0;i<n;i++)st[i]=i;
	    for (int i=0;i<(n-1);i++)
	    {
	    	min=-1;vmin=(long)1e15;
	    	for (int j=i;j<n;j++)
	    	if (rast[st[j]]<vmin) {vmin=rast[st[j]];min=j;}
	    	c=st[min];st[min]=st[i];st[i]=c;
	    	for (int j=i+1;j<n;j++) rast[st[j]]=Math.min(rast[st[j]],rast[c]+b[c][st[j]]);
	    }
	    out.println(rast[n-1]);
		out.flush();
	}
}


import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Author   : Dylan
 * Date     : 2013-07-22
 * Time     : 10:33
 * Project  : Yaroslav and Time
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long d = in.nextLong();
        int[] a = new int[n + 1];
        int[] x = new int[n + 1];
        int[] y = new int[n + 1];
        for (int i = 2; i < n; i++) {
            a[i] = in.nextInt();
        }
        for (int i = 1; i <= n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        long[][] dp = new long[n + 1][n + 1];
        for(int i = 1; i < n; i++) {
            for(int j = i + 1; j <= n; j++) {
                dp[i][j] = d * (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) - a[j];
                dp[j][i] = d * (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) - a[i];
            }
        }
        for(int k = 1; k <= n; k++) {
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= n; j++) {
                    if(i == k || j == k || i == j) continue;
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
        System.out.println(dp[1][n]);
    }
}


import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Author   : Dylan
 * Date     : 2013-07-22
 * Time     : 10:33
 * Project  : Yaroslav and Time
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long d = in.nextLong();
        int[] a = new int[n + 1];
        int[] x = new int[n + 1];
        int[] y = new int[n + 1];
        for (int i = 2; i < n; i++) {
            a[i] = in.nextInt();
        }
        for (int i = 1; i <= n; i++) {
            x[i] = in.nextInt();
        }
        for (int i = 1; i <= n; i++) {
            y[i] = in.nextInt();
        }
        long[][] dp = new long[n + 1][n + 1];
        for(int i = 1; i < n; i++) {
            for(int j = i + 1; j <= n; j++) {
                dp[i][j] = d * (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) - a[j];
                dp[j][i] = d * (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) - a[i];
            }
        }
        for(int k = 2; k < n; k++) {
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= n; j++) {
                    if(i == k || j == k || i ==j) continue;
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
        System.out.println(dp[1][n]);
    }
}


//package round182;
import java.util.*;
import java.io.*;

public class TaskB {
	FastScanner in;
	PrintWriter out;

	public void solve() throws IOException {
		int n = in.nextInt();
		int d = in.nextInt();
		int[] c = new int[n];
		int[] x = new int[n];
		int[] y = new int[n];
		int a[][] = new int[n][n];
		for (int i = 1; i < n - 1; i++) {
			c[i] = in.nextInt();
		}
		for (int i = 0; i < n; i++) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
			for (int j = 0; j < i; j++) {
				a[i][j] = ( Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j]) ) * d - c[j];
				a[j][i] = ( Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j]) ) * d - c[i];
			}
		}

		boolean[] f = new boolean[n];
		int[] w = new int[n + 1];
		w[n] = Integer.MAX_VALUE;

		for (int i = 0; i < n; i++) {
			w[i] = a[0][i];
		}

		while (!f[n -1]) {
			int min = n;
			for (int i = 0; i < n; i++) {
				if (!f[i] && w[i] < w[min]) {
					min = i;
				}
			}
			f[min] = true;
			for (int i = 0; i < n; i++) {
				if ((a[min][i] + w[min]) < w[i]) {
					w[i] = a[min][i] + w[min];
				}
			}
		}
		System.out.println(w[n - 1]);
	}

	public void run() {
		try {
			in = new FastScanner(System.in);
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}
	}

	public static void main(String[] arg) {
		new TaskB().run();
	}
}


package round182;
import java.util.*;
import java.io.*;

public class TaskB {
	FastScanner in;
	PrintWriter out;

	public void solve() throws IOException {
		int n = in.nextInt();
		int d = in.nextInt();
		int[] c = new int[n];
		int[] x = new int[n];
		int[] y = new int[n];
		int a[][] = new int[n][n];
		for (int i = 1; i < n - 1; i++) {
			c[i] = in.nextInt();
		}
		for (int i = 0; i < n; i++) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
			for (int j = 0; j < i; j++) {
				a[i][j] = ( Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j]) ) * d - c[j];
				a[j][i] = ( Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j]) ) * d - c[i];
			}
		}

		boolean[] f = new boolean[n];
		int[] w = new int[n + 1];
		w[n] = Integer.MAX_VALUE;

		for (int i = 0; i < n; i++) {
			w[i] = a[0][i];
		}

		while (!f[n -1]) {
			int min = n;
			for (int i = 0; i < n; i++) {
				if (!f[i] && w[i] < w[min]) {
					min = i;
				}
			}
			f[min] = true;
			for (int i = 0; i < n; i++) {
				if ((a[min][i] + w[min]) < w[i]) {
					w[i] = a[min][i] + w[min];
				}
			}
		}
		System.out.println(w[n - 1]);
	}

	public void run() {
		try {
			in = new FastScanner(System.in);
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}
	}

	public static void main(String[] arg) {
		new TaskB().run();
	}
}


import java.io.*;
import java.util.*;
import java.math.*;

public class Main implements Runnable {
	public static void main(String[] args) {
		new Thread(new Main()).run();
	}
	final static int MAX_SIZE = 211;
	public void run() {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = in.nextInt(), d = in.nextInt();
		int[] a = new int[n], x = new int[n], y = new int[n];
		for (int i = 1; i < n - 1; ++i)
			a[i] = in.nextInt();
		for (int i = 0; i < n; ++i) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
		}
		int cx = 1, cy = 1;
		if (x[n - 1] > x[0])
			cx = -1;
		if (y[n - 1] > y[0])
			cy = -1;
		for (int i = 0; i < n; ++i) {
			x[i] *= cx;
			y[i] *= cy;
		}
		for (int i = 0; i < n - 1; ++i) {
			x[i] -= x[n - 1];
			y[i] -= y[n - 1];
		}
		int[][] map = new int[MAX_SIZE][MAX_SIZE];
		for (int i = 1; i < n - 1; ++i) {
			if (x[i] >= 0 && y[i] >= 0)
				map[x[i]][y[i]] = a[i];
		}
		int[][] dp = new int[x[0] + 1][y[0] + 1];
		for (int i = 1; i <= x[0]; ++i) {
			dp[i][0] = Math.max(0, d + dp[i - 1][0] - map[i][0]);
		}
		for (int i = 1; i <= y[0]; ++i) {
			dp[0][i] = Math.max(0, d + dp[0][i - 1] - map[0][i]);
		}
		for (int i = 1; i <= x[0]; ++i)
			for (int j = 1; j <= y[0]; ++j) {
				dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + d - map[i][j];
				if (dp[i][j] < 0)
					dp[i][j] = 0;
			}

		out.println(dp[x[0]][y[0]]);

		out.close();
	}
}

class InputReader {
	BufferedReader buff;
	StringTokenizer tokenizer;

	InputReader(InputStream stream) {
		buff = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}
	boolean hasNext() {
		while (tokenizer == null || !tokenizer.hasMoreTokens())
			try {
				tokenizer = new StringTokenizer(buff.readLine());
			}
			catch (Exception e) {
				return false;
			}
		return true;
	}
	String next() {
		if (!hasNext())
			throw new RuntimeException();
		return tokenizer.nextToken();
	}
	int nextInt() { return Integer.parseInt(next()); }
	long nextLong() { return Long.parseLong(next()); }
}


import java.io.*;
import java.util.*;
import java.math.*;

public class Main implements Runnable {
	public static void main(String[] args) {
		new Thread(new Main()).run();
	}
	final static int MAX_SIZE = 211;
	final static int INF = 0x3fffffff;
	public void run() {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = in.nextInt(), d = in.nextInt();
		int[] a = new int[n];
		for (int i = 1; i < n - 1; ++i)
			a[i] = in.nextInt();
		int[][] map = new int[MAX_SIZE][MAX_SIZE], dist = new int[MAX_SIZE][MAX_SIZE];
		int sx = 0, sy = 0, tx = 0, ty = 0;
		for (int i = 0; i < n; ++i) {
			int x = in.nextInt(), y = in.nextInt();
			x += MAX_SIZE / 2;
			y += MAX_SIZE / 2;
			map[x][y] = a[i];
			if (i == 0) {
				sx = x; sy = y;
			}
			if (i == n - 1) {
				tx = x; ty = y;
			}
		}
		boolean[][] valid = new boolean[MAX_SIZE][MAX_SIZE];
		for (int i = 0; i < MAX_SIZE; ++i)
			for (int j = 0; j < MAX_SIZE; ++j) {
				dist[i][j] = INF;
				valid[i][j] = true;
			}
		dist[sx][sy] = 0;
		Queue<Integer> qx = new LinkedList<Integer>();
		Queue<Integer> qy = new LinkedList<Integer>();
		qx.offer(sx); qy.offer(sy);
		while (!qx.isEmpty()) {
			int x = qx.poll(), y = qy.poll();
			valid[x][y] = true;
			for (int i = -1; i <= 1; ++i)
				for (int j = -1; j <= 1; ++j) {
					if (Math.abs(i) + Math.abs(j) == 1) {
						int nx = x + i, ny = y + j;
						if (nx >= 0 && ny >= 0 && nx < MAX_SIZE && ny < MAX_SIZE) {
							if (dist[x][y] + d - map[nx][ny] < dist[nx][ny]) {
								dist[nx][ny] = dist[x][y] + d - map[nx][ny];
								if (valid[nx][ny]) {
									qx.offer(nx); qy.offer(ny);
									valid[nx][ny] = false;
								}
							}
						}
					}
				}
		}

		out.println(dist[tx][ty]);
		out.close();
	}
}

class InputReader {
	BufferedReader buff;
	StringTokenizer tokenizer;

	InputReader(InputStream stream) {
		buff = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}
	boolean hasNext() {
		while (tokenizer == null || !tokenizer.hasMoreTokens())
			try {
				tokenizer = new StringTokenizer(buff.readLine());
			}
			catch (Exception e) {
				return false;
			}
		return true;
	}
	String next() {
		if (!hasNext())
			throw new RuntimeException();
		return tokenizer.nextToken();
	}
	int nextInt() { return Integer.parseInt(next()); }
	long nextLong() { return Long.parseLong(next()); }
}


import java.io.*;
import java.util.*;
import java.math.*;

public class Main implements Runnable {
	public static void main(String[] args) {
		new Thread(new Main()).run();
	}
	final static int MAX_SIZE = 211;
	public void run() {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = in.nextInt(), d = in.nextInt();
		int[] a = new int[n], x = new int[n], y = new int[n];
		for (int i = 1; i < n - 1; ++i)
			a[i] = in.nextInt();
		for (int i = 0; i < n; ++i) {
			x[i] = in.nextInt();
			y[i] = in.nextInt();
		}
		int cx = 1, cy = 1;
		if (x[n - 1] > x[0])
			cx = -1;
		if (y[n - 1] > y[0])
			cy = -1;
		for (int i = 0; i < n; ++i) {
			x[i] *= cx;
			y[i] *= cy;
		}
		for (int i = 0; i < n - 1; ++i) {
			x[i] -= x[n - 1];
			y[i] -= y[n - 1];
		}
		int[][] map = new int[MAX_SIZE][MAX_SIZE];
		for (int i = 1; i < n - 1; ++i) {
			if (x[i] >= 0 && y[i] >= 0)
				map[x[i]][y[i]] = a[i];
		}
		int[][] dp = new int[x[0] + 1][y[0] + 1];
		for (int i = 1; i <= x[0]; ++i) {
			dp[i][0] = d + dp[i - 1][0] - map[i][0];
		}
		for (int i = 1; i <= y[0]; ++i) {
			dp[0][i] = d + dp[0][i - 1] - map[0][i];
		}
		for (int i = 1; i <= x[0]; ++i)
			for (int j = 1; j <= y[0]; ++j) {
				dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + d - map[i][j];
			}

		out.println(dp[x[0]][y[0]]);

		out.close();
	}
}

class InputReader {
	BufferedReader buff;
	StringTokenizer tokenizer;

	InputReader(InputStream stream) {
		buff = new BufferedReader(new InputStreamReader(stream));
		tokenizer = null;
	}
	boolean hasNext() {
		while (tokenizer == null || !tokenizer.hasMoreTokens())
			try {
				tokenizer = new StringTokenizer(buff.readLine());
			}
			catch (Exception e) {
				return false;
			}
		return true;
	}
	String next() {
		if (!hasNext())
			throw new RuntimeException();
		return tokenizer.nextToken();
	}
	int nextInt() { return Integer.parseInt(next()); }
	long nextLong() { return Long.parseLong(next()); }
}


import java.io.*;
import java.util.*;

public class Main {

  public static void main(String[] args) throws IOException {
    int n = nextInt();
    int d = nextInt();
    int []a = new int[n];
    for (int i = 1; i < n - 1; ++i) {
      a[i] = nextInt();
    }
    int []x = new int[n];
    int []y = new int[n];
    for (int i = 0; i < n; ++i) {
      x[i] = nextInt();
      y[i] = nextInt();
    }
    int []f = new int[n];
    for (int i = 0; i < n; ++i) {
      f[i] = Integer.MAX_VALUE;
    }
    f[n - 1] = 0;
    for (int it = 0; it < n; ++it) {
      for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n; ++j) {
          if (j != i && f[j] != Integer.MAX_VALUE &&
              Math.min(x[i], x[n - 1]) <= x[j] && x[j] <= Math.max(x[i], x[n - 1]) &&
              Math.min(y[i], y[n - 1]) <= y[j] && y[j] <= Math.max(y[i], y[n - 1])) {
            int dist = (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) * d - a[j];
            f[i] = Math.min(f[i], dist + f[j]);
          }
        }
      }
    }
    System.out.println(Math.max(0, f[0]));
  }

  static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  static StringTokenizer st;

  static String nextToken() throws IOException {
    while (st == null || !st.hasMoreTokens()) {
        String line = br.readLine();
        if (line == null) {
            return null;
        }
        st = new StringTokenizer(line);
    }
    return st.nextToken();
  }

  static int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

  static long nextLong() throws IOException {
    return Long.parseLong(nextToken());
  }

  static double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }
}


import java.io.*;
import java.util.*;

public class Main {

  public static void main(String[] args) throws IOException {
    int n = nextInt();
    int d = nextInt();
    int []a = new int[n];
    for (int i = 1; i < n - 1; ++i) {
      a[i] = nextInt();
    }
    int []x = new int[n];
    int []y = new int[n];
    for (int i = 0; i < n; ++i) {
      x[i] = nextInt();
      y[i] = nextInt();
    }
    int []f = new int[n];
    for (int i = 0; i < n; ++i) {
      f[i] = Integer.MAX_VALUE;
    }
    f[n - 1] = 0;
    for (int it = 0; it < n; ++it) {
      for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n; ++j) {
          if (j != i && f[j] != Integer.MAX_VALUE
              // &&
//              Math.min(x[i], x[n - 1]) <= x[j] && x[j] <= Math.max(x[i], x[n - 1]) &&
//              Math.min(y[i], y[n - 1]) <= y[j] && y[j] <= Math.max(y[i], y[n - 1])
              ) {
            int dist = (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j])) * d - a[j];
            f[i] = Math.min(f[i], dist + f[j]);
          }
        }
      }
    }
    System.out.println(f[0]);
  }

  static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  static StringTokenizer st;

  static String nextToken() throws IOException {
    while (st == null || !st.hasMoreTokens()) {
        String line = br.readLine();
        if (line == null) {
            return null;
        }
        st = new StringTokenizer(line);
    }
    return st.nextToken();
  }

  static int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

  static long nextLong() throws IOException {
    return Long.parseLong(nextToken());
  }

  static double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }
}


import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Arrays.binarySearch;

public class Main {

	public static void main(String[] args) {

		try {
			if (new File("input.txt").exists()) {
				System.setIn(new FileInputStream("input.txt"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		new Thread(null, new Runnable() {
			public void run() {
				try {
					new Main().run();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 23).start();

	}

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
		in.close();
	}

	/******************************************************
	 * Solution
	 *****************************************************/

	void solve() throws IOException {
		int n = nextInt();
		long mul = nextLong();
		int a[] = new int[n];
		int x[] = new int[n];
		int y[] = new int[n];

		for(int i = 1; i < n - 1; i++){
			a[i] = nextInt();
		}
		for(int i = 0; i < n; i++){
			x[i] = nextInt();
			y[i] = nextInt();
		}

		long dist1[][] = new long[n][n];
		long dist2[][] = new long[n][n];

		for(long row[] : dist1)
			fill(row, inf);
		for(long row[] : dist2)
			fill(row, inf);

		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(i == j) continue;
				long cost = max(0, (abs(x[i] - x[j]) + abs(y[i] - y[j])) * mul);
				dist1[i][j] = cost;
				cost -= a[i];
				dist2[i][j] = cost;
			}
			dist1[i][i] = dist2[i][i] = 0;
		}
		for(int k = 0; k < n; k++)
			for(int i = 0; i < n; i++)
				for(int j = 0; j < n; j++)
					if(i != k && j != k)
						dist1[i][j] = min(dist1[i][j], max(0, dist1[i][k] + dist1[k][j] - a[k]));

		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				dist2[i][j] = min(dist2[i][j], dist1[i][j]);

		for(int k = 0; k < n; k++)
			for(int i = 0; i < n; i++)
				for(int j = 0; j < n; j++)
					if(k != j)
						dist2[i][j] = min(dist2[i][j], max(0, dist2[i][k] + dist1[k][j] - a[k]));

		out.println(dist2[0][n - 1]);
	}

	final long inf = Long.MAX_VALUE;

	int abs(int x){
		return x > 0 ? x : -x;
	}

	/******************************************************
	 * Utils
	 *****************************************************/

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null) {
				return true;
			}
			st = new StringTokenizer(s);
		}
		return false;
	}

}


import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Pavel Chuprikov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    int[] x;
    int[] y;
    int d;

    int dist(int i, int j) {
        return d * (Math.abs(x[i] - x[j]) + Math.abs(y[i] - y[j]));
    }
    public void solve(int testNumber, FastScanner in, PrintWriter out) {
        int n = in.nextInt();
        d = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n - 2; i++)
            a[i + 1] = in.nextInt();
        x = new int[n];
        y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }

        int[][] dp = new int[n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                dp[i][j] = dist(i, j);
        for (int k = 1; k < n - 1; k++) {
            int[][] ndp = new int[n][n];
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++) {
                    if (i == j)
                        continue;
                    ndp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j] - a[k]);
                }
            dp = ndp;
        }
        out.println(dp[0][n - 1]);
    }
}

class FastScanner {
    private BufferedReader br;
    private StringTokenizer st;

    public FastScanner(InputStream in) {
        this.br = new BufferedReader(new InputStreamReader(in));
    }

    public boolean hasNext() {
        try {
            while (st == null || !st.hasMoreTokens()) {
                final String nextLine = br.readLine();
                if (nextLine == null) {
                    return false;
                } else {
                    st = new StringTokenizer(nextLine);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return true;
    }

    public String next() {
        return hasNext() ? st.nextToken() : null;
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    }


import java.io.*;
import java.util.*;
public class d {
public static void main(String[] args) throws IOException {
	input.init(System.in);
	PrintWriter out = new PrintWriter(System.out);
	int n = input.nextInt(), d = input.nextInt();
	int[] as = new int[n];
	for(int i = 1; i<n-1; i++)
	{
		as[i] = input.nextInt();
	}
	int[] xs = new int[n], ys = new int[n];
	for(int i = 0; i<n; i++)
	{
		xs[i] = input.nextInt();
		ys[i] = input.nextInt();
	}
	long lo = 0, hi = (long)1e15;
	long[][] g = new long[n][n];
	for(int i = 0; i<n; i++)
	{
		for(int j = 0; j<n; j++)
		{
			if(i != j) g[i][j] = as[i] - d*(Math.abs(xs[i] - xs[j]) + Math.abs(ys[i] - ys[j]));
		}
	}
	while(lo < hi - 1)
	{
		long mid = (lo+hi)/2;
		long[] ds = new long[n];
		Arrays.fill(ds, -1);
		ds[0] = mid;
		PriorityQueue<State> pq = new PriorityQueue<State>();
		pq.add(new State(0, ds[0]));
		while(!pq.isEmpty())
		{
			State at = pq.poll();
			//System.out.println(at.at+" "+at.v);
			if(at.v != ds[at.at]) continue;
			for(int i = 0; i<n; i++)
			{
				if(i == at.at) continue;
				long nv = g[at.at][i] + at.v;
				if(nv <= ds[i]) continue;
				ds[i] = nv;
				pq.add(new State(i, nv));
			}
		}
		if(ds[n-1] > -1) hi = mid;
		else lo = mid;
	}
	out.println(hi);
	out.close();
}
static class State implements Comparable<State>
{
	int at;
	long v;
	public State(int aa, long vv)
	{
		at = aa; v = vv;
	}
	@Override
	public int compareTo(State o) {
		// TODO Auto-generated method stub
		return Long.compare(o.v, v);
	}
}
public static class input {
	static BufferedReader reader;
	static StringTokenizer tokenizer;

	static void init(InputStream input) {
		reader = new BufferedReader(new InputStreamReader(input));
		tokenizer = new StringTokenizer("");
	}

	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens())
			tokenizer = new StringTokenizer(reader.readLine());
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	static long nextLong() throws IOException {
		return Long.parseLong(next());
	}
}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class YaroslavAndTime {
	static int n;
	static int d;
	static int [] clocks;
	static int [] x;
	static int [] y;
	static double [] distTo;
	static boolean [] visitado;
	public static void main(String[] args) throws IOException
	{
		// TODO Auto-generated method stub
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[]data = in.readLine().split(" ");
		n = Integer.parseInt(data[0]);
		d = Integer.parseInt(data[1]);
		data = in.readLine().split(" ");
		clocks = new int[n+1];
		for (int i = 2; i<=n-1; ++i)
		{
			clocks[i] = Integer.parseInt(data[i-2]);
		}
		x = new int[n+1];
		y = new int[n+1];
		for (int i = 1; i<=n; ++i)
		{
			data = in.readLine().split(" ");
			x[i] = Integer.parseInt(data[0]);
			y[i] = Integer.parseInt(data[1]);
		}

		distTo = new double[n+1];
		Arrays.fill(distTo, Integer.MAX_VALUE/2-1);
		visitado = new boolean[n+1];
		visitado[0] = true;

		distTo[1] = 0;
		int indexMin;
		while((indexMin = indexOfMin())!=-1)
		{
			for (int i = 1; i<=n; ++i)
			{
				if (!visitado[i] && distTo[i]>distTo[indexMin]+distBetween(indexMin,i))
				{
					distTo[i]=distTo[indexMin]+distBetween(indexMin,i);
				}
			}
		}

		System.out.println((int)distTo[n]);

	}

	public static double distBetween(int i, int j)
	{
		return d*(Math.abs(x[i]-x[j])+Math.abs(y[i]-y[j])) -clocks[j];
	}

	public static int indexOfMin()
	{
		double min = Double.MAX_VALUE;
		int index = -1;
		for (int i = 0; i<distTo.length; ++i)
			if(!visitado[i] && distTo[i]<min)
			{
				min = distTo[i];
				index = i;
			}
		if(index ==Integer.MAX_VALUE/2-1) index = -1;
		if(index!=-1)
		{
			clocks[index] = 0;
			visitado[index] = true;
		}
		return index;
	}

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Solution  {

	static class FastScanner{
		BufferedReader s;
		StringTokenizer st;

		public FastScanner(){
			st = new StringTokenizer("");
			s = new BufferedReader(new InputStreamReader(System.in));
		}

		public FastScanner(File f) throws FileNotFoundException{
			st = new StringTokenizer("");
			s = new BufferedReader (new FileReader(f));
		}

		public int nextInt() throws IOException{
			if(st.hasMoreTokens())
				return Integer.parseInt(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextInt();
			}
		}

		public double nextDouble() throws IOException{
			if(st.hasMoreTokens())
				return Double.parseDouble(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextDouble();
			}
		}

		public long nextLong() throws IOException{
			if(st.hasMoreTokens())
				return Long.parseLong(st.nextToken());
			else{
				st = new StringTokenizer(s.readLine());
				return nextLong();
			}
		}

		public String nextString() throws IOException{
			if(st.hasMoreTokens())
				return st.nextToken();
			else{
				st = new StringTokenizer(s.readLine());
				return nextString();
			}

		}
		public String readLine() throws IOException{
			return s.readLine();
		}

		public void close() throws IOException{
			s.close();
		}

	}

	//FastScanner s = new FastScanner(new File("input.txt"));       copy inside void solve
    //PrintWriter ww = new PrintWriter(new FileWriter("output.txt"));
    static FastScanner s = new FastScanner();
    static PrintWriter ww = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String args[])throws IOException{
    	//Main ob=new Main();
    	Solution ob=new Solution();
		ob.solve();
			ww.close();
    }
    ///////////////////////////////////2 10 1
    class node{
    	private int x;
    	private int y;
    	public node(int x,int y){
    		this.x=x;
    		this.y=y;
    	}
    }

    /////////////////////////////////////////////
    void solve() throws IOException {
    	int n=s.nextInt();
    	int d=s.nextInt();
    	int a[]=new int [n];
    	a[0]=0;
    	a[n-1]=0;
    	for(int i=1;i<n-1;i++)
    		a[i]=s.nextInt();

    	node[] dis=new node[n];
    	for(int i=0;i<n;i++){
    		dis[i]=new node(s.nextInt(),s.nextInt());
    	}

    	int dp[][]=new int[n][n];
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			if(i==j)
    				continue;
    			dp[i][j]=(Math.abs(dis[i].x-dis[j].x)+Math.abs(dis[i].y-dis[j].y))*d-a[j];
    		}
    	}

    	  for (int k = 0; k < n; k++) {
              for (int i = 0; i < n; i++) {
                  for (int j = 0; j < n; j++) {
                      if (dp[i][j] > dp[i][k] + dp[k][j]) {
                          dp[i][j] = dp[i][k] + dp[k][j];
                      }
                  }
              }
          }

    	  ww.println(dp[0][n-1]);

    } //solve
}//Solution


import java.io.*;
import java.util.*;

public class Main {
	static PrintWriter out = new PrintWriter(new BufferedWriter(
			new OutputStreamWriter(System.out)));

	public static void main(String[] args) throws IOException {

		Scan scan = new Scan();
		int n = scan.nextInt();
		int d = scan.nextInt();
		int get[] = new int[n];
		get[0] = get[n - 1] = 0;
		for (int i = 1; i < n - 1; i++) {
			get[i] = scan.nextInt();
		}
		// for(int i = 0;i<n;i++){
		// out.print(get[i]+" ");
		// }
		// out.println();
		p p[] = new p[n];
		for (int i = 0; i < n; i++) {
			p[i] = new p(scan.nextInt(), scan.nextInt());
		}

		int dis[][] = new int[n][n];
		for (int i = 0; i < n; i++) {
			Arrays.fill(dis[i], 1000000000);
		}
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				if (i == j)
					continue;
				dis[i][j] = abs(p[i].x - p[j].x) * d + abs(p[i].y - p[j].y) * d;
			}
		// for (int i = 0; i < n; i++) {
		// for (int j = 0; j < n; j++) {
		// out.print(dis[i][j] + " ");
		// }
		// out.println();
		// }
		for (int k = 0; k < n; k++) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					if (i == j || i == k || j == k)
						continue;
					dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j] - get[k]);
				}
			}
		}
		// for(int i = 0;i<n;i++){
		// for(int j = 0;j<n;j++){
		// out.print(dis[i][j]+" ");
		// }
		// out.println();
		// }
		if (dis[0][n - 1] >= 0)
			out.println(dis[0][n - 1]);
		else
			out.println(0);
		out.flush();
		out.close();
	}

	public static int abs(int a) {
		if (a < 0)
			a = -a;
		return a;
	}

	public static class p {
		int x;
		int y;

		public p(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

	public static int min(int a, int b) {
		if (a < b)
			return a;
		return b;
	}
}

class Scan {

	BufferedReader buffer;
	StringTokenizer tok;

	Scan() {
		buffer = new BufferedReader(new InputStreamReader(System.in));
	}

	boolean hasNext() {
		while (tok == null || !tok.hasMoreElements()) {
			try {
				tok = new StringTokenizer(buffer.readLine());
			} catch (Exception e) {
				return false;
			}
		}
		return true;
	}

	String next() {
		if (hasNext())
			return tok.nextToken();
		return null;
	}

	String nextLine() {
		String s = null;
		try {
			s = buffer.readLine();
		} catch (Exception e) {
			return null;
		}
		return s;
	}

	char nextChar() {
		try {
			return ((char) buffer.read());
		} catch (Exception e) {
		}
		return '\0';
	}

	int nextInt() {
		return Integer.parseInt(next());
	}

	long nextLong() {
		return Long.parseLong(next());
	}

	double nextDouble() {
		return Double.parseDouble(next());
	}
}


import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	public static BufferedReader in;
	public static PrintWriter out;

	public static void main(String[] args) throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		boolean showLineError = true;
		if (showLineError) {
			solve();
			out.close();
		} else {
			try {
				solve();
			} catch (Exception e) {
			} finally {
				out.close();
			}
		}

	}

	static void debug(Object... os) {
		out.println(Arrays.deepToString(os));
	}

	private static void solve() throws IOException {
		String[] line = nss();
		int n = Integer.parseInt(line[0]);
		int d = Integer.parseInt(line[1]);
		line = nss();
		int[] arr = new int[n];
		for(int i =1;i<n-1;i++)
			arr[i]= Integer.parseInt(line[i-1]);

		Point[] pos = new Point[n];
		for(int i =0;i<n;i++){
			line = nss();
			pos[i]= new Point(Integer.parseInt(line[0]),Integer.parseInt(line[1]));
		}
		int[][] g = new int[n][n];
		for(int i =0;i<n;i++)
			for(int j =0;j<n;j++)
				g[i][j]=d* (Math.abs(pos[i].x-pos[j].x) + Math.abs(pos[i].y-pos[j].y));
		int lo =-1;
		int hi = 500000000;
		while(lo+1<hi){
			int m = (lo+hi)/2;
			if(reach(g,arr,m)){
				hi =m;
			}else{
				lo=m;
			}
		}
		out.println(hi);
	}
	private static boolean reach(int[][] g, int[] arr, int buy) {
		int n = g.length;
		int[] ok = new int[n];
		Arrays.fill(ok, -1);
		ok[0]=buy;
		Queue<Integer> q = new LinkedList<Integer>();
		boolean[] inQueue = new boolean[n];
		inQueue[0]=true;
		q.add(0);
		while(!q.isEmpty()){
			int u = q.poll();
			inQueue[u]=false;
			for(int v=0;v<n;v++)
				if(u!=v && g[u][v]<=ok[u]){
					int next = ok[u]-g[u][v]+arr[v];
					if(next>ok[v]){
						ok[v]=next;
						if(!inQueue[v]){
							inQueue[v]=true;
							q.add(v);
						}
					}
				}
		}
		return ok[n-1]!=-1;
	}

	private static String[] nss() throws IOException{
		return in.readLine().split(" ");
	}
	private static int ni() throws NumberFormatException, IOException{
		return Integer.parseInt(in.readLine());
	}
}


import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	public static BufferedReader in;
	public static PrintWriter out;

	public static void main(String[] args) throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		boolean showLineError = true;
		if (showLineError) {
			solve();
			out.close();
		} else {
			try {
				solve();
			} catch (Exception e) {
			} finally {
				out.close();
			}
		}

	}

	static void debug(Object... os) {
		out.println(Arrays.deepToString(os));
	}

	private static void solve() throws IOException {
		String[] line = nss();
		int n = Integer.parseInt(line[0]);
		int d = Integer.parseInt(line[1]);
		line = nss();
		int[] arr = new int[n];
		for(int i =1;i<n-1;i++)
			arr[i]= Integer.parseInt(line[i-1]);

		Point[] pos = new Point[n];
		for(int i =0;i<n;i++){
			line = nss();
			pos[i]= new Point(Integer.parseInt(line[0]),Integer.parseInt(line[1]));
		}
		int[][] g = new int[n][n];
		for(int i =0;i<n;i++)
			for(int j =0;j<n;j++)
				g[i][j]=d* (Math.abs(pos[i].x-pos[j].x) + Math.abs(pos[i].y-pos[j].y));
		int lo =-1;
		int hi = 10000000;
		while(lo+1<hi){
			int m = (lo+hi)/2;
			if(reach(g,arr,m)){
				hi =m;
			}else{
				lo=m;
			}
		}
		out.println(hi);
	}
	private static boolean reach(int[][] g, int[] arr, int buy) {
		int n = g.length;
		int[] ok = new int[n];
		Arrays.fill(ok, -1);
		ok[0]=buy;
		Queue<Integer> q = new LinkedList<Integer>();
		boolean[] inQueue = new boolean[n];
		inQueue[0]=true;
		q.add(0);
		while(!q.isEmpty()){
			int u = q.poll();
			inQueue[u]=false;
			for(int v=0;v<n;v++)
				if(u!=v && g[u][v]<=ok[u]){
					int next = ok[u]-g[u][v]+arr[v];
					if(next>ok[v]){
						ok[v]=next;
						if(!inQueue[v]){
							inQueue[v]=true;
							q.add(v);
						}
					}
				}
		}
		return ok[n-1]!=-1;
	}

	private static String[] nss() throws IOException{
		return in.readLine().split(" ");
	}
	private static int ni() throws NumberFormatException, IOException{
		return Integer.parseInt(in.readLine());
	}
}


import static java.lang.Math.abs;

import java.io.*;
import java.util.*;

public class B {

    static void solve() throws IOException {
        int n = nextInt(), cost = nextInt();
        int[] gives = new int[n - 2];
        for (int i = 0; i < n - 2; i++) {
            gives[i] = nextInt();
        }
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        long[][] dist = new long[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    dist[i][j] = 0;
                    continue;
                }
                long d = abs(x[i] - x[j]) + abs(y[i] - y[j]);
                d *= cost;
                if (j > 0 && j < n - 1) {
                    d -= gives[j - 1];
                }
                dist[i][j] = d;
            }
        }
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                }
            }
        }

        long answer = dist[0][n-1];
        out.println(answer);

    }

    static BufferedReader br;
    static StringTokenizer st;
    static PrintWriter out;

    public static void main(String[] args) throws IOException {
        InputStream input = System.in;
        PrintStream output = System.out;
        File file = new File("b.in");
        if (file.exists() && file.canRead()) {
            input = new FileInputStream(file);
        }
        br = new BufferedReader(new InputStreamReader(input));
        out = new PrintWriter(output);
        solve();
        out.close();
    }

    static long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    static double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    static int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    static String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null) {
                return null;
            }
            st = new StringTokenizer(line);
        }
        return st.nextToken();
    }
}


import java.lang.reflect.Array;
import java.util.*;
public class Main {

	int n,d;
	int a[]=new int[105];
	int x[]=new int[105];
	int y[]=new int[105];
	int dist[][]=new int[105][105];
	public void init()
	{
		Scanner cin=new Scanner(System.in);
		n=cin.nextInt();
		d=cin.nextInt();
		for(int i=2;i<n;i++)
			a[i]=cin.nextInt();
		for(int i=1;i<=n;i++)
		{
			x[i]=cin.nextInt();
			y[i]=cin.nextInt();
		}
	}
	public void solve()
	{
		int i,j,k;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				dist[i][j]=i==j?0:(Math.abs(x[i]-x[j])+Math.abs(y[i]-y[j]))*d-a[i];
		for(k=1;k<=n;k++)
			for(i=1;i<=n;i++)
				for(j=1;j<=n;j++)
					dist[i][j]=Math.min(dist[i][j], dist[i][k]+dist[k][j]);
		System.out.println(dist[1][n]);
	}

	public Main()
	{
		init();
		solve();
	}
	public static void main(String []args){
		new Main();
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 4 4
 * 1 5 3 4
 * 1 2
 * 1 3
 * 2 3
 * 3 3
 *
 *
 * @author pttrung
 */
public class A {

    public static long Mod = (long) (1e9) + 7;
    public static long[] dp;
    static int time = 1;

    public static void main(String[] args) throws FileNotFoundException {

        //PrintWriter out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        long d = in.nextInt();
        int[] data = new int[n - 2];
        dp = new long[n];
        Arrays.fill(dp, -1);
        for (int i = 0; i < n - 2; i++) {
            data[i] = in.nextInt();
        }
        Entry[] en = new Entry[n];
        for (int i = 0; i < n; i++) {
            en[i] = new Entry(in.nextInt(), in.nextInt(), 0);
            if (i != 0 && i != n - 1) {
                en[i].c = data[i - 1];
            }
        }
        long[][] map = new long[n][n];
        for (long[] a : map) {
            Arrays.fill(a, Long.MAX_VALUE);
        }
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    long tmp = d*(Math.abs(en[i].x - en[k].x) + Math.abs(en[i].y - en[k].y)) - en[k].c + d*(Math.abs(en[k].x - en[j].x) + Math.abs(en[k].y - en[j].y)) - en[j].c;
                    if (map[i][j] > tmp) {
                        map[i][j] = tmp;
                    }
                }
            }
        }
//        for(int i = 0; i < n; i++ ){
//            for(int j = 0; j < n; j++){
//                out.println(i + " " + j + " " + map[i][j]);
//            }
//        }
        out.println(map[0][n - 1]);
        out.close();

    }

    static long cal(int index, int end, int pa, long d, Entry[] e) {
        if (index == end) {
            return 0;
        }
        if (dp[index] != -1) {
            return dp[index];
        }
        long result = Integer.MAX_VALUE;
        int dist = Integer.MAX_VALUE;
        for (int i = 0; i < e.length; i++) {
        }
        return dp[index] = result;
    }

    static class Entry {

        int x, y;
        long c;

        public Entry(int x, int y, int c) {
            this.x = x;
            this.y = y;
            this.c = c;
        }

        @Override
        public String toString() {
            return "Entry{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static int find(int index, int[] u) {
        if (index != u[index]) {
            return u[index] = find(u[index], u);
        }
        return index;
    }

    public static long pow(int a, int b, long mod) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long v = pow(a, b / 2, mod);
        if (b % 2 == 0) {
            return (v * v) % mod;
        } else {
            return (((v * v) % mod) * a) % mod;
        }
    }

    public static int[][] powSquareMatrix(int[][] A, long p) {
        int[][] unit = new int[A.length][A.length];
        for (int i = 0; i < unit.length; i++) {
            unit[i][i] = 1;
        }
        if (p == 0) {
            return unit;
        }
        int[][] val = powSquareMatrix(A, p / 2);
        if (p % 2 == 0) {
            return mulMatrix(val, val);
        } else {
            return mulMatrix(A, mulMatrix(val, val));
        }

    }

    public static int[][] mulMatrix(int[][] A, int[][] B) {
        int[][] result = new int[A.length][B[0].length];
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                long temp = 0;
                for (int k = 0; k < A[0].length; k++) {

                    temp += ((long) A[i][k] * B[k][j] % Mod);
                    temp %= Mod;
                }
                temp %= Mod;
                result[i][j] = (int) temp;
            }
        }

        return result;
    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;

    }

    static class FT {

        int[] data;

        FT(int n) {
            data = new int[n];
        }

        void update(int index, int val) {
            // System.out.println("UPDATE INDEX " + index);
            while (index < data.length) {
                data[index] += val;
                index += index & (-index);

                //    System.out.println("NEXT " +index);
            }
        }

        int get(int index) {
            //  System.out.println("GET INDEX " + index);
            int result = 0;
            while (index > 0) {
                result += data[index];
                index -= index & (-index);
                // System.out.println("BACK " + index);
            }
            return result;
        }
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {

            return val * val % Mod;
        } else {
            return (val * val % Mod) * a % Mod;
        }
    }

//    static Point intersect(Point a, Point b, Point c) {
//        double D = cross(a, b);
//        if (D != 0) {
//            return new Point(cross(c, b) / D, cross(a, c) / D);
//        }
//        return null;
//    }
//
//    static Point convert(Point a, double angle) {
//        double x = a.x * cos(angle) - a.y * sin(angle);
//        double y = a.x * sin(angle) + a.y * cos(angle);
//        return new Point(x, y);
//    }
    static Point minus(Point a, Point b) {
        return new Point(a.x - b.x, a.y - b.y);
    }
//
//    static Point add(Point a, Point b) {
//        return new Point(a.x + b.x, a.y + b.y);
//    }
//

    /**
     * Cross product ab*ac
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static double cross(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return cross(ab, ac);
    }

    static double cross(Point a, Point b) {
        return a.x * b.y - a.y * b.x;
    }

    /**
     * Dot product ab*ac;
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static long dot(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return dot(ab, ac);
    }

    static long dot(Point a, Point b) {
        long total = a.x * b.x;
        total += a.y * b.y;
        return total;
    }

    static double dist(Point a, Point b) {
        long total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return Math.sqrt(total);
    }

    static long norm(Point a) {
        long result = a.x * a.x;
        result += a.y * a.y;
        return result;
    }

    static double dist(Point a, Point b, Point x, boolean isSegment) {
        double dist = cross(a, b, x) / dist(a, b);
        // System.out.println("DIST " + dist);

        if (isSegment) {
            Point ab = new Point(b.x - a.x, b.y - a.y);

            long dot1 = dot(a, b, x);
            long norm = norm(ab);
            double u = (double) dot1 / norm;
            if (u < 0) {
                return dist(a, x);
            }

            if (u > 1) {
                return dist(b, x);
            }
        }
        return Math.abs(dist);

    }

    static long squareDist(Point a, Point b) {
        long x = a.x - b.x;
        long y = a.y - b.y;
        return x * x + y * y;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            //System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //br = new BufferedReader(new FileReader(new File("A-large (2).in")));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 4 4
 * 1 5 3 4
 * 1 2
 * 1 3
 * 2 3
 * 3 3
 *
 *
 * @author pttrung
 */
public class A {

    public static long Mod = (long) (1e9) + 7;
    public static long[] dp;
    static int time = 1;

    public static void main(String[] args) throws FileNotFoundException {

        //PrintWriter out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        long d = in.nextInt();
        int[] data = new int[n - 2];
        dp = new long[n];
        Arrays.fill(dp, -1);
        for (int i = 0; i < n - 2; i++) {
            data[i] = in.nextInt();
        }
        Entry[] en = new Entry[n];
        for (int i = 0; i < n; i++) {
            en[i] = new Entry(in.nextInt(), in.nextInt(), 0);
            if (i != 0 && i != n - 1) {
                en[i].c = data[i - 1];
            }
        }
        Entry s = en[0];
        Entry e = en[n - 1];
        Arrays.sort(en, new Comparator<Entry>() {
            @Override
            public int compare(Entry o1, Entry o2) {
                if (o1.x != o2.x) {
                    return o1.x - o2.x;
                } else {
                    return o1.y - o2.y;
                }
            }
        });
        int start = -1;
        int end = -1;
        for (int i = 0; i < n; i++) {
            if (s == en[i]) {
                start = i;
            }
            if (e == en[i]) {
                end = i;
            }
        }
     //   System.out.println(start + " " + end);
        long result = cal(start, end, d, en);
        out.println(result);
        out.close();

    }

    static long cal(int index, int end, long d, Entry[] e) {
        if (index == end) {
            return 0;
        }
        if (dp[index] != -1) {
            return dp[index];
        }
        long result = Integer.MAX_VALUE;
        int add = 1;
        if (index > end) {
            add = -1;
        }
        for (int i = index + add;; i += add) {
            long tmp = Math.abs(e[index].x - e[i].x) + Math.abs(e[index].y - e[i].y);
            tmp *= d;
            tmp -= e[i].c;
          //  System.out.println(tmp + " " + e[index] + " " + e[i]);
            tmp += cal(i, end, d, e);
            if (result > tmp) {
                result = tmp;
            }
            if(i == end){
                break;
            }
        }
        return dp[index] = result;
    }

    static class Entry {

        int x, y;
        long c;

        public Entry(int x, int y, int c) {
            this.x = x;
            this.y = y;
            this.c = c;
        }

        @Override
        public String toString() {
            return "Entry{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static int find(int index, int[] u) {
        if (index != u[index]) {
            return u[index] = find(u[index], u);
        }
        return index;
    }

    public static long pow(int a, int b, long mod) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long v = pow(a, b / 2, mod);
        if (b % 2 == 0) {
            return (v * v) % mod;
        } else {
            return (((v * v) % mod) * a) % mod;
        }
    }

    public static int[][] powSquareMatrix(int[][] A, long p) {
        int[][] unit = new int[A.length][A.length];
        for (int i = 0; i < unit.length; i++) {
            unit[i][i] = 1;
        }
        if (p == 0) {
            return unit;
        }
        int[][] val = powSquareMatrix(A, p / 2);
        if (p % 2 == 0) {
            return mulMatrix(val, val);
        } else {
            return mulMatrix(A, mulMatrix(val, val));
        }

    }

    public static int[][] mulMatrix(int[][] A, int[][] B) {
        int[][] result = new int[A.length][B[0].length];
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                long temp = 0;
                for (int k = 0; k < A[0].length; k++) {

                    temp += ((long) A[i][k] * B[k][j] % Mod);
                    temp %= Mod;
                }
                temp %= Mod;
                result[i][j] = (int) temp;
            }
        }

        return result;
    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;

    }

    static class FT {

        int[] data;

        FT(int n) {
            data = new int[n];
        }

        void update(int index, int val) {
            // System.out.println("UPDATE INDEX " + index);
            while (index < data.length) {
                data[index] += val;
                index += index & (-index);

                //    System.out.println("NEXT " +index);
            }
        }

        int get(int index) {
            //  System.out.println("GET INDEX " + index);
            int result = 0;
            while (index > 0) {
                result += data[index];
                index -= index & (-index);
                // System.out.println("BACK " + index);
            }
            return result;
        }
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {

            return val * val % Mod;
        } else {
            return (val * val % Mod) * a % Mod;
        }
    }

//    static Point intersect(Point a, Point b, Point c) {
//        double D = cross(a, b);
//        if (D != 0) {
//            return new Point(cross(c, b) / D, cross(a, c) / D);
//        }
//        return null;
//    }
//
//    static Point convert(Point a, double angle) {
//        double x = a.x * cos(angle) - a.y * sin(angle);
//        double y = a.x * sin(angle) + a.y * cos(angle);
//        return new Point(x, y);
//    }
    static Point minus(Point a, Point b) {
        return new Point(a.x - b.x, a.y - b.y);
    }
//
//    static Point add(Point a, Point b) {
//        return new Point(a.x + b.x, a.y + b.y);
//    }
//

    /**
     * Cross product ab*ac
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static double cross(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return cross(ab, ac);
    }

    static double cross(Point a, Point b) {
        return a.x * b.y - a.y * b.x;
    }

    /**
     * Dot product ab*ac;
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static long dot(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return dot(ab, ac);
    }

    static long dot(Point a, Point b) {
        long total = a.x * b.x;
        total += a.y * b.y;
        return total;
    }

    static double dist(Point a, Point b) {
        long total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return Math.sqrt(total);
    }

    static long norm(Point a) {
        long result = a.x * a.x;
        result += a.y * a.y;
        return result;
    }

    static double dist(Point a, Point b, Point x, boolean isSegment) {
        double dist = cross(a, b, x) / dist(a, b);
        // System.out.println("DIST " + dist);

        if (isSegment) {
            Point ab = new Point(b.x - a.x, b.y - a.y);

            long dot1 = dot(a, b, x);
            long norm = norm(ab);
            double u = (double) dot1 / norm;
            if (u < 0) {
                return dist(a, x);
            }

            if (u > 1) {
                return dist(b, x);
            }
        }
        return Math.abs(dist);

    }

    static long squareDist(Point a, Point b) {
        long x = a.x - b.x;
        long y = a.y - b.y;
        return x * x + y * y;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            //System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //br = new BufferedReader(new FileReader(new File("A-large (2).in")));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 4 4
 * 1 5 3 4
 * 1 2
 * 1 3
 * 2 3
 * 3 3
 *
 *
 * @author pttrung
 */
public class A {

    public static long Mod = (long) (1e9) + 7;
    static int time = 1;
    static long[]dp;

    public static void main(String[] args) throws FileNotFoundException {

        //PrintWriter out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        final long d = in.nextInt();
        int[] data = new int[n - 2];

        for (int i = 0; i < n - 2; i++) {
            data[i] = in.nextInt();
        }
        dp = new long[n];
        Arrays.fill(dp,-1);
        Entry[] en = new Entry[n];
        for (int i = 0; i < n; i++) {
            en[i] = new Entry(in.nextInt(), in.nextInt(), 0);
            if (i != 0 && i != n - 1) {
                en[i].c = data[i - 1];
            }
        }
        Entry s = en[0];
        final Entry e = en[n - 1];
        Arrays.sort(en, new Comparator<Entry>() {
            @Override
            public int compare(Entry o1, Entry o2) {
                long a = Math.abs(o1.x - e.x) + Math.abs(o1.y - e.y);
                a = a * d - o1.c;
                long b = Math.abs(o2.x - e.x) + Math.abs(o2.y - e.y);
                b = b * d - o2.c;
                if (a != b) {
                    return Long.compare(a, b);
                } else {
                    if (e == o1) {
                        return -1;
                    } else if (e == o2) {
                        return 1;
                    }else{
                        return 0;
                    }
                }
            }
        });

        int start = -1;
        int end = -1;
        for (int i = 0; i < n; i++) {
            if (en[i] == s) {
                start = i;
            }
            if (en[i] == e) {
                end = i;
            }
        }
       // System.out.println(start + " " + end);
        long result = cal(end, start, d, en);
        out.println(result);
        out.close();

    }

    static long cal(int index, int end, long d, Entry[] e) {
        if (index == end) {
            return 0;
        }
        if(dp[index] != -1){
            return dp[index];
        }
        long result = Long.MAX_VALUE;
        for (int i = index + 1; i <= end; i++) {
            long tmp = d * (long) (Math.abs(e[index].x - e[i].x) + Math.abs(e[index].y - e[i].y)) - e[i].c;
            tmp += cal(i, end, d, e);
            if (tmp < result) {
                result = tmp;
            }
        }
        return dp[index] = result;
    }

    static class Entry {

        int x, y;
        long c;

        public Entry(int x, int y, int c) {
            this.x = x;
            this.y = y;
            this.c = c;
        }

        @Override
        public String toString() {
            return "Entry{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static int find(int index, int[] u) {
        if (index != u[index]) {
            return u[index] = find(u[index], u);
        }
        return index;
    }

    public static long pow(int a, int b, long mod) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long v = pow(a, b / 2, mod);
        if (b % 2 == 0) {
            return (v * v) % mod;
        } else {
            return (((v * v) % mod) * a) % mod;
        }
    }

    public static int[][] powSquareMatrix(int[][] A, long p) {
        int[][] unit = new int[A.length][A.length];
        for (int i = 0; i < unit.length; i++) {
            unit[i][i] = 1;
        }
        if (p == 0) {
            return unit;
        }
        int[][] val = powSquareMatrix(A, p / 2);
        if (p % 2 == 0) {
            return mulMatrix(val, val);
        } else {
            return mulMatrix(A, mulMatrix(val, val));
        }

    }

    public static int[][] mulMatrix(int[][] A, int[][] B) {
        int[][] result = new int[A.length][B[0].length];
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                long temp = 0;
                for (int k = 0; k < A[0].length; k++) {

                    temp += ((long) A[i][k] * B[k][j] % Mod);
                    temp %= Mod;
                }
                temp %= Mod;
                result[i][j] = (int) temp;
            }
        }

        return result;
    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;

    }

    static class FT {

        int[] data;

        FT(int n) {
            data = new int[n];
        }

        void update(int index, int val) {
            // System.out.println("UPDATE INDEX " + index);
            while (index < data.length) {
                data[index] += val;
                index += index & (-index);

                //    System.out.println("NEXT " +index);
            }
        }

        int get(int index) {
            //  System.out.println("GET INDEX " + index);
            int result = 0;
            while (index > 0) {
                result += data[index];
                index -= index & (-index);
                // System.out.println("BACK " + index);
            }
            return result;
        }
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {

            return val * val % Mod;
        } else {
            return (val * val % Mod) * a % Mod;
        }
    }

//    static Point intersect(Point a, Point b, Point c) {
//        double D = cross(a, b);
//        if (D != 0) {
//            return new Point(cross(c, b) / D, cross(a, c) / D);
//        }
//        return null;
//    }
//
//    static Point convert(Point a, double angle) {
//        double x = a.x * cos(angle) - a.y * sin(angle);
//        double y = a.x * sin(angle) + a.y * cos(angle);
//        return new Point(x, y);
//    }
    static Point minus(Point a, Point b) {
        return new Point(a.x - b.x, a.y - b.y);
    }
//
//    static Point add(Point a, Point b) {
//        return new Point(a.x + b.x, a.y + b.y);
//    }
//

    /**
     * Cross product ab*ac
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static double cross(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return cross(ab, ac);
    }

    static double cross(Point a, Point b) {
        return a.x * b.y - a.y * b.x;
    }

    /**
     * Dot product ab*ac;
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static long dot(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return dot(ab, ac);
    }

    static long dot(Point a, Point b) {
        long total = a.x * b.x;
        total += a.y * b.y;
        return total;
    }

    static double dist(Point a, Point b) {
        long total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return Math.sqrt(total);
    }

    static long norm(Point a) {
        long result = a.x * a.x;
        result += a.y * a.y;
        return result;
    }

    static double dist(Point a, Point b, Point x, boolean isSegment) {
        double dist = cross(a, b, x) / dist(a, b);
        // System.out.println("DIST " + dist);

        if (isSegment) {
            Point ab = new Point(b.x - a.x, b.y - a.y);

            long dot1 = dot(a, b, x);
            long norm = norm(ab);
            double u = (double) dot1 / norm;
            if (u < 0) {
                return dist(a, x);
            }

            if (u > 1) {
                return dist(b, x);
            }
        }
        return Math.abs(dist);

    }

    static long squareDist(Point a, Point b) {
        long x = a.x - b.x;
        long y = a.y - b.y;
        return x * x + y * y;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            //System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //br = new BufferedReader(new FileReader(new File("A-large (2).in")));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * 4 4
 * 1 5 3 4
 * 1 2
 * 1 3
 * 2 3
 * 3 3
 *
 *
 * @author pttrung
 */
public class A {

    public static long Mod = (long) (1e9) + 7;
    public static long[][] dp;
    static int time = 1;

    public static void main(String[] args) throws FileNotFoundException {

        //PrintWriter out = new PrintWriter(new FileOutputStream(new File("output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        int d = in.nextInt();
        int[] data = new int[n - 2];
        for (int i = 0; i < n - 2; i++) {
            data[i] = in.nextInt();
        }
        Point[] p = new Point[n];
        for (int i = 0; i < n; i++) {
            p[i] = new Point(in.nextInt(), in.nextInt());
        }
        int[][] map = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int dist = Math.abs(p[i].x - p[j].x) + Math.abs(p[i].y - p[j].y);
                map[i][j] = dist;
                map[j][i] = dist;
             //   System.out.println(i + " " + j + " " + map[i][j]);
            }
        }
        int[] dist = new int[n];
        PriorityQueue<Point> q = new PriorityQueue(n, new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
                return o1.y - o2.y;
            }
        });
        Arrays.fill(dist, Integer.MAX_VALUE);
        q.add(new Point(0, 0));
        dist[0] = 0;
        boolean[]check = new boolean[n];
        while (!q.isEmpty()) {
            Point t = q.poll();
            if (!check[t.x]) {
                check[t.x] = true;
               // System.out.println(t);
                for (int i = 0; i < n; i++) {
                    if(check[i]){
                        continue;
                    }
                    int tmp = map[t.x][i] * d;
                    if (i != 0 && i != n - 1) {
                        tmp -= data[i - 1];
                    }
                    if (dist[i] > tmp) {
                        dist[i] = tmp;
                        q.add(new Point(i, dist[i]));
                    }
                }
            }
        }
        //System.out.println(Arrays.toString(dist));
        out.println(dist[n - 1]);
        out.close();

    }

    static long[] cal(int p) {
        if (p == 0) {
            return new long[]{0, 1};
        } else if (p == 1) {
            return new long[]{1, 0};
        } else if (p == 2) {
            return new long[]{1, 1};
        }
        if (dp[p][0] != -1) {
            return dp[p];
        }
        long[] result = new long[2];
        long[] tmp = cal(p - 2);
        result[0] = tmp[0] + tmp[1];

        result[1] = tmp[1];
        result[0] += tmp[0];
        result[1] += tmp[0];
        return dp[p] = result;
    }

    static int find(int index, int[] u) {
        if (index != u[index]) {
            return u[index] = find(u[index], u);
        }
        return index;
    }

    public static long pow(int a, int b, long mod) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long v = pow(a, b / 2, mod);
        if (b % 2 == 0) {
            return (v * v) % mod;
        } else {
            return (((v * v) % mod) * a) % mod;
        }
    }

    public static int[][] powSquareMatrix(int[][] A, long p) {
        int[][] unit = new int[A.length][A.length];
        for (int i = 0; i < unit.length; i++) {
            unit[i][i] = 1;
        }
        if (p == 0) {
            return unit;
        }
        int[][] val = powSquareMatrix(A, p / 2);
        if (p % 2 == 0) {
            return mulMatrix(val, val);
        } else {
            return mulMatrix(A, mulMatrix(val, val));
        }

    }

    public static int[][] mulMatrix(int[][] A, int[][] B) {
        int[][] result = new int[A.length][B[0].length];
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                long temp = 0;
                for (int k = 0; k < A[0].length; k++) {

                    temp += ((long) A[i][k] * B[k][j] % Mod);
                    temp %= Mod;
                }
                temp %= Mod;
                result[i][j] = (int) temp;
            }
        }

        return result;
    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;

    }

    static class FT {

        int[] data;

        FT(int n) {
            data = new int[n];
        }

        void update(int index, int val) {
            // System.out.println("UPDATE INDEX " + index);
            while (index < data.length) {
                data[index] += val;
                index += index & (-index);

                //    System.out.println("NEXT " +index);
            }
        }

        int get(int index) {
            //  System.out.println("GET INDEX " + index);
            int result = 0;
            while (index > 0) {
                result += data[index];
                index -= index & (-index);
                // System.out.println("BACK " + index);
            }
            return result;
        }
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2);
        if (b % 2 == 0) {

            return val * val % Mod;
        } else {
            return (val * val % Mod) * a % Mod;
        }
    }

//    static Point intersect(Point a, Point b, Point c) {
//        double D = cross(a, b);
//        if (D != 0) {
//            return new Point(cross(c, b) / D, cross(a, c) / D);
//        }
//        return null;
//    }
//
//    static Point convert(Point a, double angle) {
//        double x = a.x * cos(angle) - a.y * sin(angle);
//        double y = a.x * sin(angle) + a.y * cos(angle);
//        return new Point(x, y);
//    }
    static Point minus(Point a, Point b) {
        return new Point(a.x - b.x, a.y - b.y);
    }
//
//    static Point add(Point a, Point b) {
//        return new Point(a.x + b.x, a.y + b.y);
//    }
//

    /**
     * Cross product ab*ac
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static double cross(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return cross(ab, ac);
    }

    static double cross(Point a, Point b) {
        return a.x * b.y - a.y * b.x;
    }

    /**
     * Dot product ab*ac;
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    static long dot(Point a, Point b, Point c) {
        Point ab = new Point(b.x - a.x, b.y - a.y);
        Point ac = new Point(c.x - a.x, c.y - a.y);
        return dot(ab, ac);
    }

    static long dot(Point a, Point b) {
        long total = a.x * b.x;
        total += a.y * b.y;
        return total;
    }

    static double dist(Point a, Point b) {
        long total = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
        return Math.sqrt(total);
    }

    static long norm(Point a) {
        long result = a.x * a.x;
        result += a.y * a.y;
        return result;
    }

    static double dist(Point a, Point b, Point x, boolean isSegment) {
        double dist = cross(a, b, x) / dist(a, b);
        // System.out.println("DIST " + dist);

        if (isSegment) {
            Point ab = new Point(b.x - a.x, b.y - a.y);

            long dot1 = dot(a, b, x);
            long norm = norm(ab);
            double u = (double) dot1 / norm;
            if (u < 0) {
                return dist(a, x);
            }

            if (u > 1) {
                return dist(b, x);
            }
        }
        return Math.abs(dist);

    }

    static long squareDist(Point a, Point b) {
        long x = a.x - b.x;
        long y = a.y - b.y;
        return x * x + y * y;
    }

    static class Point {

        int x, y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point{" + "x=" + x + ", y=" + y + '}';
        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            //System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //br = new BufferedReader(new FileReader(new File("A-large (2).in")));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}