#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define MAXN 1000+5
#define INF (int)1e9+5
#define DEBUG 1
using namespace std;
//int G[MAXN][MAXN] = {INF}; //图
//int COST[MAXN][MAXN] = {0}; //代价
int N=0,M;
int cost_d[MAXN] = {INF}; //距离数组
int cost_p[MAXN] = {0}; //花费数组
int vis[MAXN]={0};
struct Edge{
int u,v,d;
int uu,vv;//uu vv代表离散化后的节点序号
};
vector<Edge> vec_edges;
vector<int> Nodes;
vector<int> vec_Start;//存储相邻的城市
vector<int> vec_endd;//存储想去的地方
int T,S,D; //T代表边数,S代表有几个城市,D代表要去的几个地方
//vector 存储节点
/*
void init(){
memset(G,INF,sizeof(G));
memset(cost_d,INF,sizeof(cost_d));
memset(vis,0,sizeof(vis));
N=0;
vec_Start.clear();
vec_endd.clear();
}
void solve(){
int a,b,d;
while(scanf("%d %d %d",&T,&S,&D)==3){
init();
//先将边输入进来
for(int i=0;i<T;i++){
scanf("%d%d%d",&a,&b,&d);
Edge edge;
edge.u = a;
edge.v =b;
edge.d = d;
if(edge.d<G[a][b])
G[a][b] = G[b][a] = d;
N= max(max(a,b),N);
}
for(int i=0;i<S;i++){
int t1;
scanf("%d",&t1);
vec_Start.push_back(t1);
vis[t1] = 1;
cost_d[t1] = 0;
}
for(int i=0;i<D;i++){
int t1;
scanf("%d",&t1);
vec_endd.push_back(t1);
}
//首先将起始点初始化 即cost-d数组第一次
for(int i=1;i<=N;i++){
if(vis[i])
continue;
for(int j=0;j<vec_Start.size();j++){
if(G[vec_Start[j]][i]){
if(cost_d[i] >G[vec_Start[j]][i]){
cost_d[i] = G[vec_Start[j]][i];
}
}
}
}
//遍历剩下的节点
for(int i=1;i<N;i++){
if(vis[i]){
continue;
}
int next;
int minn = INF;
//查找最小的路径
for(int i=1;i<=N;i++){
if(!vis[i] && cost_d[i] <minn){
next = i;
minn = cost_d[i];
}
}
vis[next] = 1;
//到达其他节点
for(int i =1;i<=N;i++){
if(!vis[i]&&G[next][i]<INF){
if(G[next][i] +cost_d[next] < cost_d[i]){
cost_d[i] = G[next][i] +cost_d[next];
}
}
}
}
int minn = INF,mark;
for(int i=0;i<vec_endd.size();i++){
if(minn > cost_d[vec_endd[i]]){
mark = vec_endd[i];
minn = cost_d[vec_endd[i]];
}
}
cout<<minn<<endl;
}
}
*/
vector<vector<Edge> > G(MAXN);
//在加上离散化
int search_node(int value,int Size){
int l =0,r = Size;
while(l>r){
int mid = (l+r)>>1;
if(Nodes[mid] == value)
return mid;
else if(Nodes[mid] < value){
l = mid +1;
}else{
r = mid-1;
}
}
return -1;
}
void init1(){
//memset(G,INF,sizeof(G));
memset(cost_d,INF,sizeof(cost_d));
memset(vis,0,sizeof(vis));
for(int i=0;i<MAXN;i++){
G[i].clear();
}
N=0;
vec_Start.clear();
vec_endd.clear();
Nodes.clear();
}
void solve1(){
int a,b,d;
while(scanf("%d %d %d",&T,&S,&D)==3){
init1();
//先将边输入进来
for(int i=0;i<T;i++){
scanf("%d%d%d",&a,&b,&d);
Edge edge;
edge.u = a;
edge.v =b;
edge.d = d;
vec_edges.push_back(edge);
//离散化前先存入节点vec中
Nodes.push_back(a);
Nodes.push_back(b);
N= max(max(a,b),N);
}
//离散化 sort 最后一位是不取的
sort(Nodes.begin(),Nodes.end());
int Node_Size = unique(Nodes.begin(),Nodes.end()) - Nodes.begin();
//离散化后对应的可能为
//前 2 4 6 8 9
//后 0 1 2 3 4
G.resize(Node_Size);
for(int i=0;i<G.size();i++)
G[i].resize(Node_Size + 1000);
//将各节点离散化的顺序对应起来
//并将各边存储进图中
for(int i=0;i<T;i++){
Edge& edge = vec_edges[i];
int uu = search_node(edge.u,Node_Size);
int vv = search_node(edge.v,Node_Size);
edge.uu = uu;
edge.vv = vv;
G[uu].push_back(edge);
G[vv].push_back(edge);
}
//合并起点
for(int i=0;i<S;i++){
//t1是原始的节点顺序,
int t1;
scanf("%d",&t1);
int index = search_node(t1,Node_Size);
vec_Start.push_back(index);
//找到离散化后的节点
//
vis[index] = 1;
cost_d[index] = 0;
}
for(int i=0;i<D;i++){
int t1;
scanf("%d",&t1);
int index = search_node(t1,Node_Size);
vec_endd.push_back(index);
}
//首先将起点初始化
//并将起始点到所有能到达的点的坐标一一更新
for(int i = 0;i<vec_Start.size();i++){
int u = vec_Start[i];
for(int j =0;j<G[u].size();j++){
Edge& edge = G[u][j];
int v = (u==edge.uu? edge.vv:edge.uu);
if(vis[v])
continue;
if(edge.d < cost_d[v]){
cost_d[v] = edge.d;
}
}
}
//遍历剩下的节点
for(int i=0;i<Node_Size;i++){
if(vis[i])
continue;
int next;
int minn = INF;
//从cost_d中寻找最短的路径
for(int j=0;j<Node_Size;j++){
if(!vis[j]&& minn >cost_d[j]){
next = j;
minn = cost_d[j];
}
}
vis[next] =1;
//从next节点访问剩下的节点
for(int j=0;j<G[next].size();j++){
Edge& edge = G[next][j];
int v = (next==edge.uu? edge.vv:edge.uu);
if(vis[v])
continue;
if(edge.d + cost_d[next] < cost_d[v]){
cost_d[v] = edge.d+cost_d[next];
}
}
}
int minn = INF,mark;
for(int i=0;i<vec_endd.size();i++){
int v = vec_endd[i];
int vv = search_node(v,Node_Size);
if(minn > cost_d[vv]){
mark = vv;
minn = cost_d[vv];
}
}
cout<<minn<<endl;
}
}
int main()
{
if(DEBUG)
freopen("data.txt","r",stdin);
solve1();
return 0;
}