#include<bits/stdc++.h>
#define N 4000006
#define int long long
using namespace std;
int n, m, tot;
int t[N], dep[N], fa[N], siz[N], son[N], dfn[N], a[N], top[N];
vector<int>p[N];
void dfs1(int x, int father) {
dep[x] = dep[father] + 1;
fa[x] = father;
siz[x] = 1;
int maxson = -1;
for(int i = 0; i < p[x].size(); i++) {
int y = p[x][i];
if(y == father) continue;
dfs1(y, x);
siz[x] += siz[y];
if(siz[y] > maxson) {
maxson = siz[y];
son[x] = y;
}
}
}
void dfs2(int x, int topf) {
dfn[x] = ++tot;
a[tot] = t[x];
top[x] = topf;
if(son[x] == 0) return;
dfs2(son[x], topf);
for(int i = 0; i < p[x].size(); i++) {
int y = p[x][i];
if(dfn[y] == 0) dfs2(y, y);
}
}
struct node {
int maxx, minn, lmax, rmax, tag;
//maxx:最大值 minn:最小值 lmax:从左往右的最大价值 rmax:从右往左的最大价值
friend node operator + (node a, node b) {
node s;
s.maxx = max(a.maxx, b.maxx);
s.minn = min(a.minn, b.minn);
s.lmax = max(max(a.lmax, b.lmax), b.maxx - a.minn);
s.rmax = max(max(a.rmax, b.rmax), a.maxx - b.minn);
return s;
}
}c[N];
void pushup(int u) {
c[u] = c[u * 2] + c[u * 2 + 1];
}
void build(int u, int L, int R) {
if(L == R) {
c[u].maxx = a[L];
c[u].minn = a[L];
return;
}
int mid = (L + R) / 2;
build(u * 2, L, mid);
build(u * 2 + 1, mid + 1, R);
pushup(u);
}
void maketag(int u, int x) {
c[u].maxx += x;
c[u].minn += x;
c[u].tag += x;
}
void pushdown(int u) {
maketag(u * 2, c[u].tag);
maketag(u * 2 + 1, c[u].tag);
c[u].tag = 0;
}
bool OutofRange(int L, int R, int l, int r) { return r < L || R < l; }
bool InRange(int L, int R, int l, int r) { return l <= L && R <= r; }
void update(int u, int L, int R, int l, int r, int k) {
if(OutofRange(L, R, l, r)) return;
if(InRange(L, R, l, r)) {
maketag(u, k);
return;
}
pushdown(u);
int mid = (L + R) / 2;
update(u * 2, L, mid, l, r, k);
update(u * 2 + 1, mid + 1, R, l, r, k);
pushup(u);
}
node query(int u, int L, int R, int l, int r) {
if(OutofRange(L, R, l, r)) {
node S;
S.maxx = -1e15;
S.minn = 1e15;
S.lmax = S.rmax = S.tag = 0;
return S;
}
if(InRange(L, R, l, r)) return c[u];
pushdown(u);
int mid = (L + R) / 2;
return query(u * 2, L, mid, l, r) + query(u * 2 + 1, mid + 1, R, l, r);
}
signed main() {
cin >> n;
for(int i = 1; i <= n; i++)
cin >> t[i];
for(int i = 1; i <= n - 1; i++) {
int u, v;
cin >> u >> v;
p[u].push_back(v);
p[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
cin >> m;
while(m--) {
int x, y, k, X, Y;
cin >> x >> y >> k;
X = x, Y = y;
node L, R;
L.lmax = L.rmax = 0;
L.maxx = -1e15;
L.minn = 1e15;
R = L;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) { //跳y
node S = query(1, 1, n, dfn[top[y]], dfn[y]);
R = S + R;
y = fa[top[y]];
}
else { //跳x
node S = query(1, 1, n, dfn[top[x]], dfn[x]);
L = S + L;
x = fa[top[x]];
}
}
if(dep[x] < dep[y]) { //y在x的下面
node S = query(1, 1, n, dfn[x], dfn[y]);
R = S + R;
}
else {//x在y的下面
node S = query(1, 1, n, dfn[y], dfn[x]);
L = S + L;
}
int ans = max(max(L.rmax, R.lmax), R.maxx - L.minn);
if(ans < 0) cout << "0" << endl;
else cout << ans << endl;
x = X, y = Y;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
update(1, 1, n, dfn[top[x]], dfn[x], k);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
update(1, 1, n, dfn[x], dfn[y], k);
}
return 0;
}