Problem:
Score : 400 points

Problem Statement

There are N towns in the State of Atcoder, connected by M bidirectional roads.

The i-th road connects Town A_i and B_i and has a length of C_i.

Joisino is visiting R towns in the state, r_1,r_2,..,r_R (not necessarily in this order).

She will fly to the first town she visits, and fly back from the last town she visits, but for the rest of the trip she will have to travel by road.

If she visits the towns in the order that minimizes the distance traveled by road, what will that distance be?

Constraints

2≤N≤200

1≤M≤N×(N-1)/2

2≤R≤min(8,N) (min(8,N) is the smaller of 8 and N.)

r_i≠r_j (i≠j)

1≤A_i,B_i≤N, A_i≠B_i

(A_i,B_i)≠(A_j,B_j),(A_i,B_i)≠(B_j,A_j) (i≠j)

1≤C_i≤100000

Every town can be reached from every town by road.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N M R
r_1 ... r_R
A_1 B_1 C_1
:
A_M B_M C_M

Output

Print the distance traveled by road if Joisino visits the towns in the order that minimizes it.

Sample Input 1

3 3 3
1 2 3
1 2 1
2 3 1
3 1 4

Sample Output 1

2

For example, if she visits the towns in the order of 1, 2, 3, the distance traveled will be 2, which is the minimum possible.

Sample Input 2

3 3 2
1 3
2 3 2
1 3 6
1 2 2

Sample Output 2

4

The shortest distance between Towns 1 and 3 is 4. Thus, whether she visits Town 1 or 3 first, the distance traveled will be 4.

Sample Input 3

4 6 3
2 3 4
1 2 4
2 3 3
4 3 1
1 4 1
4 2 2
3 1 6

Sample Output 3

3

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Math;
using static System.Console;
using static CS_Contest.Utils;
using System.IO;
//using static CS_Contest.Library;

namespace CS_Contest {
	using Li = List<int>;
	using LLi = List<List<int>>;
	using Ls = List<string>;
	using Ll = List<long>;
	using LLl = List<List<long>>;
	class Program {
		static void Main(string[] args) {
			var sw = new StreamWriter(OpenStandardOutput()) { AutoFlush = false };
			SetOut(sw);
			new Calc().Solve();
			Out.Flush();
			return;
        }

		private class Calc {
			int[,] G;
			public void Solve() {
				int N, M, R;
				ReadMulti(out N, out M, out R);
				Li Root = ReadInt(' ');
				D Dijk = new D(N);
				REP(M, m => {
					int A, B, C;
					ReadMulti(out A, out B, out C);
					A--; B--;
					Dijk.Add(A, B, C);
				});
				int s=0, t=0;
				long dis = 0;
				while (Root.Count > 1) {
					long min = INF;
					for (int i = 0; i < Root.Count; i++) {
						for (int k = 0; k < Root.Count; k++) {
							if (i == k) continue;
							var d = Dijk.GetMinCost(Root[i] - 1, Root[k] - 1);
							if (d < min) {
								min = d;
								s = i; t = k;
							}
						}
					}
					Root.RemoveAt(s);
					dis += min;
				}
				
				dis.WL();
				return;
			}
			public class D {
				private int maxIndex = -1;
				private const int INF = int.MaxValue;

				private int[,] edge;
				public D(int size) {
					maxIndex = size + 1;
					edge = new int[maxIndex, maxIndex];
					REP(edge.GetLength(0), i => {
						REP(edge.GetLength(1), j => {
							edge[i, j] = INF;
							if (i == j) edge[i, j] = 0;
						});
					});
				}
				public void Add(int a,int b,int c) {
					edge[a, b] = Min(edge[a, b], c);
					edge[b, a] = edge[a, b];
				}
				public int GetMinCost(int s,int g) {
					int[] cost = new int[maxIndex];
					REP(maxIndex, i => cost[i] = INF);
					cost[s] = 0;

					var Q =new PriorityQueue<CPair<int, int>>();
					Q.Enqueue(new CPair<int, int>(0, s));

					while (Q.Count>0) {
						var costDP = Q.Dequeue();
						if (cost[costDP.Y] < costDP.X) continue;

						REP(maxIndex, i => {
							int ncost = edge[costDP.Y, i] == INF ? INF : costDP.X + edge[costDP.Y, i];
							if (ncost < cost[i]) {
								cost[i] = ncost;
								Q.Enqueue(new CPair<int, int>(ncost, i));
							}
						});
					}
					return cost[g];
				}


				public class CPair<T, U> : IComparable where T : IComparable<T> {
					public readonly T X;
					public readonly U Y;
					public int CompareTo(object obj) {
						var casted = (CPair<T, U>)obj;
						return this.X.CompareTo(casted.X);
					}
					public CPair(T t,U u) { X = t;Y = u; }
				}
			}
			
		}
	}


	public static class Utils {
		public static int ModValue = (int)(1000000007);
		public static long INF = long.MaxValue;
		public static long Mod(long x) => x % ModValue;
		public static long ModPow(long x, long n) { long tmp = 1; while (n != 0) { if (n % 2 == 1) { tmp = Mod(tmp * x); } x = Mod(x * x); n /= 2; } return tmp; }
		public static long DivMod(long x, long y) => Mod(x * ModPow(y, (long)(1e9 + 5)));
		public static void WL(this object obj) => WriteLine(obj);
		public static void WL(this string obj) => WriteLine(obj);
		public static void WL<T>(this IEnumerable<T> list) => list.ToList().ForEach(x => x.WL());
		public static int ReadInt() => int.Parse(ReadLine());
		public static List<int> ReadInt(char s) => ReadLine().Split(s).Where(x => x != "").Select(int.Parse).ToList();
		public static long ReadLong() => long.Parse(ReadLine());
		public static List<long> ReadLong(char s) => ReadLine().Split(s).Select(long.Parse).ToList();
		public static void ReadMulti(out int x, out int y) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1];

		}
		public static void ReadMulti(out long x, out long y) {
			var i = ReadLong(' ');
			x = i[0]; y = i[1];
		}
		public static void ReadMulti(out int x, out int y, out int z) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1]; z = i[2];
		}
		public static void ReadMulti(out int x, out int y, out int z, out int v) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1]; z = i[2]; v = i[3];
		}

		public static string StringJoin<T>(this IEnumerable<T> l, string separator) => string.Join(separator, l);

		public static long GCD(long m, long n) {
			long tmp;
			if (m < n) { tmp = n; n = m; m = tmp; }
			while (m % n != 0) {
				tmp = n;
				n = m % n;
				m = tmp;
			}
			return n;
		}
		public static long LCM(long m, long n) => m * (n / GCD(m, n));

		public static void REP(int n, Action<int> act) {
			for (int i = 0; i < n; i++) {
				act(i);
			}
		}
		public static void RREP(int n, Action<int> act) {
			for (int i = n - 1; i >= 0; i--) {
				act(i);
			}
		}
		public static void REP(long n, Action<int> act) => REP((int)n, act);
		public static void RREP(long n, Action<int> act) => RREP((int)n, act);

		public static void Yes() => "Yes".WL();
		public static void No() => "No".WL();
		public static void YES() => "YES".WL();
		public static void NO() => "NO".WL();


		public static int ManhattanDistance(int x1, int y1, int x2, int y2) => Abs(x2 - x1) + Abs(y2 - y1);


		public class Vector2 {
			public int X { get; set; }
			public int Y { get; set; }
			public Vector2() { X = 0; Y = 0; }
			public Vector2(int x, int y) { X = x; Y = y; }
			public int ManhattanDistance(Vector2 v2) {
				return Utils.ManhattanDistance(X, Y, v2.X, v2.Y);
			}
			public static int ManhattanDistance(Vector2 v1, Vector2 v2) => v2.ManhattanDistance(v2);
			public double Distance(Vector2 v2) => Sqrt(Pow(X - v2.X, 2) + Pow(Y - v2.Y, 2));
			public static Vector2 Zero { get { return new Vector2(); } }
			public void Clear() { X = 0; Y = 0; }
		}

		public struct IndexT<T> {
			public T Value { get; set; }
			public int Index { get; set; }
			public IndexT(T v,int i) { Value = v; Index = i; }
		}
		public static IEnumerable<IndexT<T>> ToIndexEnumerable<T>(this IEnumerable<T> list) => list.Select((x, i) => new IndexT<T>(x, i));

		public class PriorityQueue<T> {
			private readonly List<T> heap;
			private readonly Comparison<T> compare;
			private int size;
			public PriorityQueue() : this(Comparer<T>.Default) { }
			public PriorityQueue(IComparer<T> comparer) : this(16, comparer.Compare) { }
			public PriorityQueue(Comparison<T> comparison) : this(16, comparison) { }
			public PriorityQueue(int capacity, Comparison<T> comparison) {
				this.heap = new List<T>(capacity);
				this.compare = comparison;
			}
			public void Enqueue(T item) {
				this.heap.Add(item);
				var i = size++;
				while (i > 0) {
					var p = (i - 1) >> 1;
					if (compare(this.heap[p], item) <= 0)
						break;
					this.heap[i] = heap[p];
					i = p;
				}
				this.heap[i] = item;

			}
			public T Dequeue() {
				var ret = this.heap[0];
				var x = this.heap[--size];
				var i = 0;
				while ((i << 1) + 1 < size) {
					var a = (i << 1) + 1;
					var b = (i << 1) + 2;
					if (b < size && compare(heap[b], heap[a]) < 0) a = b;
					if (compare(heap[a], x) >= 0)
						break;
					heap[i] = heap[a];
					i = a;
				}
				heap[i] = x;
				heap.RemoveAt(size);
				return ret;
			}
			public T Peek() { return heap[0]; }
			public int Count { get { return size; } }
			public bool Any() { return size > 0; }
		}

		public static Tuple<TKey, TSource> ToTuple<TKey, TSource>(this KeyValuePair<TKey, TSource> kvp) => new Tuple<TKey, TSource>(kvp.Key, kvp.Value);
		public static IEnumerable<Tuple<TKey, TSource>> ToTupleList<TKey, TSource>(this Dictionary<TKey, TSource> d) => d.Select(_ => _.ToTuple());
	}
}