#pragma GCC optimize("O3", "inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
#define pb push_back
#define ub upper_bound
#define INF 1e18 + 100
ll dfs(int r, int p, vector<vector<pair<int, ll>>>& g, ll& ans, vector<ll>& a){
priority_queue<ll, vector<ll>, greater<ll>> pq;
ll me = LONG_LONG_MIN;
for(auto& it: g[r]){
if(it.first != p) {
ll x = dfs(it.first, r, g, ans, a);
ll topi = a[r] + a[it.first] - 2 * it.second;
if(x != LONG_LONG_MIN) {
topi = max(topi, x + a[r] + a[it.first] - 2 * it.second);
me = max(me, x + a[r] + a[it.first] - 2 * it.second);
}
pq.push(topi);
}
if(pq.size() > 2) pq.pop();
}
// if(!r){
// priority_queue<ll, vector<ll>, greater<ll>> pq1;
// cout << "printing pq1: " << '\n';
// while(!pq.empty()){
// ll x = pq.top();
// cout << x << ' ';
// pq1.push(x);
// pq.pop();
// }
// cout << '\n';
// while(!pq1.empty()){
// ll x = pq1.top();
// pq.push(x);
// pq1.pop();
// }
// }
ll tor = LONG_LONG_MIN;
if(pq.size() == 2){
ll x = pq.top();
pq.pop();
ll y = pq.top();
pq.pop();
tor = y;
me = max(me, x + y - a[r]);
} else if(pq.size() == 1){
ll y = pq.top();
pq.pop();
tor = y;
}
ans = max(ans, me);
// cout << "r: " << r << ", me: " << me << ", tor: " << tor << '\n';
if(tor == LONG_LONG_MIN) return tor;
return tor - a[r];
}
ll solve()
{
int n;
cin >> n;
vector<ll> a(n);
for(int i = 0; i < n; i++) cin >> a[i];
vector<vector<pair<int, ll>>> g(n, vector<pair<int, ll>>());
for(int i = 0; i < n - 1; i++){
int x, y;
ll w;
cin >> x >> y >> w;
g[x - 1].pb({y - 1, w});
g[y - 1].pb({x - 1, w});
}
ll ans = LONG_LONG_MIN;
dfs(0, -1, g, ans, a);
return ans;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t--)
{
ll x = solve();
cout << x << "\n";
}
return 0;
}