#include <bits/stdc++.h>
#define long long ll
#define N 50014
using namespace std;
struct node {
int to,len;
node(){}
node(int _to,int _len):to(_to),len(_len){}
bool operator < (const node& a)const{
return len>a.len;
}
};
bool cmp(node a,node b){
return a.len<b.len;
}
priority_queue <node> q0;
/**
在这个优先队列内node存储的是部分的路径信息(一条路径的结尾以及这条路径的长度)
*/
priority_queue <int> q1;///已知的所有路径的长度
vector <node> ve[N];
/**
在这个vector内node存储的是以N号路径为起点,下一跳可以走到那些节点以及单步长度
*/
int a[N],b[N];
void init(int n){
while(!q1.empty()){
q1.pop();
}
while(!q0.empty()){
q0.pop();
}
for(int i = 1;i<=n;i++){
ve[i].clear();
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
init(n);
for(int i = 1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
q0.push({v,w});
q1.push(w);
ve[u].push_back({v,w});
}
for(int i = 1;i<=n;i++){
sort(ve[i].begin(),ve[i].end(),cmp);
}
int mx = 0;
for(int i = 0;i<k;i++){
scanf("%d",&a[i]);
mx = max(mx,a[i]);
}
for(int i = 1;i<=mx;i++){
b[i] = q0.top().len;
///用当前已知的所有边的最短边更新答案
int x = q0.top().to;
q0.pop();///这条路已经被用于更新过答案,抛弃
for(int j = 0;j<(int)ve[x].size();j++){
///类似于bfs但不是从所有路径的结尾处拓展,
///而是从当前已知的最短路的结尾处拓展一步
///因为下一条最短的路径一定只可能出现在
///已知路径或者这些拓展出的路径中(!!)
///除了这里的策略是只需要从上一条最短路的结尾进行拓展
///其他做法都和完全bfs暴力寻找相同。
///这个优化实现了一次找一条最短路,方便更新答案,而且优化了复杂度
///(假设这个图构成了完全图,应该就是最坏情况)
int y = ve[x][j].to;
int len = b[i]+ve[x][j].len;
if((int)q1.size() == mx){
if(len>q1.top()){
break;
}
else{
q1.pop();
q1.push(len);
q0.push(node(y,len));
}
}else{
q1.push(len);
q0.push(node(y,len));
}
}
}
for(int i = 0;i<k;i++){
printf("%d\n",b[a[i]]);
}
}
return 0;
}