#include <bits/stdc++.h>
using namespace std;
template <typename T>
void chkmax(T &x, T y) {
  if (x < y) x = y;
}
template <typename T>
void chkmin(T &x, T y) {
  if (x > y) x = y;
}
inline int read() {
  int x = 0;
  char c = getchar();
  bool f = 0;
  while (c < 48) f |= c == '-', c = getchar();
  while (c > 47) x = x * 10 + (c ^ 48), c = getchar();
  return f ? -x : x;
}
const int maxn = 1e5 + 10, P = 1e9 + 7;
int Inc(int x, int y) { return x + y < P ? x + y : x + y - P; }
int Dec(int x, int y) { return x < y ? x - y + P : x - y; }
void Add(int &x, int y) {
  x += y;
  if (x >= P) x -= P;
}
void Sub(int &x, int y) {
  x -= y;
  if (x < 0) x += P;
}
int qp(int a, int k) {
  int res = 1;
  for (; k; k >>= 1, a = 1ll * a * a % P)
    if (k & 1) res = 1ll * res * a % P;
  return res;
}
int n, q, ans[maxn];
bitset<10000010> ntp;
int ptt, pri[666000];
void sieve() {
  int N = 1e7;
  for (int i = (2), iend = (N); i <= iend; ++i) {
    if (!ntp[i]) pri[++ptt] = i;
    for (int j = (1), jend = (ptt); j <= jend; ++j) {
      int x = i * pri[j];
      if (x > N) break;
      ntp[x] = 1;
      if (i % pri[j] == 0) break;
    }
  }
}
vector<int> E[maxn];
int fa[maxn], sz[maxn], son[maxn], top[maxn], dep[maxn], dfn[maxn];
void dfs1(int u, int f) {
  sz[u] = 1, fa[u] = f, dep[u] = dep[f] + 1;
  for (int v : E[u])
    if (v != f) {
      dfs1(v, u), sz[u] += sz[v];
      if (sz[son[u]] < sz[v]) son[u] = v;
    }
}
void dfs2(int u, int tp) {
  static int now;
  dfn[u] = ++now, top[u] = tp;
  if (son[u]) dfs2(son[u], tp);
  for (int v : E[u])
    if (v != fa[u] && v != son[u]) dfs2(v, v);
}
int qlca(int u, int v) {
  for (; top[u] != top[v]; u = fa[top[u]]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
  }
  return dep[u] < dep[v] ? u : v;
}
int tot;
struct node {
  int x, p, u;
} dat[maxn * 16];
struct Querys {
  int u, v, anc;
} Q[maxn];
int zzh[maxn];
struct BIT {
  int c[maxn];
  void add(int pos, int x) {
    for (; pos <= n; pos += pos & -pos) c[pos] += x;
  }
  int query(int pos) {
    int res = 0;
    for (; pos; pos &= pos - 1) res += c[pos];
    return res;
  }
} bit;
void add_sub(int u, int x) {
  bit.add(dfn[u], x), bit.add(dfn[u] + sz[u], -x), zzh[u] += x;
}
int query_l(int id) {
  return bit.query(dfn[Q[id].u]) + bit.query(dfn[Q[id].v]) -
         bit.query(dfn[Q[id].anc]) * 2 + zzh[Q[id].anc];
}
void solve() {
  cin >> n;
  for (int i = (2), iend = (n); i <= iend; ++i) {
    int u = read(), v = read();
    E[u].push_back(v), E[v].push_back(u);
  }
  dfs1(1, 0), dfs2(1, 1);
  for (int u = (1), uend = (n); u <= uend; ++u) {
    int x = read();
    for (int i = (1), iend = (452); i <= iend; ++i) {
      int y = pri[i];
      if (x % y == 0) {
        int c = 0;
        do {
          x /= y, ++c;
        } while (x % y == 0);
        dat[++tot] = {y, c, u};
      }
    }
    if (x > 1) dat[++tot] = {x, 1, u};
  }
  cin >> q;
  for (int j = (1), jend = (q); j <= jend; ++j) {
    Q[j].u = read(), Q[j].v = read(), Q[j].anc = qlca(Q[j].u, Q[j].v),
    ans[j] = 1;
    int x = read();
    for (int i = (1), iend = (452); i <= iend; ++i) {
      int y = pri[i];
      if (x % y == 0) {
        int c = 0;
        do {
          x /= y, ++c;
        } while (x % y == 0);
        dat[++tot] = {y, c, -j};
      }
    }
    if (x > 1) dat[++tot] = {x, 1, -j};
  }
  sort(dat + 1, dat + tot + 1, [](node P, node Q) {
    return P.x < Q.x ||
           (P.x == Q.x && (P.p < Q.p || (P.p == Q.p && P.u < Q.u)));
  });
  for (int lef = (1), lefend = (tot); lef <= lefend; ++lef) {
    int rig = lef;
    while (dat[rig + 1].x == dat[lef].x) rig++;
    for (int i = (lef), iend = (rig); i <= iend; ++i) {
      auto tmp = dat[i];
      if (tmp.u > 0) {
        add_sub(tmp.u, tmp.p);
      } else {
        int id = -tmp.u;
        ans[id] = 1ll * ans[id] * qp(tmp.x, query_l(id)) % P;
      }
    }
    for (int i = (lef), iend = (rig); i <= iend; ++i) {
      auto tmp = dat[i];
      if (tmp.u > 0) {
        add_sub(tmp.u, -tmp.p);
      }
    }
    for (int i = (rig), iend = (lef); i >= iend; --i) {
      auto tmp = dat[i];
      if (tmp.u > 0) {
        add_sub(tmp.u, 1);
      } else {
        int id = -tmp.u;
        ans[id] = 1ll * ans[id] * qp(tmp.x, tmp.p * query_l(id)) % P;
      }
    }
    for (int i = (rig), iend = (lef); i >= iend; --i) {
      auto tmp = dat[i];
      if (tmp.u > 0) {
        add_sub(tmp.u, -1);
      }
    }
    lef = rig;
  }
  for (int i = (1), iend = (q); i <= iend; ++i) printf("%d\n", ans[i]);
}
signed main() {
  sieve();
  solve();
  return 0;
}
