dp1[i]为i到儿子(包括自己)演讲获得的最大价值
dp2[i]为i到祖先或祖先儿子演讲获得的最大价值
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
int n,q,u,v,w,idx,head[N],x,y;
long long c[N];
struct Edge{
int v,w,next;
}e[2*N];
void add(int u,int v,int w){
e[++idx].v=v;
e[idx].w=w;
e[idx].next=head[u];
head[u]=idx;
}
int fat[N],dep[N],siz[N],mason[N],masonw[N];
long long dp1[N],dp2[N];
void dfs1(int now,int fa){
fat[now]=fa;
dep[now]=dep[fa]+1;
siz[now]=1;
int mas=-1;
for(int i=head[now];i;i=e[i].next){
int to=e[i].v;
if(to==fa) continue;
dfs1(to,now);
siz[now]+=siz[to];
if(siz[to]>mas){
mas=siz[to];
mason[now]=to;
masonw[now]=e[i].w;
}
dp1[now]=max(dp1[now],dp1[to]-2*e[i].w);
}
dp1[now]=max(dp1[now],c[now]);
}
int top[N],dfn[N],cost[N],cnt;
long long value[N];
void dfs2(int now,int fa,int topp,int w){
top[now]=topp;
dfn[now]=++cnt;
cost[cnt]=w;
value[cnt]=dp1[now];
if(siz[now]>1) dfs2(mason[now],now,topp,masonw[now]);
for(int i=head[now];i;i=e[i].next){
int to=e[i].v;
if(to==fa||to==mason[now]) continue;
dfs2(to,now,to,e[i].w);
}
dp2[now]=max(dp2[fa],dp1[fa])-w*2;
}
struct segement_Tree{
long long sum;
long long ma;
}t[4*N];
void build(int now,int l,int r){
if(l==r){
t[now].ma=value[l];
t[now].sum=cost[l];
return;
}
int mid=(l+r)/2;
build(now*2,l,mid);
build(now*2+1,mid+1,r);
t[now].ma=max(t[now*2].ma,t[now*2+1].ma);
t[now].sum=t[now*2].sum+t[now*2+1].sum;
}
long long qs(int now,int l,int r,int ml,int mr){
if(ml<=l&&r<=mr){
return t[now].sum;
}
int mid=(l+r)/2;
long long res=0;
if(ml<=mid) res+=qs(now*2,l,mid,ml,mr);
if(mr>=mid+1) res+=qs(now*2+1,mid+1,r,ml,mr);
return res;
}
long long qm(int now,int l,int r,int ml,int mr){
if(ml<=l&&r<=mr){
return t[now].ma;
}
int mid=(l+r)/2;
long long res1=-0x7fffffff,res2=-0x7fffffff;
if(ml<=mid) res1=qm(now*2,l,mid,ml,mr);
if(mr>=mid+1) res2=qm(now*2+1,mid+1,r,ml,mr);
return max(res1,res2);
}
long long query(int x,int y){
int X=x,Y=y;
long long ans=0;
long long maa=-0x7fffffff;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=qs(1,1,n,dfn[top[x]],dfn[x]);
maa=max(maa,qm(1,1,n,dfn[top[x]],dfn[x]));
x=fat[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
ans+=qs(1,1,n,dfn[y],dfn[x]);
ans-=cost[dfn[y]];
maa=max(maa,qm(1,1,n,dfn[y],dfn[x]));//cout<<maa<<" ";
maa=max(maa,dp2[y]);//y为LCA
//cout<<ans<<" "<<maa<<"\n";
return c[X]+c[Y]-ans+maa;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
}
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
for(int i=0;i<=n+1;i++){
dp1[i]=-0x7fffffff;
dp2[i]=-0x7fffffff;
}
dfs1(1,0);
dfs2(1,0,1,0);
build(1,1,n);
while(q--){
scanf("%d%d",&x,&y);
printf("%lld\n",query(x,y));
}
return 0;
}