#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Max=5e5+5,inf=0x7fffffff;
int n,m;
struct edge{
int to,next;
}p[Max*4];
string in;
int head[Max],idx=0,tot=0,sum=0;
int torank[Max],totree[Max];
struct infor{
int w,dfn,top,hs,dep,size,fa,down;
}g[Max];
struct tree{
int l,r,nl,nr,dp[2][2];
}t[Max*4];
struct dps{
int dp[2][2];
dps()
{
dp[0][0]=dp[0][1]=dp[1][0]=dp[1][1]=0;
}
dps(int n00,int n01,int n10,int n11)
{
dp[0][0]=n00;
dp[0][1]=n01;
dp[1][0]=n10;
dp[1][1]=n11;
}
}last[Max];
stack<pair<int,dps> > into;
int root[Max],cnt=0;
void pushup(int now)
{
t[now].dp[0][0]=t[t[now].l].dp[0][0]+t[t[now].r].dp[0][0];
t[now].dp[0][0]=max(t[now].dp[0][0] , t[t[now].l].dp[0][0]+t[t[now].r].dp[1][0]);
t[now].dp[0][0]=max(t[now].dp[0][0] , t[t[now].l].dp[0][1]+t[t[now].r].dp[0][0]);
t[now].dp[0][1]=t[t[now].l].dp[0][0]+t[t[now].r].dp[0][1];
t[now].dp[0][1]=max(t[now].dp[0][1] , t[t[now].l].dp[0][0]+t[t[now].r].dp[1][1]);
t[now].dp[0][1]=max(t[now].dp[0][1] , t[t[now].l].dp[0][1]+t[t[now].r].dp[0][1]);
t[now].dp[1][0]=t[t[now].l].dp[1][0]+t[t[now].r].dp[0][0];
t[now].dp[1][0]=max(t[now].dp[1][0] , t[t[now].l].dp[1][0]+t[t[now].r].dp[1][0]);
t[now].dp[1][0]=max(t[now].dp[1][0] , t[t[now].l].dp[1][1]+t[t[now].r].dp[0][0]);
t[now].dp[1][1]=t[t[now].l].dp[1][0]+t[t[now].r].dp[0][1];
t[now].dp[1][1]=max(t[now].dp[1][1] , t[t[now].l].dp[1][1]+t[t[now].r].dp[0][1]);
t[now].dp[1][1]=max(t[now].dp[1][1] , t[t[now].l].dp[1][0]+t[t[now].r].dp[1][1]);
}
void build(int now,int l,int r)
{
t[now].nl=l;
t[now].nr=r;
if(l==r)
{
t[now].dp[0][0]=0;
t[now].dp[1][1]=g[torank[l]].w;
t[now].dp[0][1]=-inf*0x7ffff;
t[now].dp[1][0]=-inf*0x7ffff;
totree[torank[l]]=now;
return ;
}
int mid=(l+r)>>1;
t[now].l=++cnt;
build(cnt,l,mid);
t[now].r=++cnt;
build(cnt,mid+1,r);
pushup(now);
}
void update(int now,int loc,dps num)
{
if(t[now].nl==t[now].nr)
{
into.push(make_pair(now,dps(t[now].dp[0][0],t[now].dp[0][1],t[now].dp[1][0],t[now].dp[1][1])));
t[now].dp[0][0]+=num.dp[0][0];
t[now].dp[0][1]+=num.dp[0][1];
t[now].dp[1][0]+=num.dp[1][0];
t[now].dp[1][1]+=num.dp[1][1];
return ;
}
int mid=(t[now].nl+t[now].nr)>>1;
if(loc<=mid)
update(t[now].l,loc,num);
else
update(t[now].r,loc,num);
into.push(make_pair(now,dps(t[now].dp[0][0],t[now].dp[0][1],t[now].dp[1][0],t[now].dp[1][1])));
pushup(now);
}
void add(int u,int v)
{
p[++idx].next=head[u];
head[u]=idx;
p[idx].to=v;
}
void dfs(int now,int from)
{
g[now].size++;
g[now].dep=g[from].dep+1;
g[now].fa=from;
for(int i=head[now];p[i].to;i=p[i].next)
{
if(p[i].to==from)
continue;
dfs(p[i].to,now);
g[now].size+=g[p[i].to].size;
}
}
void dfs2(int now,int from)
{
g[now].dfn=++tot;
torank[tot]=now;
g[now].down=now;
int Maxsize=0,to=0;
for(int i=head[now];p[i].to;i=p[i].next)
{
if(p[i].to==from)
continue;
if(g[p[i].to].size>Maxsize)
{
Maxsize=g[p[i].to].size;
to=p[i].to;
}
}
if(to==0)
return ;
g[now].hs=to;
g[to].top=g[now].top;
dfs2(to,now);
g[now].down=g[to].down;
for(int i=head[now];p[i].to;i=p[i].next)
{
if(p[i].to==from or p[i].to==to)
continue;
g[p[i].to].top=p[i].to;
dfs2(p[i].to,now);
}
}
void dfs3(int now,int from)
{
if(g[now].top==now)
{
root[now]=++cnt;
build(cnt,g[now].dfn,g[g[now].down].dfn);
}
for(int i=head[now];p[i].to;i=p[i].next)
{
if(p[i].to==from)
continue;
dfs3(p[i].to,now);
if(p[i].to!=g[now].hs)
{
int top=g[p[i].to].top,rot=root[top];
dps to;
to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
update(root[g[now].top],g[now].dfn,to);
}
}
if(g[now].top==now)
{
int top=g[now].top,rot=root[top];
dps to;
to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
last[rot]=dps(to.dp[0][0],0,0,to.dp[1][1]);
}
return ;
}
void Update(int now)
{
while(g[now].top!=1)
{
int top=g[now].top,rot=root[top];
dps to=dps(-last[rot].dp[0][0] ,0 ,0 ,-last[rot].dp[1][1]);
to.dp[0][0]+=max(t[rot].dp[0][0],max(t[rot].dp[1][0],max(t[rot].dp[1][1],t[rot].dp[0][1])));
to.dp[1][1]+=max(t[rot].dp[0][0],t[rot].dp[0][1]);
update(root[g[g[top].fa].top],g[g[top].fa].dfn,to);
now=g[top].fa;
}
}
signed main()
{
scanf("%lld%lld",&n,&m);
cin>>in;
for(int i=1;i<=n;i++)
{
scanf("%lld",&g[i].w);
sum+=g[i].w;
}
int x,y;
for(int i=1;i<n;i++)
{
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,1);
g[1].top=1;
dfs2(1,1);
dfs3(1,1);
while(!into.empty())
into.pop();
int a,op1,b,op2;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld%lld",&a,&op1,&b,&op2);
if((g[a].fa==b or g[b].fa==a )and op1==0 and op2==0)
{
printf("-1\n");
continue;
}
if(op1==0)
update(root[g[a].top],g[a].dfn,dps(0,0,0,inf));
else
update(root[g[a].top],g[a].dfn,dps(0,0,0,-inf));
Update(g[a].top);
if(op2==0)
update(root[g[b].top],g[b].dfn,dps(0,0,0,inf));
else
update(root[g[b].top],g[b].dfn,dps(0,0,0,-inf));
Update(g[b].top);
int ans=t[1].dp[0][0];
ans=max(ans,t[1].dp[0][1]);
ans=max(ans,t[1].dp[1][0]);
ans=max(ans,t[1].dp[1][1]);
if(op1==0)
ans-=inf;
if(op2==0)
ans-=inf;
while(sum-ans<0)
ans-=inf;
printf("%lld\n",sum-ans);
while(!into.empty())
{
int now=into.top().first;
dps to=into.top().second;
into.pop();
t[now].dp[0][0]=to.dp[0][0];
t[now].dp[0][1]=to.dp[0][1];
t[now].dp[1][0]=to.dp[1][0];
t[now].dp[1][1]=to.dp[1][1];
}
}
}