#include<iostream>
using namespace std;
#define MaxSize 505
typedef struct {
int arc[MaxSize][MaxSize]; // 邻接矩阵
int numV, numE; //图中的定点数和边数
}MGraph;
int main() {
int t;
cin >> t;
while (t--) {
MGraph G;
int x, y, a, b, cost = 0;
cin >> G.numV >> G.numE;
for (int i = 1; i <= G.numV; i++) { //初始化邻接矩阵
for (int j = 1; j <= G.numV; j++) {
if (i == j) G.arc[i][j] = 0;
else G.arc[i][j] = 200; //题中条件 c<=100,这里设置的数值比 100大就能够
}
}
for (int i = 0; i < G.numE; i++) {
cin >> x >> y;
cin >> G.arc[x][y];
G.arc[y][x] = G.arc[x][y];
}
cin >> a; //找出代价最小的链接点
for (int i = 1; i < G.numV; i++) {
cin >> b;
if (b < a) a = b;
}
int adjvex[MaxSize]; //保存相关顶点下标
int lowcost[MaxSize]; //保存相关顶点间的边的权值
adjvex[1] = 1; //初始化第1号楼的下标为1
lowcost[1] = 0; //初始化第一个权值为0,即1号楼加入生成树,lowcost的值0即表示此下标的的楼号已加入生成树
for (int i = 2; i <= G.numV; i++) { //循环除了下标为1的所有楼号
lowcost[i] = G.arc[1][i]; //将与1号楼链接的楼号的权值存入数组
adjvex[i] = 1; //表示全部楼与1号楼相连
}
for (int i = 1; i < G.numV; i++) {
int min = 200; // c <= 100
int j = 1, k = 0;
while (j <= G.numV) { //寻找与当前楼相连的权值最小的楼号
if (lowcost[j] != 0 && min > lowcost[j]) {
min = lowcost[j];
k = j;
}
j++;
}
//cout << adjvex[k] << k << lowcost[k] << endl;
cost += lowcost[k];
lowcost[k] = 0; //lowcost的值0即表示此下标的的楼号已加入生成树
for (int l = 2; l <= G.numV; l++) { //更新加入k号楼所致使的lowcost,adjvex的变化
if (lowcost[l] != 0 && G.arc[k][l] < lowcost[l]) {
lowcost[l] = G.arc[k][l];
adjvex[l] = k;
}
}
}
cout << cost+a << endl;
}
}