#include <iostream>
#include <vector>
#include <queue>
#define MAXK 15
#define MAXN 2000
#define MAXDIST 200000000
#define MAXMASK 131072
using namespace std;
///citirea lui Cristian Francu
#define MAXLOG10 10
#define BUFSIZE (128 * 1024)
FILE *fin, *fout;
int p10[MAXLOG10 + 1] = { 0, 1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000 }; // santinela pe prima pozitie
int rpos; char rbuf[BUFSIZE];
int wpos; char wbuf[BUFSIZE];
// initializare citire
static inline void initRead() {
rpos = BUFSIZE - 1;
}
// citire caracter
static inline char readChar() {
if ( !(rpos = (rpos + 1) & (BUFSIZE - 1)) )
fread( rbuf, 1, BUFSIZE, fin );
return rbuf[rpos];
}
// citire intreg cu semn
int readInt() { // citeste un intreg
int ch, res = 0, semn = 1;
while ( isspace( ch = readChar() ) );
if ( ch == '-' ) {
semn = -1;
ch = readChar();
}
do
res = 10 * res + ch - '0';
while ( isdigit( ch = readChar() ) );
return semn * res;
}
struct edge{
int b, cost;
};
struct node{
int dist;
bool visited;
vector <edge> neighbours;
};
///am schimbat semnul la operator :))
bool operator<(edge a, edge b) {
return a.cost > b.cost;
}
priority_queue <edge> pq;
node graph[MAXN];
node graphWithGoodPos[MAXK];
int valuablePos[MAXK + 2];
long long dp[MAXK + 2][MAXMASK];
void addEdge(int a, int b, int cost) {
graph[a].neighbours.push_back({b, cost});
graph[b].neighbours.push_back({a, cost});
}
void addEdgeInGraphWithGoodPos(int a, int b, int cost) {
graphWithGoodPos[a].neighbours.push_back({b, cost});
graphWithGoodPos[b].neighbours.push_back({a, cost});
}
void dijkstra(int startPos, int n) {
int i;
edge pos;
for ( i = 0; i < n; i++ ) {
graph[i].dist = MAXDIST;
}
graph[startPos].dist = 0;
for ( edge i2 : graph[startPos].neighbours ) {
pq.push(i2);
graph[i2.b].dist = i2.cost;
}
while ( !pq.empty() ) {
pos = pq.top();
pq.pop();
if ( graph[pos.b].dist == pos.cost ) {
graph[pos.b].dist = pos.cost;
for ( edge i2 : graph[pos.b].neighbours ) {
if ( pos.cost + i2.cost < graph[i2.b].dist ) {
graph[i2.b].dist = pos.cost + i2.cost;
pq.push({i2.b, pos.cost + i2.cost});
}
}
}
}
}
int main() {
fin = fopen("ubuntzei.in", "r");
fout = fopen("ubuntzei.out", "w");
int n, m, k, i, a, b, cost, i2;
initRead();
n = readInt();
m = readInt();
k = readInt();
valuablePos[0] = 0;
for ( i = 1; i <= k; i++ ) {
valuablePos[i] = readInt();
valuablePos[i]--;
}
valuablePos[k + 1] = n - 1;
k += 2;
for ( i = 0; i < m; i++ ) {
a = readInt();
b = readInt();
cost = readInt();
a--;
b--;
addEdge(a, b, cost);
}
for ( i = 0; i < k; i++ ) {
dijkstra(valuablePos[i], n);
for ( i2 = i + 1; i2 < k; i2++ ) {
//printf("%d %d %d\n", valuablePos[i] + 1, valuablePos[i2] + 1, graph[valuablePos[i2]].dist);
addEdgeInGraphWithGoodPos(i, i2, graph[valuablePos[i2]].dist);
}
}
for ( i = 0; i < (1 << k); i++ ) {
for ( i2 = 0; i2 < k; i2++ ) {
dp[i2][i] = (long long) MAXDIST * (MAXK + 2) + 1;
}
}
dp[0][1] = 0;
for ( i = 1; i < (1 << k); i++ ) {
for ( i2 = 0; i2 < k; i2++ ) {
if ( i & (1 << i2) ) {
for ( edge i3 : graphWithGoodPos[i2].neighbours ) {
if ( i & (1 << i3.b) ) {
dp[i3.b][i] = min(dp[i3.b][i], (long long) dp[i2][i - (1 << i3.b)] + i3.cost);
}
}
}
}
}
fprintf(fout, "%lld\n", dp[k - 1][(1 << k) - 1]);
fclose(fin);
fclose(fout);
return 0;
}