#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T; cin >> T;
while (T--) {
int N; cin >> N;
vector<ll> W(N);
for (int i = 0; i < N; i++) cin >> W[i];
vector<vector<pair<int,ll>>> adj(N);
for (int i = 0; i < N - 1; i++) {
int u,v; ll c;
cin >> u >> v >> c;
u--; v--;
adj[u].emplace_back(v,c);
adj[v].emplace_back(u,c);
}
ll global_max = LLONG_MIN;
function<pair<ll,int>(int,int)> dfs = [&](int u, int p) -> pair<ll,int> {
vector<pair<ll,int>> child_vals;
for (auto &[to,cost] : adj[u]) {
if (to == p) continue;
auto [val,len] = dfs(to,u);
val -= 2*cost;
child_vals.emplace_back(val, len+1);
}
sort(child_vals.rbegin(), child_vals.rend(), [](auto &a, auto &b){
return a.first < b.first;
});
ll best1_val = 0; int best1_len = 0;
ll best2_val = 0; int best2_len = 0;
if (!child_vals.empty()) {
if (child_vals[0].first > 0) {
best1_val = child_vals[0].first;
best1_len = child_vals[0].second;
}
}
if (child_vals.size() > 1) {
if (child_vals[1].first > 0) {
best2_val = child_vals[1].first;
best2_len = child_vals[1].second;
}
}
ll sum_val = W[u] + best1_val + best2_val;
int sum_len = best1_len + best2_len;
if (sum_len >= 2) {
global_max = max(global_max, sum_val);
}
return {W[u] + best1_val, best1_len};
};
dfs(0,-1);
// If no path of length >=2 found, cycle cannot be formed, answer might be negative or zero
// To cover the case, if global_max not updated, fallback to minimal cycle weight
if (global_max == LLONG_MIN) {
// If no cycle can be formed (shouldn't happen), output something reasonable
// For safety output max node weight - 0
global_max = *max_element(W.begin(), W.end());
}
cout << global_max << "\n";
}
return 0;
}