#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls u*2
#define rs u*2+1
const int N=100000;
const int INF=1000000099;
vector<int>mp[N];
int n,m,vistime,u,v,z;
int dfn[N],rdfn[N],size[N],dep[N],fa[N],w[N],top[N],a[N];
struct node{
int lmax,rmax,maxn,minn,tag;
}t[N*4];
void dfs1(int u,int f){
size[u]=1;
fa[u]=f;
dep[u]=dep[f]+1;
for(int i=0;i<mp[u].size();i++){
int v=mp[u][i];
if(v==f)continue;
dfs1(v,u);
size[u]+=size[v];
if(!w[u]||size[w[u]]<size[v])w[u]=v;
}
}
void dfs2(int u,int T){
top[u]=T;
dfn[u]=++vistime;
rdfn[vistime]=a[u];
if(w[u]!=0){
dfs2(w[u],T);
for(int i=0;i<mp[u].size();i++){
int v=mp[u][i];
if((v!=fa[u])&&(v!=w[u])){
dfs2(v,v);
}
}
}
}
void pushup(int u){
t[u].maxn=max(t[ls].maxn,t[rs].maxn);
t[u].minn=min(t[ls].minn,t[rs].minn);
t[u].lmax=max(max(t[ls].lmax,t[rs].lmax),t[rs].maxn-t[ls].minn);
t[u].rmax=max(max(t[ls].rmax,t[rs].rmax),t[ls].maxn-t[rs].minn);
}
void build(int u,int L,int R){
if(L==R){
t[u].maxn=rdfn[L];
t[u].minn=rdfn[L];
return ;
}
else {
int M=(L+R)>>1;
build(ls,L,M);
build(rs,M+1,R);
pushup(u);
}
}
void maketag(int u,int x){
t[u].maxn+=x;
t[u].minn+=x;
t[u].tag+=x;
}
void pushdown(int u,int L,int R){
maketag(ls,t[u].tag);
maketag(rs,t[u].tag);
t[u].tag=0;
}
void update(int u,int L,int R,int l,int r,int x){
if(l<=L&&R<=r){
maketag(u,x);
return ;
}
if(t[u].tag!=0&&L!=R)
pushdown(u,L,R);
int M=(L+R)>>1;
if(r<=M)update(ls,L,M,l,r,x);
if(l>=M+1)update(rs,M+1,R,l,r,x);
pushup(u);
}
node query(int u,int L,int R,int l,int r){
if(l<=L&&R<=r){
return t[u];
}
else{
if(t[u].tag!=0&&L!=R)
pushdown(u,L,R);
int M=(L+R)>>1;
if(r<=M)return query(ls,L,M,l,r);
if(l>=M+1)return query(rs,M+1,R,l,r);
node tree;
node a=query(ls,L,M,l,r);
node b=query(rs,M+1,R,l,r);
tree.maxn=max(a.maxn,b.maxn);
tree.minn=min(a.minn,b.minn);
tree.lmax=max(max(a.lmax,b.lmax),b.maxn-a.minn);
tree.rmax=max(max(a.rmax,b.rmax),a.maxn-b.minn);
return tree;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<n;i++){
cin>>u>>v;
mp[u].push_back(v);
mp[v].push_back(u);
}
dfs1(1,0);
dfs2(1,0);
build(1,1,n);
cin>>m;
int x,y,k;
while(m--){
cin>>x>>y>>k;
node L,R;
L.lmax=L.rmax=0;
L.maxn=-INF;
L.minn=INF;
R=L;
int xx=x,yy=y;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
node tree=query(1,1,n,dfn[top[y]],dfn[y]);
R.lmax=max(max(tree.lmax,R.lmax),R.maxn-tree.minn);
R.rmax=max(max(tree.rmax,R.rmax),tree.maxn-R.minn);
R.maxn=max(R.maxn,tree.maxn);
R.minn=min(R.minn,tree.minn);
y=fa[top[y]];
}
else {
node tree=query(1,1,n,dfn[top[x]],dfn[x]);
L.lmax=max(max(tree.lmax,L.lmax),L.maxn-tree.minn);
L.rmax=max(max(tree.rmax,L.rmax),tree.maxn-L.minn);
L.maxn=max(L.maxn,tree.maxn);
L.minn=min(L.minn,tree.minn);
x=fa[top[x]];
}
}
if(dep[x]<dep[y]){
node tree=query(1,1,n,dfn[x],dfn[y]);
R.lmax=max(max(tree.lmax,R.lmax),R.maxn-tree.minn);
R.rmax=max(max(tree.rmax,R.rmax),tree.maxn-R.minn);
R.maxn=max(R.maxn,tree.maxn);
R.minn=min(R.minn,tree.minn);
}
else{
node tree=query(1,1,n,dfn[y],dfn[x]);
L.lmax=max(max(tree.lmax,L.lmax),L.maxn-tree.minn);
L.rmax=max(max(tree.rmax,L.rmax),tree.maxn-L.minn);
L.maxn=max(L.maxn,tree.maxn);
L.minn=min(L.minn,tree.minn);
}
int ans=max(max(L.rmax,R.lmax),R.maxn-L.minn);
cout<<ans<<"\n";
x=xx,y=yy;
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]];
}
update(1,1,n,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),k);
}
}