#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, q, head[N], nxt[N], w[N];
void add(int f, int t) {
  static int cnt = 0;
  w[++cnt] = t;
  nxt[cnt] = head[f];
  head[f] = cnt;
}
struct bit {
  int a[N];
  void add(int p, int v) {
    for (; p <= n; p += p & -p) a[p] += v;
  }
  void add(int l, int r, int v) {
    add(l, v);
    add(r + 1, -v);
  }
  int query(int x) {
    int ans = 0;
    for (; x; x -= x & -x) ans += a[x];
    return ans;
  }
} T;
int dfn[N], size[N], fa[N], link[N], big[N];
void dfs(int x) {
  size[x] = 1;
  for (int i = head[x]; i; i = nxt[i]) {
    int v = w[i];
    if (size[v]) continue;
    fa[v] = x;
    dfs(v);
    size[x] += size[v];
    if (size[v] > size[big[x]]) big[x] = v;
  }
}
void divide(int x) {
  static int cnt = 0;
  dfn[x] = ++cnt;
  link[x] = (dfn[x] == dfn[fa[x]] + 1 ? link[fa[x]] : x);
  if (!big[x]) return;
  divide(big[x]);
  for (int i = head[x]; i; i = nxt[i])
    if (w[i] != fa[x] && w[i] != big[x]) divide(w[i]);
}
int lca(int x, int y) {
  for (; link[x] != link[y]; x = fa[link[x]])
    if (dfn[link[x]] < dfn[link[y]]) swap(x, y);
  return dfn[x] < dfn[y] ? x : y;
}
const int V = 1e7 + 10, M = 1e6 + 10;
bitset<V> isp;
int prime[M], id[V], pcnt;
void init() {
  int n = 1e7;
  for (int i = 2; i <= n; i++) {
    if (!isp[i]) prime[++pcnt] = i, id[i] = pcnt;
    for (int j = 1; j <= pcnt && i * prime[j] <= n; j++) {
      isp[i * prime[j]] = 1;
      if (i % prime[j] == 0) break;
    }
  }
}
struct opt {
  int id, u, v, T;
};
vector<opt> Q[M];
const int p = 1e9 + 7;
int mul(int x, int y) { return (long long)x * y % p; }
int power(int x, int y) {
  int ans = 1;
  for (; y; y >>= 1, x = mul(x, x))
    if (y & 1) ans = mul(ans, x);
  return ans;
}
int ans[N];
void change(int x, int val) {
  for (int i = 1; prime[i] * prime[i] <= val; i++)
    if (val % prime[i] == 0) {
      int c = 0;
      while (val % prime[i] == 0)
        Q[i].push_back((opt){0, x, 1, ++c}), val /= prime[i];
    }
  if (val > 1) Q[id[val]].push_back((opt){0, x, 1, 1});
}
void query(int u, int v, int val, int ID) {
  for (int i = 1; prime[i] * prime[i] <= val; i++)
    if (val % prime[i] == 0) {
      int c = 0;
      while (val % prime[i] == 0) val /= prime[i], c++;
      Q[i].push_back((opt){ID, u, v, c});
    }
  if (val > 1) Q[id[val]].push_back((opt){ID, u, v, 1});
}
bool cmp(const opt &a, const opt &b) {
  return a.T != b.T ? a.T < b.T : a.id < b.id;
}
void work(int pid) {
  vector<opt> &q = Q[pid];
  sort(q.begin(), q.end(), cmp);
  for (opt now : q) {
    int id = now.id, u = now.u, v = now.v;
    if (id == 0)
      T.add(dfn[u], dfn[u] + size[u] - 1, 1);
    else {
      int LCA = lca(u, v);
      int pw = T.query(dfn[u]) + T.query(dfn[v]) - T.query(dfn[LCA]) -
               T.query(dfn[fa[LCA]]);
      ans[id] = mul(ans[id], power(prime[pid], pw));
    }
  }
  for (opt now : q) {
    int id = now.id, u = now.u, v = now.v;
    if (id == 0) T.add(dfn[u], dfn[u] + size[u] - 1, -1);
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  dfs(1);
  divide(1);
  init();
  for (int i = 1, a; i <= n; i++) scanf("%d", &a), change(i, a);
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int u, v, x;
    scanf("%d%d%d", &u, &v, &x);
    query(u, v, x, i);
    ans[i] = 1;
  }
  for (int i = 1; i <= pcnt; i++) work(i);
  for (int i = 1; i <= q; i++) printf("%d\n", ans[i]);
  return 0;
}
