#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
const int LG = 17;
typedef long long ll;
constexpr int MOD = 1e9 + 7;
int qpow(int x, int y = MOD - 2) {
int z = 1;
for (; y; y >>= 1, x = 1ll * x * x % MOD)
if (y & 1) z = 1ll * z * x % MOD;
return z;
}
void mod_r(int& x) {
if (x >= MOD) x -= MOD;
}
int mod(int x) { return x >= MOD ? x - MOD : x; }
namespace FIFO
{
char buf[1 << 23], *p1 = buf, *p2 = buf;
#ifndef Troverld
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#else
#define gc() getchar()
#endif
template<typename T>
void read(T& x) {
x = 0;
char c = gc();
while (c > '9' || c < '0') c = gc();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
}
template<typename T>
void print(T x) {
if (x <= 9) putchar('0' + x);
else print(x / 10), putchar('0' + x % 10);
}
} // namespace FIFO
using namespace FIFO;
int n, m, col[N];
vector<int> vcol[N];
namespace TRE
{
struct Chain {
int bot, top, x, y;
Chain(int B, int T, int W, int U) { bot = B, top = T, x = W, y = U; }
Chain() { bot = top = y = 0, x = 1; }
Chain rev() { return Chain(top, bot, x, y); }
} chain[N];
Chain merge(Chain u, Chain v, int val, int bon) {
return Chain((1ll * u.x * v.bot % MOD * val + u.bot) % MOD, (1ll * u.top * v.x % MOD * val + v.top) % MOD,
1ll * u.x * v.x % MOD * val % MOD, (1ll * u.top * v.bot % MOD * val + u.y + v.y + bon) % MOD);
}
Chain split(Chain u, Chain v, int val, int bon) {
int inv = qpow(1ll * v.x * val % MOD);
int whl = 1ll * u.x * inv % MOD;
int bot = mod(u.bot + MOD - 1ll * whl * v.bot % MOD * val % MOD);
int x = 1ll * (u.top + MOD - v.top) * inv % MOD;
int y = mod(u.y + MOD - (1ll * x * v.bot % MOD * val + v.y + bon) % MOD);
return Chain(bot, x, whl, y);
}
vector<int> G[N];
void aev(int x, int y) { G[x].push_back(y), G[y].push_back(x); }
int F1[N], F3[N], up[N][LG], dep[N], dfn[N], tot, F1_sum[N], F2[N], F1_inv[N], F2_inv[N];
int pas(int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
return 1ll * F1[x] * F1_inv[y] % MOD;
}
void dfs1(int x, int fa) {
F1[x] = 1, dep[x] = dep[fa] + 1, dfn[x] = ++tot;
for (auto y : G[x])
if (y != fa) dfs1(y, x), F1[x] = 1ll * F1[x] * (F1[y] + 1) % MOD, mod_r(F1_sum[x] += mod(F1_sum[y] + F1[y]));
F1_inv[x] = qpow(F1[x] + 1);
}
void dfs2(int x, int fa) {
for (auto y : G[x])
if (y != fa)
F2[y] = 1ll * F3[x] * F1_inv[y] % MOD, F2_inv[y] = qpow(F2[y] + 1), F3[y] = 1ll * (F2[y] + 1) * F1[y] % MOD,
dfs2(y, x);
}
void dfs3(int x, int fa) {
up[x][0] = fa;
for (int i = 1; i < LG; i++) up[x][i] = up[up[x][i - 1]][i - 1];
for (auto y : G[x])
if (y != fa)
chain[y] = merge(Chain(1, 1, 1, 0), chain[x], pas(x, y), mod(F1_sum[x] + MOD - mod(F1_sum[y] + F1[y]))), dfs3(y, x);
}
int find_ch(int x, int y) {
for (int i = LG - 1; i >= 0; i--)
if (dep[x] < dep[y] - (1 << i)) y = up[y][i];
return y;
}
Chain Path(int x, int y) {
int z = find_ch(x, y);
return split(chain[y], chain[x], pas(x, z), mod(F1_sum[x] + MOD - mod(F1_sum[z] + F1[z])));
}
int LCA(int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
for (int i = LG - 1; i >= 0; i--)
if (dep[x] <= (dep[y] - (1 << i))) y = up[y][i];
if (x == y) return x;
for (int i = LG - 1; i >= 0; i--)
if (up[x][i] != up[y][i]) x = up[x][i], y = up[y][i];
return up[x][0];
}
} // namespace TRE
using namespace TRE;
namespace IMG
{
int stk[N], tp, S[N], head[N], lam[N], cnt;
struct node {
int to, next, all, par;
} edge[N << 1];
bool vis[N];
int f[N][6][6][6], RT, SZ, sz[N], msz[N];
int a, b, c, A, B, C, res;
void upd_vtr_path(int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
Chain z = Path(x, y);
// printf("%d %d\n",x,y);
if (!A && !B && !C) mod_r(res += z.y);
edge[cnt].next = head[x], edge[cnt].to = y;
edge[cnt].all = z.x, edge[cnt].par = z.top, head[x] = cnt++;
int zz = find_ch(x, y);
lam[x] = 1ll * lam[x] * F1_inv[zz] % MOD;
if (!A && !B && !C) mod_r(res += MOD - mod(F1_sum[zz] + F1[zz]));
edge[cnt].next = head[y], edge[cnt].to = x;
edge[cnt].all = z.x, edge[cnt].par = z.bot, head[y] = cnt++;
lam[y] = 1ll * lam[y] * F2_inv[y] % MOD;
}
void ins(int x) {
if (!tp) {
stk[++tp] = x, SZ++;
return;
}
int lca = LCA(stk[tp], x);
while (tp >= 2 && dep[stk[tp - 1]] >= dep[lca]) upd_vtr_path(stk[tp - 1], stk[tp]), tp--;
if (dep[stk[tp]] > dep[lca]) upd_vtr_path(lca, stk[tp--]);
if (stk[tp] != lca) stk[++tp] = lca, SZ++;
if (stk[tp] != x) stk[++tp] = x, SZ++;
}
void fin() {
while (tp >= 2) upd_vtr_path(stk[tp - 1], stk[tp]), tp--;
tp = 0;
}
#define iter \
for (int i = head[x], y; i != -1; i = edge[i].next) \
if (!vis[y = edge[i].to])
void getroot(int x, int fa) {
sz[x] = 1, msz[x] = 0;
iter if (y != fa) getroot(y, x), sz[x] += sz[y], msz[x] = max(msz[x], sz[y]);
msz[x] = max(msz[x], SZ - sz[x]);
if (msz[x] < msz[RT]) RT = x;
}
void getsz(int x, int fa) {
sz[x] = 1;
iter if (y != fa) getsz(y, x), sz[x] += sz[y];
}
#define trit \
for (int _a = 0; _a <= A; _a++) \
for (int _b = 0; _b <= B; _b++) \
for (int _c = 0; _c <= C; _c++)
#define trin _a][_b][_c
int num, rec[N], lea[N], ALL[N], PAR[N], LAM[N];
void dfs4(int x, int fa) {
int id = ++num;
// printf("%d ",x);
rec[id] = col[x], LAM[id] = lam[x];
for (int i = head[x], y; i != -1; i = edge[i].next) {
if ((y = edge[i].to) == fa) continue;
if (vis[edge[i].to]) LAM[id] = 1ll * LAM[id] * edge[i].par % MOD;
else PAR[num + 1] = edge[i].par, ALL[num + 1] = edge[i].all, dfs4(y, x);
}
lea[id] = num;
}
void calc(int x) {
dfs4(x, 0);
for (int i = 1; i <= num; i++) trit f[i][trin] = 0;
f[1][rec[1] == a][rec[1] == b][rec[1] == c] = LAM[1];
for (int i = 2; i <= num; i++) {
trit {
int _A = _a + (rec[i] == a), _B = _b + (rec[i] == b), _C = _c + (rec[i] == c);
if (_A <= A && _B <= B && _C <= C)
f[i][_A][_B][_C] = (1ll * f[i - 1][trin] * ALL[i] % MOD * LAM[i] + f[i][_A][_B][_C]) % MOD;
}
trit f[lea[i]][trin] = (1ll * f[i - 1][trin] * PAR[i] + f[lea[i]][trin]) % MOD;
}
mod_r(res += f[num][A][B][C]), num = 0;
}
void solve(int x) {
calc(x), getsz(x, 0), vis[x] = true;
iter SZ = sz[y], RT = 0, getroot(y, 0), solve(RT);
}
void nil(int x, int fa) {
mod_r(res += F1_sum[x]);
iter if (y != fa) nil(y, x);
}
void reset(int x, int fa) {
for (int i = head[x], y; i != -1; i = edge[i].next)
if ((y = edge[i].to) != fa) reset(y, x);
lam[x] = F3[x], vis[x] = false, head[x] = -1;
}
void query() {
read(a), read(A), read(b), read(B), read(c), read(C);
if (A > vcol[a].size() || B > vcol[b].size() || C > vcol[c].size()) {
putchar('0'), putchar('\n');
return;
}
for (auto x : vcol[a]) S[++S[0]] = x;
for (auto x : vcol[b]) S[++S[0]] = x;
for (auto x : vcol[c]) S[++S[0]] = x;
sort(S + 1, S + S[0] + 1, [](int x, int y) { return dfn[x] < dfn[y]; });
if (S[1] != 1) ins(1);
for (int i = 1; i <= S[0]; i++) ins(S[i]);
fin();
if (!A && !B && !C) nil(1, 0);
getroot(1, 0), solve(RT);
print(res), putchar('\n');
RT = SZ = res = cnt = 0;
for (int i = 1; i <= S[0]; i++) S[i] = 0;
S[0] = 0, reset(1, 0);
}
} // namespace IMG
using namespace IMG;
int main() {
read(n), read(m), memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++) read(col[i]), vcol[col[i]].push_back(i);
for (int i = 1, x, y; i < n; i++) read(x), read(y), aev(x, y);
dfs1(1, 0), F3[1] = F1[1], dfs2(1, 0), dfs3(1, 0);
msz[0] = n;
for (int i = 1; i <= n; i++) lam[i] = F3[i];
for (int i = 1; i <= m; i++) query();
return 0;
}