#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;
}
}