#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
#define inf 2000000000
struct sheap
{
int val,node;
};
bool operator < (sheap a,sheap b)
{
if (a.val<b.val)
return true;
return false;
}
//must do
void init(vector <sheap> &heap)
{
sheap ax;
ax.val=-inf;
ax.node=-1;
heap.push_back(ax);
}
bool safe(vector <sheap> &heap,int pos)
{
if (pos>=heap.size())
return false;
if (pos<=0)
return false;
return true;
}
void heapswap(vector <sheap> &heap,vector <int> &vpos,int pos1,int pos2)
{
sheap ax;
ax=heap[pos1];
heap[pos1]=heap[pos2];
heap[pos2]=ax;
int axi;
int node1,node2;
node1=heap[pos1].node;
node2=heap[pos2].node;
axi=vpos[node1];
vpos[node1]=vpos[node2];
vpos[node2]=axi;
}
void heapup(vector <sheap> &heap,vector <int> &vpos,int pos)
{
if (!safe(heap,pos))
return;
if (heap[pos]<heap[pos/2])
{
heapswap(heap,vpos,pos,pos/2);
heapup(heap,vpos,pos/2);
}
}
int heapmin(vector <sheap> &heap, int pos1, int pos2)
{
if (heap[pos1]<heap[pos2])
return pos1;
return pos2;
}
void heapdown(vector <sheap> &heap, vector <int> &vpos, int pos)
{
if (!safe(heap,pos*2))
return;
int posdown;
if (!safe(heap,pos*2+1))
posdown=pos*2;
else
posdown=heapmin(heap,pos*2,pos*2+1);
if (heap[posdown]<heap[pos])
{
heapswap(heap,vpos,posdown,pos);
heapdown(heap,vpos,posdown);
}
}
void heapinsert(vector <sheap> &heap,vector <int> &vpos,sheap val)
{
heap.push_back(val);
int pos=heap.size()-1;
vpos[val.node]=pos;
heapup(heap,vpos,pos);
}
//delete last one
void heapdelete(vector <sheap> &heap,vector <int> &vpos)
{
int pos=heap.size()-1;
sheap ax=heap[pos];
vpos[ax.node]=0;
heap.pop_back();
}
void heapdelete(vector <sheap> &heap,vector <int> &vpos,int pos)
{
if (!safe(heap,pos))
return;
int last=heap.size()-1;
heapswap(heap,vpos,pos,last);
heapdelete(heap,vpos);
if (!safe(heap,pos))
return;
heapup(heap,vpos,pos);
heapdown(heap,vpos,pos);
}
void heapupdate(vector <sheap> &heap, vector <int> &vpos, int pos, sheap arg)
{
heap[pos]=arg;
heapup(heap,vpos,pos);
heapdown(heap,vpos,pos);
}
class dijkstra
{
private:vector <sheap> heap;
private:vector <int> vpos;
public:vector <int> dist;
dijkstra(int nrnodes)
{
heap.clear();
vpos.clear();
dist.clear();
init(heap);
for (int i=0;i<nrnodes;i++)
{
vpos.push_back(0);
dist.push_back(inf);
}
}
bool add_or_update(sheap upd)
{
if (upd.node>=vpos.size())
return false;
if (upd.node<0)
return false;
int node=upd.node;
dist[node]=upd.val;
if (vpos[node]==0)
heapinsert(heap,vpos,upd);
else
heapupdate(heap,vpos,vpos[node],upd);
return true;
}
bool topdelete()
{
if (heap.size()<=1)
return false;
heapdelete(heap,vpos,1);
return true;
}
sheap top()
{
return heap[1];
}
bool empty()
{
if (heap.size()<=1)
return true;
return false;
}
};
////intermission////
#define maxn 20005
sheap axs;
int m,n,k,i,nr,a,b,c,now,dnow,to,dnowto,i1;
vector <int> orase;
vector <pair <int,int> > muchii[maxn];
int md[20][20];
int mymap[300000][20];
int go(int mask,int last)
{
int i;
if (mymap[mask][last]!=0)
return mymap[mask][last];
if (mask==0)
{
if (last==0)
return 0;
else
return inf;
}
int d=inf;
int axmask=0;
for (i=0;(1<<i)<=mask;i++)
{
if (i!=last)
if (((1<<i)&mask)!=0)
{
axmask=mask-(1<<i);
d=min(d,go(axmask,i)+md[i][last]);
}
}
mymap[mask][last]=d;
return d;
}
int main(void)
{
FILE * f;
f=fopen("ubuntzei.in","r");
ofstream g("ubuntzei.out");
fscanf(f,"%d%d%d",&n,&m,&k);
orase.push_back(1);
for (i=1;i<=k;i++)
{
fscanf(f,"%d",&nr);
orase.push_back(nr);
}
orase.push_back(n);
for (i=1;i<=m;i++)
{
fscanf(f,"%d%d%d",&a,&b,&c);
muchii[a].push_back(make_pair(b,c));
muchii[b].push_back(make_pair(a,c));
}
dijkstra d(n+1);
for (i=0;i<orase.size();i++)
{
d=dijkstra(n+1);
axs.node=orase[i];
axs.val=0;
d.add_or_update(axs);
while (!d.empty())
{
now=d.top().node;
dnow=d.top().val;
for (i1=0;i1<muchii[now].size();i1++)
{
to=muchii[now][i1].first;
dnowto=muchii[now][i1].second;
if (dnow+dnowto<d.dist[to])
{
axs.val=dnow+dnowto;
axs.node=to;
d.add_or_update(axs);
}
}
d.topdelete();
}
for (i1=0;i1<orase.size();i1++)
md[i][i1]=d.dist[orase[i1]];
}
k=k+2;
g<<go((1<<k)-1,k);
return 0;
}