#include<iostream>
#include<vector>
#include<queue>
#include<map>
using namespace std;

#define N 3002
#define INF 100000000

struct Edge {
	int to, cost;
	Edge(int t, int c) : to(t), cost(c) {}
	Edge() {};
};

typedef vector<Edge> Graph;

int cost[N];
Graph g[N];
vector<int> sv;
typedef pair<int, int> P;

void dijkstra(int s) {
	priority_queue<P, vector<P>, greater<P> > q;
	cost[s] = 0; q.push(P(0,s));
	while(!q.empty()) {
		int p = q.top().first, v = q.top().second; q.pop();
		if(cost[v]<p) continue;
		for(int i=0; i<(signed)g[v].size(); ++i) {
			Edge e = g[v][i];
			if(cost[v]+e.cost<cost[e.to]) {
				cost[e.to] = cost[v]+e.cost;
				q.push(P(cost[e.to], e.to));
			}
		}
	}
}

#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)

int main() {
	int n, m, k, a, b, l, s;
	double ans = 0.0;
	cin >> n >> m >> k;
	for(int i=1; i<=n; ++i) cost[i] = INF;
	for(int i=0; i<m; ++i) {
		cin >> a >> b >> l;
		g[a].push_back(Edge(b,l));
		g[b].push_back(Edge(a,l));
	}
	for(int i=0; i<k; ++i) {
		cin >> s;
		dijkstra(s);
	}
	for(int i=1; i<=n; ++i) {
		for(int j=0; j<(signed)g[i].size(); ++j) {
			if(i<g[i][j].to) continue;
			a = cost[i]; b = cost[g[i][j].to]; l = g[i][j].cost;
			if(a>=b+l || b>=a+l) {
				ans = max(ans, (double)max(a,b));
			}else {
				ans = max(ans, (double)(a+b+l)/2.0);
			}
		}
	}
	cout << (int)(ans+0.5) << endl;
	return 0;
}