#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 1e5 + 5;
const int LOG = 32 - __builtin_clz(N_MAX);
const int Q_MAX = 1e5 + 5;
const int AX_MAX = 1e7 + 5;
const int MOD = 1e9 + 7;
int N, Q;
vector<int> adj[N_MAX];
int A[N_MAX];
int depth[N_MAX];
int ancestor[LOG][N_MAX];
int tour1, tour2;
int preorder[N_MAX];
int postorder_ancestors[N_MAX];
int postorder[N_MAX];
int smallest_factor[AX_MAX];
map<int, vector<pair<int, int>>> prime_nodes;
map<int, vector<pair<int, int>>> prime_queries;
struct query {
  int u, v, lca;
  int answer;
};
query queries[Q_MAX];
void prepare_primes() {
  memset(smallest_factor, -1, sizeof(smallest_factor));
  for (int i = 2; i < AX_MAX; i++)
    if (smallest_factor[i] == -1) {
      smallest_factor[i] = i;
      if ((long long)i * i >= AX_MAX) continue;
      for (int j = i * i; j < AX_MAX; j += i)
        if (smallest_factor[j] == -1) {
          smallest_factor[j] = i;
        }
    }
}
void dfs(int node, int parent) {
  ancestor[0][node] = parent;
  depth[node] = parent == -1 ? 0 : depth[parent] + 1;
  preorder[node] = tour1++;
  for (int neighbor : adj[node]) {
    if (neighbor != parent) dfs(neighbor, node);
  }
  postorder_ancestors[node] = tour1;
  postorder[node] = tour2++;
}
int lca(int a, int b) {
  if (depth[a] > depth[b]) swap(a, b);
  for (int k = 0; k < LOG; k++)
    if ((depth[b] - depth[a]) & 1 << k) b = ancestor[k][b];
  if (a == b) return a;
  assert(a != b && depth[a] == depth[b]);
  for (int k = LOG - 1; k >= 0; k--)
    if (ancestor[k][a] != ancestor[k][b]) {
      a = ancestor[k][a];
      b = ancestor[k][b];
    }
  assert(ancestor[0][a] == ancestor[0][b]);
  return ancestor[0][a];
}
void prepare_lca() {
  for (int k = 0; k + 1 < LOG; k++)
    for (int i = 0; i < N; i++)
      ancestor[k + 1][i] =
          ancestor[k][i] == -1 ? -1 : ancestor[k][ancestor[k][i]];
}
int tree[2][N_MAX];
int tree_sum(int t, int x) {
  int sum = 0;
  for (int i = x; i > 0; i -= i & -i) sum += tree[t][i];
  return sum;
}
void tree_update(int t, int x, int change) {
  for (int i = x + 1; i <= N + 1; i += i & -i) {
    tree[t][i] += change;
  }
}
void update_node(int node, int change) {
  tree_update(0, preorder[node], change);
  tree_update(1, postorder[node], change);
}
int query_node(int node) {
  if (node == -1) return 0;
  return tree_sum(0, postorder_ancestors[node]) - tree_sum(1, postorder[node]);
}
int mod_pow(long long a, long long b) {
  long long result = 1;
  while (b > 0) {
    if (b & 1) result = result * a % MOD;
    a = a * a % MOD;
    b >>= 1;
  }
  return result;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  assert(1 << LOG >= N_MAX);
  prepare_primes();
  cin >> N;
  for (int e = 0; e < N - 1; e++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  tour1 = tour2 = 0;
  dfs(0, -1);
  prepare_lca();
  for (int i = 0; i < N; i++) {
    cin >> A[i];
    while (A[i] > 1) {
      int p = smallest_factor[A[i]];
      int power = 0;
      assert(A[i] % p == 0);
      do {
        A[i] /= p;
        power++;
      } while (A[i] % p == 0);
      prime_nodes[p].push_back(make_pair(power, i));
    }
  }
  cin >> Q;
  for (int q = 0; q < Q; q++) {
    int u, v, x;
    cin >> u >> v >> x;
    u--;
    v--;
    queries[q].u = u;
    queries[q].v = v;
    queries[q].lca = lca(u, v);
    queries[q].answer = 1;
    while (x > 1) {
      int p = smallest_factor[x];
      int power = 0;
      assert(x % p == 0);
      do {
        x /= p;
        power++;
      } while (x % p == 0);
      prime_queries[p].push_back(make_pair(power, q));
    }
  }
  for (auto it = prime_queries.begin(); it != prime_queries.end(); it++) {
    int p = it->first;
    vector<pair<int, int>> &p_queries = it->second;
    vector<pair<int, int>> &p_nodes = prime_nodes[p];
    sort(p_queries.begin(), p_queries.end());
    sort(p_nodes.begin(), p_nodes.end());
    vector<pair<int, int>> tree_updates;
    int power = 0;
    for (pair<int, int> p_query : p_queries) {
      if (p_query.first > power) {
        for (pair<int, int> p_node : p_nodes)
          if (p_node.first > power) {
            int node = p_node.second;
            int change = min(p_node.first, p_query.first) - power;
            update_node(node, change);
            tree_updates.push_back(make_pair(node, change));
          }
        power = p_query.first;
      }
      int index = p_query.second;
      int exponent =
          query_node(queries[index].u) + query_node(queries[index].v);
      exponent -= query_node(queries[index].lca) +
                  query_node(ancestor[0][queries[index].lca]);
      queries[index].answer =
          (long long)queries[index].answer * mod_pow(p, exponent) % MOD;
    }
    for (pair<int, int> update : tree_updates)
      update_node(update.first, -update.second);
  }
  for (int q = 0; q < Q; q++) {
    cout << queries[q].answer << '\n';
  }
  return 0;
}
