#include <bits/stdc++.h>
using namespace std;
const int P = 1e9 + 7;
const int MAXN = 1e5 + 10;
const int MAXP = 1e6 + 10;
const int MAXV = 1e7 + 10;
struct edge {
  int to, nxt;
} e[MAXN << 1];
struct info {
  int value, home;
  bool type;
};
int tot, n, t;
int a[MAXN], depth[MAXN], prime[MAXP], head[MAXN], ans[MAXN], f[MAXV];
int cnt[MAXP][30], anc[MAXN][30];
vector<info> q[MAXN];
template <typename T>
inline void chkmax(T &x, T y) {
  x = max(x, y);
}
template <typename T>
inline void chkmin(T &x, T y) {
  x = min(x, y);
}
template <typename T>
inline void read(T &x) {
  T f = 1;
  x = 0;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -f;
  for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
  x *= f;
}
inline void addedge(int u, int v) {
  t++;
  e[t] = (edge){v, head[u]};
  head[u] = t;
}
inline int power(int a, int n) {
  int res = 1, b = a;
  while (n > 0) {
    if (n & 1) res = 1ll * res * b % P;
    b = 1ll * b * b % P;
    n >>= 1;
  }
  return res;
}
inline int inv(int x) { return power(x, P - 2); }
inline void dfs(int u, int fa) {
  depth[u] = depth[fa] + 1;
  for (int i = 1; i < 30; i++) {
    if (depth[u] <= (1 << i)) break;
    anc[u][i] = anc[anc[u][i - 1]][i - 1];
  }
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if (v == fa) continue;
    anc[v][0] = u;
    depth[v] = depth[u] + 1;
    dfs(v, u);
  }
}
inline int lca(int u, int v) {
  if (depth[u] > depth[v]) swap(u, v);
  for (int i = 30 - 1; i >= 0; i--) {
    if (depth[anc[v][i]] >= depth[u]) v = anc[v][i];
  }
  if (u == v) return u;
  for (int i = 30 - 1; i >= 0; i--) {
    if (anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
  }
  return anc[u][0];
}
inline void modify(int x, int delta) {
  for (int i = 1; 1ll * prime[i] * prime[i] <= x; i++) {
    if (x % prime[i] == 0) {
      int p = 0;
      while (x % prime[i] == 0) {
        x /= prime[i];
        p++;
      }
      cnt[i][p] += delta;
    }
  }
  if (x != 1) {
    int pos = lower_bound(prime + 1, prime + tot + 1, x) - prime;
    cnt[pos][1] += delta;
  }
}
inline int query(int x) {
  int ret = 1;
  for (int i = 1; 1ll * prime[i] * prime[i] <= x; i++) {
    if (x % prime[i] == 0) {
      int p = 0;
      while (x % prime[i] == 0) {
        p++;
        x /= prime[i];
      }
      int s = 0;
      for (int j = 1; j <= p; j++) s += cnt[i][j] * j;
      for (int j = p + 1; j < 30; j++) s += cnt[i][j] * p;
      ret = 1ll * ret * power(prime[i], s) % P;
    }
  }
  if (x != 1) {
    int pos = lower_bound(prime + 1, prime + tot + 1, x) - prime;
    int s = 0;
    for (int i = 1; i < 30; i++) s += cnt[pos][i];
    ret = 1ll * ret * power(x, s) % P;
  }
  return ret;
}
inline void solve(int u, int fa) {
  modify(a[u], 1);
  for (unsigned i = 0; i < q[u].size(); i++) {
    if (q[u][i].type)
      ans[q[u][i].home] = 1ll * ans[q[u][i].home] * query(q[u][i].value) % P;
    else
      ans[q[u][i].home] =
          1ll * ans[q[u][i].home] * inv(query(q[u][i].value)) % P;
  }
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if (v == fa) continue;
    solve(v, u);
  }
  modify(a[u], -1);
}
int main() {
  read(n);
  for (int i = 2; i < MAXV; i++) {
    if (!f[i]) {
      f[i] = i;
      prime[++tot] = i;
    }
    for (int j = 1; j <= tot; j++) {
      int tmp = i * prime[j];
      if (tmp >= MAXV) break;
      f[tmp] = prime[j];
      if (prime[j] == f[i]) break;
    }
  }
  for (int i = 1; i < n; i++) {
    int u, v;
    read(u);
    read(v);
    addedge(u, v);
    addedge(v, u);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++) read(a[i]);
  int Q;
  read(Q);
  for (int i = 1; i <= Q; i++) {
    int u, v, x;
    read(u);
    read(v);
    read(x);
    int Lca = lca(u, v);
    q[u].push_back((info){x, i, true});
    q[v].push_back((info){x, i, true});
    q[Lca].push_back((info){x, i, false});
    if (Lca != 1) q[anc[Lca][0]].push_back((info){x, i, false});
    ans[i] = 1;
  }
  solve(1, 0);
  for (int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
  return 0;
}
