#include <iostream>
#include <vector>
#include <numeric>
// Using global variables for simplicity as is common in competitive programming contests.
// These will be re-initialized for each test case.
std::vector<std::vector<int>> adj;
std::vector<long long> node_values;
std::vector<int> in_time;
std::vector<int> out_time;
std::vector<long long> subtree_sum;
int timer;
/**
* @brief Performs DFS from a node to compute subtree sums and discovery/finish times.
* @param u The current node (1-based).
* @param p The parent of the current node (1-based).
*/
void dfs(int u, int p) {
in_time[u] = ++timer;
// node_values is 0-indexed, while node u is 1-indexed.
subtree_sum[u] = node_values[u - 1];
for (int v : adj[u]) {
if (v != p) {
dfs(v, u);
subtree_sum[u] += subtree_sum[v];
}
}
out_time[u] = ++timer;
}
/**
* @brief Checks if node u is an ancestor of node v.
* @param u The potential ancestor node (1-based).
* @param v The potential descendant node (1-based).
* @return True if u is an ancestor of v, false otherwise.
*/
bool is_ancestor(int u, int v) {
if (u == 0 || v == 0) return false; // A fictional parent 0 is not a real node.
// A node is considered an ancestor of itself.
return in_time[u] <= in_time[v] && out_time[u] >= out_time[v];
}
/**
* @brief Solves the "Swap subtree" problem for one test case.
* @param N The number of nodes.
* @param A The vector of node values.
* @param edges The vector of edges in the tree.
* @param Q The number of queries.
* @param query The vector of queries.
* @return A vector of long long integers representing the answers to the queries.
*/
std::vector<long long> solve(int N, std::vector<int> A, std::vector<std::vector<int>> edges, int Q, std::vector<std::vector<int>> query) {
// 1. Initialize data structures for the current test case.
adj.assign(N + 1, std::vector<int>());
node_values.assign(A.begin(), A.end());
in_time.assign(N + 1, 0);
out_time.assign(N + 1, 0);
subtree_sum.assign(N + 1, 0LL);
timer = 0;
// 2. Build the adjacency list representation of the tree.
for (const auto& edge : edges) {
adj[edge[0]].push_back(edge[1]);
adj[edge[1]].push_back(edge[0]);
}
// 3. Pre-computation using DFS from the root (node 1).
dfs(1, 0); // The tree is rooted at 1, with a dummy parent 0.
std::vector<long long> results;
results.reserve(Q);
// 4. Process each query.
for (const auto& q : query) {
int U = q[0];
int V = q[1];
int X = q[2];
// Check the condition for not performing the swap.
if (is_ancestor(U, V) || is_ancestor(V, U)) {
// No swap needed. The answer is the pre-calculated subtree sum.
results.push_back(subtree_sum[X]);
} else {
// Swap is performed. Calculate the new sum for X's subtree.
long long current_ans = subtree_sum[X];
// If X is a *proper* ancestor of U, its subtree composition changes.
if (is_ancestor(X, U) && X != U) {
current_ans += subtree_sum[V] - subtree_sum[U];
}
// If X is a *proper* ancestor of V, its subtree composition changes.
if (is_ancestor(X, V) && X != V) {
current_ans += subtree_sum[U] - subtree_sum[V];
}
// Note: If X is not a proper ancestor (e.g., X=U, or X is in U's subtree, or X is unrelated),
// the conditions above are false, and the answer remains subtree_sum[X], which is correct.
results.push_back(current_ans);
}
}
return results;
}
// Main function to handle input/output as per the problem description.
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
std::cin >> T;
while (T--) {
int N;
std::cin >> N;
std::vector<int> A(N);
for (int i = 0; i < N; ++i) {
std::cin >> A[i];
}
std::vector<std::vector<int>> edges(N - 1, std::vector<int>(2));
for (int i = 0; i < N - 1; ++i) {
std::cin >> edges[i][0] >> edges[i][1];
}
int Q;
std::cin >> Q;
std::vector<std::vector<int>> query(Q, std::vector<int>(3));
for (int i = 0; i < Q; ++i) {
std::cin >> query[i][0] >> query[i][1] >> query[i][2];
}
// Call the solve function with the parsed input.
std::vector<long long> result = solve(N, A, edges, Q, query);
// Print the results for the current test case.
for (size_t i = 0; i < result.size(); ++i) {
std::cout << result[i] << (i == result.size() - 1 ? "" : " ");
}
std::cout << "\n";
}
return 0;
}