#include <bits/stdc++.h>
using namespace std;
#define lson x<<1
#define rson x<<1|1
struct mat{
long long a[2][2];
mat(){for(int i=0;i<2;i++) for(int j=0;j<2;j++) a[i][j]=1e11;}
mat operator *(const mat &A)const{
mat res;
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++) res.a[i][j]=min(res.a[i][j],a[i][k]+A.a[k][j]);
}
}
return res;
}
}val[100010],tree[2000010];
int n,m,a[100010],siz[100010],fat[100010],son[100010],top[100010],dfn[100010],End[100010],idx;
long long f[100010][2],g[100010][2];
char s[5];
vector<int> ed[100010];
void update(int x,int l,int r,int d,mat v){
if(l==r){
tree[x]=v;
return;
}
int mid=(l+r)>>1;
if(mid>=d) update(lson,l,mid,d,v);
else update(rson,mid+1,r,d,v);
tree[x]=tree[lson]*tree[rson];
}
mat query(int x,int l,int r,int cl,int cr){
if(cl<=l&&r<=cr) return tree[x];
int mid=(l+r)>>1;
mat res;
if(mid>=cl) res=query(lson,l,mid,cl,cr);
if(mid<cr){
if(mid>=cl) res=res*query(rson,mid+1,r,cl,cr);
else res=query(rson,mid+1,r,cl,cr);
}
return res;
}
void dfs1(int x,int fa){
int len=ed[x].size();
siz[x]=1;fat[x]=fa;
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fa) continue;
dfs1(v,x);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]]) son[x]=v;
}
}
void dfs2(int x,int t){
int len=ed[x].size();
f[x][1]=g[x][1]=a[x];
top[x]=t;
dfn[x]=++idx;
End[t]=idx;
if(son[x]){
dfs2(son[x],t);
f[x][0]+=f[son[x]][1];
f[x][1]+=min(f[son[x]][0],f[son[x]][1]);
}
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fat[x]||v==son[x]) continue;
dfs2(v,v);
f[x][0]+=f[v][1];
f[x][1]+=min(f[v][0],f[v][1]);
g[x][0]+=f[v][1];
g[x][1]+=min(f[v][0],f[v][1]);
}
val[x].a[0][1]=g[x][0];
val[x].a[1][0]=val[x].a[1][1]=g[x][1];
update(1,1,n,dfn[x],val[x]);
}
void change(int x,int c){
if(c==1) val[x].a[0][1]=val[x].a[0][0];
else val[x].a[1][1]=val[x].a[1][0]=val[x].a[0][0];
while(x){
mat pre=query(1,1,n,dfn[top[x]],End[top[x]]);
update(1,1,n,dfn[x],val[x]);
mat now=query(1,1,n,dfn[top[x]],End[top[x]]);
x=fat[top[x]];
val[x].a[0][1]+=now.a[1][1]-pre.a[1][1];
val[x].a[1][0]+=min(now.a[1][1],now.a[0][1])-min(pre.a[1][1],pre.a[0][1]);
val[x].a[1][1]=val[x].a[1][0];
}
}
void until(int x){
val[x].a[0][1]=g[x][0];val[x].a[1][0]=val[x].a[1][1]=g[x][1];
while(x){
mat pre=query(1,1,n,dfn[top[x]],End[top[x]]);
update(1,1,n,dfn[x],val[x]);
mat now=query(1,1,n,dfn[top[x]],End[top[x]]);
x=fat[top[x]];
val[x].a[0][1]+=now.a[1][1]-pre.a[1][1];
val[x].a[1][0]+=min(now.a[1][1],now.a[0][1])-min(pre.a[1][1],pre.a[0][1]);
val[x].a[1][1]=val[x].a[1][0];
}
}
int main(){
scanf("%d%d%s",&n,&m,s);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
ed[x].push_back(y);
ed[y].push_back(x);
}
dfs1(1,0);
dfs2(1,1);
while(m--){
int a,x,b,y;
scanf("%d%d%d%d",&a,&x,&b,&y);
if(x==0&&y==0&&(fat[a]==b||fat[b]==a)) printf("-1\n");
else{
change(a,x);
change(b,y);
mat ans=query(1,1,n,dfn[1],End[1]);
printf("%lld\n",min(ans.a[0][1],ans.a[1][1]));
until(a);
until(b);
}
}
return 0;
}