#include<iostream>
#include<algorithm>
#include<functional>
#include<vector>
#include<queue>
using namespace std;
#define LL long long

struct edge{
    int to, cost;
};
struct node{
    int n, cost;
    bool operator<(const node & n1) const {
        return n1.cost < cost;
    }
};
int N, M, K;
int a[100010], b[100010], l[100010];
vector<edge> G[3010];
int main(){
    cin >> N >> M >> K;
    for(int i = 0; i < M; i++){
        cin >> a[i] >> b[i] >> l[i];
        G[a[i]].push_back(edge{b[i], l[i]});
        G[b[i]].push_back(edge{a[i], l[i]});
    }
    int D[3010] = {};
    fill(D, D + (N + 1), 1 << 30);
    priority_queue<node> pq;
    for(int i = 0; i < K; i++){
        int c = 0;
        cin >> c;
        D[c] = 0;
        pq.push(node{c, 0});
    }
    while(!pq.empty()){
        node n = pq.top();
        pq.pop();
        if(D[n.n] < n.cost) continue;
        for(auto u : G[n.n]){
            int c = n.cost + u.cost;
            if(c < D[u.to]){
                D[u.to] = c;
                pq.push(node{u.to, c});
            }
        }
    }
    int ans = 0;
    for(int i = 1; i <= N; i++){
        ans = max(ans, D[i]);
    }
    for(int i = 0; i < M; i++){
        int cost = (D[a[i]] + D[b[i]] + l[i] + 1) / 2;
        ans = max(cost, ans);
    }
    cout << ans << endl;
    return 0;
}
