#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> adj;
vector<int> gifts;
vector<int> path;
bool findPath(int current, int target, int parent) {
path.push_back(current);
if (current == target) {
return true;
}
for (int neighbor : adj[current]) {
if (neighbor != parent) {
if (findPath(neighbor, target, current)) {
return true;
}
}
}
path.pop_back();
return false;
}
long long maxSubarraySum(const vector<int>& arr) {
if (arr.empty()) return 0;
long long maxSum = arr[0];
long long currentSum = arr[0];
for (size_t i = 1; i < arr.size(); i++) {
currentSum = max((long long)arr[i], currentSum + arr[i]);
maxSum = max(maxSum, currentSum);
}
return maxSum;
}
void maxHappiness(int N, int nodex[][2], int arr[], int nqs, int queries[][2]) {
adj.resize(N + 1);
gifts.resize(N + 1);
// Build adjacency list
for (int i = 0; i < N - 1; i++) {
int u = nodex[i][0];
int v = nodex[i][1];
adj[u].push_back(v);
adj[v].push_back(u);
}
// Store gift values
for (int i = 1; i <= N; i++) {
gifts[i] = arr[i - 1];
}
// Process queries
for (int i = 0; i < nqs; i++) {
int a = queries[i][0];
int b = queries[i][1];
path.clear();
findPath(a, b, -1);
// Create array of gift values along the path
vector<int> pathGifts;
for (int node : path) {
pathGifts.push_back(gifts[node]);
}
// Find maximum subarray sum and print
long long result = maxSubarraySum(pathGifts);
cout << result << endl;
}
}
int main() {
int N;
cin >> N;
int nodex[N][2];
for (int i = 0; i < N - 1; i++) {
cin >> nodex[i][0] >> nodex[i][1];
}
int arr[N];
for (int j = 0; j < N; j++) {
cin >> arr[j];
}
int nqs;
cin >> nqs;
int queries[nqs][2];
for (int k = 0; k < nqs; k++) {
cin >> queries[k][0] >> queries[k][1];
}
maxHappiness(N, nodex, arr, nqs, queries);
return 0;
}