#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int n,m,r,p;
vector<int>g[100001];
struct segment
{
int _begin,_end;
};
vector<segment>rev[2];
int a[100001];
int dfn[100001],rdfn[100001],dep[100001],father[100001],wc[100001],sz[100001],top[100001],vistime=0;
int lw[400001],rw[400001],maxw[400001],minw[400001],lzy[400001];
void dfs1(int u,int f)
{
father[u]=f;
sz[u]=1;
dep[u]=dep[f]+1;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v!=f)
{
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wc[u]])
{
wc[u]=v;
}
}
}
}
void dfs2(int u,int Top)
{
vistime++;
dfn[u]=vistime;
rdfn[vistime]=u;
top[u]=Top;
if(wc[u]!=0)
{
dfs2(wc[u],Top);
}
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v!=father[u]&&v!=wc[u])
{
dfs2(v,v);
}
}
}
void split(int u,int v)
{
rev[0].clear();
rev[1].clear();
int x=0,y=1;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
swap(u,v);
swap(x,y);
}
rev[x].push_back((segment){dfn[top[u]],dfn[u]});
u=father[top[u]];
}
if(dep[u]>dep[v])
{
swap(u,v);
}
rev[x].push_back((segment){dfn[u],dfn[v]});
reverse(rev[1].begin(),rev[1].end());
}
void pushup(int u)
{
lw[u]=max(max(lw[u*2],lw[u*2+1]),maxw[u*2]-minw[u*2+1]);
rw[u]=max(max(rw[u*2],rw[u*2+1]),maxw[u*2+1]-minw[u*2]);
maxw[u]=max(maxw[u*2],maxw[u*2+1]);
minw[u]=min(minw[u*2],minw[u*2+1]);
}
void maketag(int u,int x)
{
lzy[u]+=x;
maxw[u]+=x;
minw[u]+=x;
}
void pushdown(int u,int l,int r)
{
int mid=(l+r)/2;
maketag(u*2,lzy[u]);
maketag(u*2+1,lzy[u]);
lzy[u]=0;
}
bool inrange(int l,int r,int L,int R)
{
return (L<=l)&&(r<=R);
}
bool outrange(int l,int r,int L,int R)
{
return (r<L)||(R<l);
}
void build(int u,int l,int r)
{
if(l==r)
{
lw[u]=0;
rw[u]=0;
maxw[u]=minw[u]=a[rdfn[l]];
return;
}
int mid=(l+r)/2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int L,int R,int v)
{
if(inrange(l,r,L,R))
{
maketag(u,v);
}
else if(!outrange(l,r,L,R))
{
int mid=(l+r)/2;
pushdown(u,l,r);
update(u*2,l,mid,L,R,v);
update(u*2+1,mid+1,r,L,R,v);
pushup(u);
}
}
struct node
{
int lw,rw,maxw,minw;
};
node ask(int u,int l,int r,int L,int R)
{
if(inrange(l,r,L,R))
{
return (node){lw[u],rw[u],maxw[u],minw[u]};
}
else if(!outrange(l,r,L,R))
{
int mid=(l+r)/2;
pushdown(u,l,r);
node a=ask(u*2,l,mid,L,R);
node b=ask(u*2+1,mid+1,r,L,R);
node k=(node){max(max(a.lw,b.lw),a.maxw-b.minw),max(max(a.rw,b.rw),b.maxw-a.minw),max(a.maxw,b.maxw),min(a.minw,b.minw)};
return k;
}
else
{
return (node){0,0,0,2000000000};
}
}
int query(int x,int y,int k)
{
int a=x,b=y;
split(a,b);
int ans=0;
int maxn=0,minn=2e9;
for(int p=0;p<=1;p++)
{
for(int i=0;i<rev[p].size();i++)
{
int u=rev[p][i]._begin,v=rev[p][i]._end;
node k=ask(1,1,n,u,v);
maxn=max(maxn,k.maxw);
if(i==0)
{
ans=max(ans,max(maxn-minn,k.rw));
}
else
{
ans=max(ans,max(maxn-minn,k.rw));
}
minn=min(minn,k.minw);
}
}
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=father[top[x]];
}
update(1,1,n,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),k);
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
int ans=query(x,y,k);
printf("%d\n",ans);
}
return 0;
}