#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;
}