#include<bits/stdc++.h>
using namespace std;
#define MX 400000000009ll
struct mat{
long long v[2][2];
mat(){
v[0][0] = v[1][1] = 0;
v[0][1] = v[1][0] = MX;
}
}pm[100009],seg[400009];
inline mat mpt(){
mat c = mat();
c.v[1][1] = MX;
c.v[0][1] = 0;
return c;
}
mat operator*(mat x,mat y){
mat z;
z.v[0][0] = min(x.v[0][0] + y.v[0][0],x.v[0][1] + y.v[1][0]);
z.v[0][1] = min(x.v[0][0] + y.v[0][1],x.v[0][1] + y.v[1][1]);
z.v[1][0] = min(x.v[1][0] + y.v[0][0],x.v[1][1] + y.v[1][0]);
z.v[1][1] = min(x.v[1][0] + y.v[0][1],x.v[1][1] + y.v[1][1]);
return z;
}
void change(int k,int l,int r,int pl,mat val){
if(l == r){
seg[k] = val;
return;
}
int m = (l + r) >> 1;
if(m < pl)
change((k << 1) | 1,m + 1,r,pl,val);
else
change((k << 1),l,m,pl,val);
seg[k] = seg[(k << 1) | 1] * seg[(k << 1)];
}
mat query(int k,int l,int r,int lq,int rq){
if(lq > r || rq < l)
return mat();
if(lq <= l && r <= rq){
return seg[k];
}
int m = (l + r) >> 1;
return query((k << 1) | 1,m + 1,r,lq,rq) * query((k << 1),l,m,lq,rq);
}
int n,q,dfscnt,dfs[100009],top[100009],fa[100009],dep[100009],p[100009],dfsl[100009],sz[100009];
vector<int>e[100009];
long long sg[100009][2],dp[100009][2],tg[100009][2];
void srh1(int v){
dep[v] = dep[fa[v]] + 1;
sz[v] = 1;
int p = 0;
for(int i = 0; i < e[v].size(); i ++){
if(e[v][i] == fa[v]){
swap(e[v][i],e[v][e[v].size() - 1]);
e[v].pop_back();
if(i == e[v].size())
break;
}
fa[e[v][i]] = v;
srh1(e[v][i]);
sz[v] += sz[e[v][i]];
if(sz[e[v][i]] > sz[e[v][p]])
p = i;
}
if(e[v].size() > 0)
swap(e[v][p],e[v][0]);
}
void srh2(int v){
dfs[v] = ++dfscnt;
dfsl[v] = dfs[v];
dp[v][1] = sg[v][1] = p[v];
if(e[v].size() > 0){
top[e[v][0]] = top[v];
srh2(e[v][0]);
dfsl[v] = dfsl[e[v][0]];
dp[v][0] += dp[e[v][0]][1];
dp[v][1] += min(dp[e[v][0]][1],dp[e[v][0]][0]);
for(int i = 1; i < e[v].size(); i ++){
top[e[v][i]] = e[v][i];
srh2(e[v][i]);
sg[v][0] = sg[v][0] + dp[e[v][i]][1];
sg[v][1] = sg[v][1] + min(dp[e[v][i]][0],dp[e[v][i]][1]);
dp[v][0] = dp[v][0] + dp[e[v][i]][1];
dp[v][1] = dp[v][1] + min(dp[e[v][i]][0],dp[e[v][i]][1]);
}
}
pm[v].v[0][0] = MX;
pm[v].v[1][0] = sg[v][0];
pm[v].v[0][1] = sg[v][1];
pm[v].v[1][1] = sg[v][1];
tg[v][0] = sg[v][0];
tg[v][1] = sg[v][1];
change(1,1,n,dfs[v],pm[v]);
}
void p_change(int v,mat val){
while(true){
int o = top[v];
if(o == 1){
change(1,1,n,dfs[v],val);
break;
}
else{
mat m = mpt() * query(1,1,n,dfs[o],dfsl[o]);
tg[fa[o]][0] -= m.v[0][1];
tg[fa[o]][1] -= min(m.v[0][0],m.v[0][1]);
change(1,1,n,dfs[v],val);
m = mpt() * query(1,1,n,dfs[o],dfsl[o]);
tg[fa[o]][0] += m.v[0][1];
tg[fa[o]][1] += min(m.v[0][0],m.v[0][1]);
val.v[0][0] = MX;
val.v[1][0] = tg[fa[o]][0];
val.v[0][1] = val.v[1][1] = tg[fa[o]][1];
v = fa[o];
}
}
}
int main(){
scanf("%d %d",&n,&q);
scanf(" %*s");
for(int i = 1; i <= n; i ++){
scanf("%d",&p[i]);
}
for(int i = 1; i < n; i ++){
int u,v;
scanf("%d %d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
srh1(1);
top[1] = 1;
srh2(1);
for(int i = 1; i <= q; i ++){
int a,x,b,y;
scanf("%d %d %d %d",&a,&x,&b,&y);
if(dep[a] < dep[b]){
swap(a,b);
swap(x,y);
}
if(fa[a] == b && x == 0 && y == 0){
puts("-1");
}
else{
mat m = pm[a];
m.v[0][1] = (x == 1) ? sg[a][1] - MX - p[a] : sg[a][1] + MX - p[a];
m.v[1][1] = (x == 1) ? sg[a][1] - MX - p[a] : sg[a][1] + MX - p[a];
p_change(a,m);
m = pm[b];
m.v[0][1] = (y == 1) ? sg[b][1] - MX - p[b] : sg[b][1] + MX - p[b];
m.v[1][1] = (y == 1) ? sg[b][1] - MX - p[b] : sg[b][1] + MX - p[b];
p_change(b,m);
m = mpt() * query(1,1,n,dfs[1],dfsl[1]);
printf("%lld\n",min(m.v[0][0],m.v[0][1]) + (x + y) * MX + x * p[a] + y * p[b]);
p_change(a,pm[a]);
p_change(b,pm[b]);
}
}
return 0;
}