#include <bits/stdc++.h>//喵内~
#define re register//喵内~
#define int long long
using namespace std;//喵内~
typedef long long ll;
typedef long double ld;
const int N = 1e5 + 5;//喵内~要填数字哟~
const int INF = 1145141919810114514;
inline int read(){
int s = 0,f = 1;char c = getchar();
while (!isdigit(c)){if (c == '-')f = -1;c = getchar();}
while (isdigit(c)){s = (s<<3) + (s<<1) + (c ^ 48);c = getchar();}
return s * f;
}//喵内~
set<pair<int,int> > st;
int head[N],cnt;
struct node{
int v,next;
}tree[N << 1];
int f[N][2],g[N][2],fh[N][20][2][2],val[N];
int dep[N],fa[N][20];
int n,m;
string s;
void add(int u,int v){
tree[++cnt].next = head[u];
tree[cnt].v = v;
head[u] = cnt;
}
void dfs(int u,int father){
dep[u] = dep[father] + 1;
f[u][1] = val[u];
fa[u][0] = father;
for (int i=head[u];i;i=tree[i].next){
int v = tree[i].v;if (v == father)continue;
dfs(v,u);
f[u][0] += f[v][1],f[u][1] += min(f[v][0],f[v][1]);
}
}
void dfs2(int u,int father){
for (int i=head[u];i;i=tree[i].next){
int v = tree[i].v;
if (v == father)continue;
g[v][0] = g[u][1] + f[u][1] - min(f[v][0],f[v][1]);
g[v][1] = min(g[u][0] + f[u][0] - f[v][1],g[v][0]);
//g[v][1] = min{g[x][0] + f[x][0] - f[v][1],g[u][1] + f[u][1] - min(f[v][0],f[v][1])};
dfs2(v,u);
}
}
int solve(int x,int a,int y,int b){
if (dep[x] < dep[y]){
swap(x,y),swap(a,b);
}
int tx[2] = {INF,INF},ty[2] = {INF,INF};
int nx[2],ny[2];
tx[a] = f[x][a],ty[b] = f[y][b];
//tx,ty 分别表示在 x,y 子树下取 z 的最xiao值,这个值跟初始 x,y 无关。
//nx,ny 用于更新最大值,作用不大。
for (int j=20;j >= 0;j--){
if (dep[fa[x][j]] >= dep[y]){
nx[0] = nx[1] = INF;
for (int u=0;u<2;u++)
for (int v=0;v<2;v++){
nx[v] = min(nx[v],tx[u] + fh[x][j][u][v]);
}
tx[1] = nx[1],tx[0] = nx[0],x = fa[x][j];
}
}
cout << tx[0] << " " << tx[1] << endl;
cout << ty[0] << " " << ty[1] << endl;
if (x == y)
return tx[b] + g[x][b];//b 以上的值的最xiao。
for (int j = 20;j >= 0;j--){
if (fa[x][j] != fa[y][j]){
nx[0] = nx[1] = ny[0] = ny[1] = INF;
for (int u=0;u<2;u++)
for (int v = 0;v < 2;v++){
nx[v] = min(nx[v],tx[u] + fh[x][j][u][v]);
ny[v] = min(ny[v],ty[u] + fh[y][j][u][v]);
}
tx[0] = nx[0],tx[1] = nx[1],x = fa[x][j];
ty[0] = ny[0],ty[1] = ny[1],y = fa[y][j];
}
}
int lca = fa[x][0];
cout << lca << endl;
// when lca is 0 or 1
cout << f[lca][0] << " " << f[x][1] << " " << f[y][1] << " " << tx[1] << " " << ty[1] << " " << g[lca][0] << endl;
int ans0 = f[lca][0] - f[x][1] - f[y][1] + tx[1] + ty[1] + g[lca][0];
// 把 x 和 y 两棵子树的数据切掉,换上新数据
int ans1 = f[lca][1] - min(f[x][0],f[x][1]) - min(f[y][0],f[y][1]) + min(tx[1],tx[0]) + min(ty[1],ty[0]) + g[lca][1];
cout << ans0 << " " << ans1 << endl;
return min(ans0,ans1);
}
signed main(){
n = read(),m = read(),cin >> s;
for (int i=1;i<=n;i++)val[i] = read();
for (int i=1,u,v;i<n;i++){
u = read(),v = read();
add(u,v),add(v,u);
st.insert(make_pair(u,v));
st.insert(make_pair(v,u));
}
dep[0] = 0;
dfs(1,0),dfs2(1,-1);
for (int i=1;i<=n;i++){
fh[i][0][0][0] = INF;
fh[i][0][0][1] = f[fa[i][0]][1] - min(f[i][0],f[i][1]);
fh[i][0][1][0] = f[fa[i][0]][0] - f[i][1];
fh[i][0][1][1] = f[fa[i][0]][1] - min(f[i][0],f[i][1]);
}
for (int j=1;j<=20;j++){
for (int i=1;i<=n;i++){
int tmp = fa[i][j-1];
fa[i][j] = fa[tmp][j-1];
for (int u = 0;u < 2;u++)
for (int v = 0;v < 2;v++){
fh[i][j][u][v] = INF;
for (int w = 0;w < 2;w++){
fh[i][j][u][v] = min(fh[i][j][u][v],fh[i][j-1][u][w] + fh[tmp][j-1][w][v]);
}
}
}
}
for (int i=1,a,b,x,y;i<=m;i++){
a = read(),x = read(),b = read(),y = read();
if (!x && !y && st.find(make_pair(a,b)) != st.end()){
puts("-1");
continue;
}
printf("%lld\n",solve(a,x,b,y));
}
return 0;
}//喵内~
/*
*/