#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e5+1e4;
long long my_max(const long long x,const long long y){
return x>y?x:y;
}
long long my_min(const long long x,const long long y){
return x<y?x:y;
}
const long long inf=1e18;
struct trees{
struct tre{
long long l,r;
long long plz,val,sum;
}tree[4*N];
void push_up(int i){
tree[i].val=my_max(tree[i*2].val,tree[i*2+1].val);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void push_down(int i){
if (tree[i].plz==0) return ;
tree[i*2].val+=tree[i].plz;
tree[i*2+1].val+=tree[i].plz;
tree[i*2].plz+=tree[i].plz;
tree[i*2+1].plz+=tree[i].plz;
tree[i*2].sum+=(tree[i*2].r-tree[i*2].l+1)*tree[i].plz;
tree[i*2+1].sum+=(tree[i*2+1].r-tree[i*2+1].l+1)*tree[i].plz;
tree[i].plz=0;
return ;
}
void build(int i,int l,int r){
tree[i].l=l;tree[i].r=r;tree[i].plz=0;tree[i].val=0;tree[i].sum=0;
if (l==r){
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
return ;
}
void add(int i,int l,int r,long long val){
if (tree[i].l>=l&&tree[i].r<=r){
tree[i].val+=val;
tree[i].plz+=val;
tree[i].sum+=(tree[i].r-tree[i].l+1)*val;
return ;
}
if (tree[i].l>r||tree[i].r<l) return ;
push_down(i);
if (tree[i*2].r>=l) add(i*2,l,r,val);
if (tree[i*2+1].l<=r) add(i*2+1,l,r,val);
push_up(i);
return ;
}
long long query_maxn(int i,int l,int r){
if (tree[i].l>=l&&tree[i].r<=r) return tree[i].val;
if (tree[i].l>r||tree[i].r<l) return -inf;
long long s=-inf;
push_down(i);
if (tree[i*2].r>=l) s=query_maxn(i*2,l,r);
if (tree[i*2+1].l<=r) s=my_max(query_maxn(i*2+1,l,r),s);
return s;
}
long long query_sum(int i,int l,int r){
if (tree[i].l>=l&&tree[i].r<=r) return tree[i].sum;
if (tree[i].l>r||tree[i].r<l) return 0;
long long s=0;
push_down(i);
if (tree[i*2].r>=l) s=query_sum(i*2,l,r);
if (tree[i*2+1].l<=r) s+=query_sum(i*2+1,l,r);
return s;
}
void change(int i,int pos,long long val){
if (tree[i].l==tree[i].r){
tree[i].val=val;
tree[i].sum=val;
return ;
}
if (tree[i*2].r>=pos) change(i*2,pos,val);
else change(i*2+1,pos,val);
push_up(i);
return ;
}
void change_val(int i,int pos,long long val){
if (tree[i].l==tree[i].r){
tree[i].val=val;
return ;
}
if (tree[i*2].r>=pos) change_val(i*2,pos,val);
else change_val(i*2+1,pos,val);
push_up(i);
return ;
}
void change_sum(int i,int pos,long long val){
if (tree[i].l==tree[i].r){
tree[i].sum=val;
return ;
}
if (tree[i*2].r>=pos) change_sum(i*2,pos,val);
else change_sum(i*2+1,pos,val);
push_up(i);
return ;
}
}t1,t2,t3;
int n,q;
struct rec{
int e,nex;
long long d;
}z[N*2];
int en,fi[N];
void add(int s,int e,long long d){
z[++en].e=e;
z[en].d=d;
z[en].nex=fi[s];
fi[s]=en;
}
long long a[N],b[N],c[N],maxn[N],d[N],m3[N],v[N],e[N];
int fa[N],deep[N],siz[N],son[N],id[N],tot,toop[N];
void dfs1(int s,int f,long long sum){
fa[s]=f;
deep[s]=deep[f]+1;
siz[s]=1;
son[s]=-1;
for (int i=fi[s];i!=0;i=z[i].nex){
if (z[i].e==f) continue;
dfs1(z[i].e,s,sum+z[i].d);
maxn[s]=my_max(maxn[s],maxn[z[i].e]-2*z[i].d);
d[z[i].e]=z[i].d;
siz[s]+=siz[z[i].e];
if (son[s]==-1||siz[son[s]]<siz[z[i].e]) son[s]=z[i].e;
}
m3[s]=maxn[s]+2*sum;
}
void dfs2(int s,int topp){
toop[s]=topp;
id[s]=++tot;
a[id[s]]=maxn[s];
b[id[s]]=d[s];
c[id[s]]=m3[s];
e[id[s]]=v[s];
if (son[s]==-1) return ;
dfs2(son[s],topp);
for (int i=fi[s];i!=0;i=z[i].nex){
if (z[i].e!=son[s]&&z[i].e!=fa[s]) dfs2(z[i].e,z[i].e);
}
}
int q_lca(int x,int y,long long &s){
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
s-=t2.query_sum(1,id[toop[x]],id[x]);
x=fa[toop[x]];
}
if (id[x]>id[y]) swap(x,y);
if (id[x]!=id[y]){
s-=t2.query_sum(1,id[x]+1,id[y]);
}
return deep[x]>deep[y]?y:x;
}
void q_sum(int x,int y,long long &s){
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
s+=t2.query_sum(1,id[toop[x]],id[x]);
x=fa[toop[x]];
}
s+=t2.query_sum(1,min(id[x],id[y]),max(id[x],id[y]));
return ;
}
void q_ans_t1(int x,int y,long long &s){
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
s=my_max(s,t1.query_maxn(1,id[toop[x]],id[x]));
x=fa[toop[x]];
}
s=my_max(s,t1.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
return ;
}
void q_ans_t2(int x,int y,long long &s){
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
s=my_max(s,t2.query_maxn(1,id[toop[x]],id[x]));
x=fa[toop[x]];
}
s=my_max(s,t2.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
return ;
}
void c_add(int x,int y,long long op){
long long sum=0;
q_sum(x,y,sum);
sum*=op;
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
t3.add(1,id[toop[x]],id[x],sum);
x=fa[toop[x]];
}
if (id[x]>id[y]) swap(x,y);
t3.add(1,id[x],id[y],sum);
return ;
}
void q_ans_t3(int x,int y,long long &s){
while (toop[x]!=toop[y]){
if (deep[toop[x]]<deep[toop[y]]) swap(x,y);
s=my_max(s,t3.query_maxn(1,id[toop[x]],id[x]));
x=fa[toop[x]];
}
s=my_max(s,t3.query_maxn(1,min(id[x],id[y]),max(id[x],id[y])));
return ;
}
void init(){
scanf("%lld%lld",&n,&q);
for (int i=1;i<=n;++i){
scanf("%lld",&maxn[i]);
v[i]=maxn[i];
}
for (int i=1;i<n;++i){
int s,e;
long long d;
scanf("%d%d%lld",&s,&e,&d);
add(s,e,d);
add(e,s,d);
}
dfs1(1,0,0);
dfs2(1,1);
t1.build(1,1,n);
t2.build(1,1,n);
t3.build(1,1,n);
for (int i=1;i<=n;++i){
t1.change(1,i,a[i]);
t3.change(1,i,c[i]);
t2.change_sum(1,i,b[i]);
t2.change_val(1,i,e[i]);
}
}
void work(){
int x,y,lca;
long long ans,s;
for (int i=1;i<=q;++i){
scanf("%d%d",&x,&y);
ans=0;s=-inf;
lca=q_lca(x,y,ans);
ans+=v[x]+v[y];
q_ans_t1(x,y,s);
q_ans_t2(x,y,s);
c_add(1,lca,-2);
q_ans_t3(1,lca,s);
c_add(1,lca,2);
ans+=s;
printf("%lld\n",ans);
}
}
int main(){
init();
work();
return 0;
}