#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int INF=0x7fffffff;
const int N=1e6+10;
struct node{
int to,nxt;
}edge[N];
int head[N];
int cnt;
void add(int u,int v){
edge[++cnt]={v,head[u]};
head[u]=cnt;
}
int trans[N],dv[N],fa[N],hson[N],top[N],siz[N],dep[N],in[N];
void dfs1(int x,int last){
fa[x]=last;
siz[x]=1;
dep[x]=dep[last]+1;
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last){
dfs1(edge[i].to,x);
siz[x]+=siz[edge[i].to];
if(siz[edge[i].to]>siz[hson[x]]||!hson[x]){
hson[x]=edge[i].to;
}
}
}
}
int timer;
void dfs2(int x,int tpx){
if(!x) return;
top[x]=tpx;
in[x]=++timer;
trans[timer]=dv[x];
if(hson[x]) dfs2(hson[x],tpx);
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to==hson[x]||edge[i].to==fa[x]) continue;
dfs2(edge[i].to,edge[i].to);
}
}
struct nnd{
int maxn,minn,tans;
};
nnd mgr(nnd a,nnd b){
return {max(a.maxn,b.maxn),min(a.minn,b.minn),max(max(a.tans,b.tans),b.maxn-a.minn)};
}
struct tn{
int l,r,laz;
nnd val;
}tree[4*N];
void push_up(int pos){
tree[pos].val=mgr(tree[pos*2].val,tree[pos*2+1].val);
}
void build(int pos,int lft,int rgt){
tree[pos].l=lft;
tree[pos].r=rgt;
if(lft==rgt){
tree[pos].val={trans[lft],trans[lft],0};
return;
}
int mid=(lft+rgt)/2;
build(pos*2,lft,mid);
build(pos*2+1,mid+1,rgt);
push_up(pos);
}
void push_down(int pos){
tree[pos*2].val.maxn+=tree[pos].laz;
tree[pos*2].val.minn+=tree[pos].laz;
tree[pos*2+1].val.maxn+=tree[pos].laz;
tree[pos*2+1].val.minn+=tree[pos].laz;
tree[pos*2].laz+=tree[pos].laz;
tree[pos*2+1].laz+=tree[pos].laz;
tree[pos].laz=0;
}
void upd(int pos,int lft,int rgt,int x){
if(lft<=tree[pos].l&&tree[pos].r<=rgt){
tree[pos].val.maxn+=x;
tree[pos].val.minn+=x;
tree[pos].laz+=x;
return;
}
if(rgt<tree[pos].l||tree[pos].r<lft) return;
push_down(pos);
upd(pos*2,lft,rgt,x);
upd(pos*2+1,lft,rgt,x);
push_up(pos);
}
nnd ask(int pos,int lft,int rgt){
if(rgt<tree[pos].l||tree[pos].r<lft) return {-INF,INF,0};
if(lft<=tree[pos].l&&tree[pos].r<=rgt) return tree[pos].val;
push_down(pos);
return mgr(ask(pos*2,lft,rgt),ask(pos*2+1,lft,rgt));
}
int n,q;
signed main(){
memset(head,-1,sizeof(head));
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>dv[i];
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
fa[1]=1;
build(1,1,n);
cin>>q;
while(q--){
int a,b,v,ta,tb;
cin>>a>>b>>v;
ta=a;tb=b;
while(top[a]!=top[b]){
if(dep[top[a]]>=dep[top[b]]){
upd(1,in[top[a]],in[a],v);
a=fa[top[a]];
}else{
upd(1,in[top[b]],in[b],v);
b=fa[top[b]];
}
}
if(dep[a]>=dep[b]){
upd(1,in[b],in[a],v);
}else{
upd(1,in[a],in[b],v);
}
a=ta;b=tb;
nnd ll={-INF,INF,0},rr={-INF,INF,0};
while(top[a]!=top[b]){
if(dep[top[a]]>=dep[top[b]]){
ll=mgr(ll,ask(1,in[top[a]],in[a]));
a=fa[top[a]];
}else{
rr=mgr(ask(1,in[top[b]],in[b]),rr);
b=fa[top[b]];
}
}
if(dep[a]>=dep[b]){
cout<<mgr(mgr(ll,ask(1,in[b],in[a])),rr).tans<<'\n';
}else{
cout<<mgr(ll,mgr(ask(1,in[a],in[b]),rr)).tans<<'\n';
}
}
return 0;
}