#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void make_ett(int node, int parent, int& nodes_in_tour, const vector<vector<int>>& tree, vector<pair<int, int>>& subtree_range)
{
	subtree_range[node].first = nodes_in_tour; nodes_in_tour++;
	for (int neighbor : tree[node]){
		if (neighbor != parent)
			make_ett(neighbor, node, nodes_in_tour, tree, subtree_range);}
	subtree_range[node].second = nodes_in_tour;
}

void make_ett_lca(int node, int prnt, int height, const vector<vector<int>>& tree, vector<int>& frst_ett, vector<pair<int, int>>& h)
{
	frst_ett[node] = h.size(); h.emplace_back(height, node);
	for (int neighbor : tree[node])
	{
		if (neighbor != prnt)
		{
			h.emplace_back(height, node);
			make_ett_lca(neighbor, node, height + 1, tree, frst_ett, h);
		}
	}
}

class sgmnt_tr
{
public:
	sgmnt_tr(const vector<ll>& elements);
	void upd(int position, ll delta);
	ll sum(int l, int r);
private:
	int el_cnt;
	vector<ll> tree;
};

class m_sgmnt_tr
{
public:
	m_sgmnt_tr(const vector<pair<int, int>>& elements);
	int min_query(int l, int r);
private:
	int el_cnt;
	vector<pair<int, int>> tree;
};

ll dfs_calc_brute(int node, const vector<vector<int>>& tree, sgmnt_tr& seg_tree, const vector<pair<int,int>>& tr_rng, int curr_dst, int parent = -1)
{
	ll val = seg_tree.sum(tr_rng[node].first, tr_rng[node].first + 1);
	ll sol = curr_dst * val;
	for (int neighbor : tree[node])
		if (neighbor != parent)
			sol += dfs_calc_brute(neighbor, tree, seg_tree, tr_rng, curr_dst + 1, node);
	return sol;
}

ll calc_brute(int node, const vector<vector<int>>& tree, sgmnt_tr& seg_tree, const vector<pair<int, int>>& tr_rng)
{
	return dfs_calc_brute(node, tree, seg_tree, tr_rng, 0);
}

void dfs_calc_seg_tree(int node, const vector<vector<int>>& tree, const vector<pair<int,int>>& tr_rng, sgmnt_tr& seg_tree, vector<ll>& costs, int parent = -1)
{
	if (parent != -1)
	{
		ll ts = seg_tree.sum(0, tree.size());
		int l = tr_rng[node].first, r = tr_rng[node].second;
		ll x = seg_tree.sum(l, r), to_add = ts - x;
		costs[node] = costs[parent] + to_add - x;
	}
	for (int neighbor: tree[node])
		if (neighbor != parent)
			dfs_calc_seg_tree(neighbor, tree, tr_rng, seg_tree, costs, node);
}

pair<int,ll> find_min_pos(const vector<vector<int>>& tree, sgmnt_tr& seg_tree, const vector<pair<int,int>>& tr_rng)
{
	int n = tree.size();
	vector<ll> costs(n);
	costs[0] = calc_brute(0, tree, seg_tree, tr_rng);
	dfs_calc_seg_tree(0, tree, tr_rng, seg_tree, costs);
	int min_pos = -1;
	ll min_val = LLONG_MAX;
	for (int i = 0; i < n; i++){
		if (costs[i] < min_val){min_val = costs[i];min_pos = i;}
	}
	return { min_pos,min_val };
}

void dfs_mk_prnts(int node, const vector<vector<int>>& tree, vector<int>& parent_arr, int parent = -1)
{
	parent_arr[node] = parent;
	for (int neighbor: tree[node])
		if (neighbor != parent)
			dfs_mk_prnts(neighbor, tree, parent_arr, node);
}

vector<int> mk_prnt_arr(const vector<vector<int>>& tree)
{
	vector<int> parent_arr(tree.size());
	dfs_mk_prnts(0, tree, parent_arr);
	return parent_arr;
}

vector<int> solve(const vector<vector<int>>& tree, const vector<ll>& values, const vector<pair<ll, int>>& queries)
{
	int n = tree.size();
	auto parent_arr = mk_prnt_arr(tree);
	int x = 0;
	vector<pair<int, int>> subtree_range(n);
	make_ett(0, -1, x, tree, subtree_range);
	vector<ll> shifted_values(values.size());
	for (int i = 0; i < n; i++)
		shifted_values[subtree_range[i].first] = values[i];
	
	auto seg_tree = sgmnt_tr(shifted_values);

	vector<pair<int, int>> heights; heights.reserve(n);
	vector<int> first_occurence_euler(n);
	make_ett_lca(0, -1, 0, tree, first_occurence_euler, heights);
	m_sgmnt_tr lca_tree(heights);
	
	auto min_pos_val = find_min_pos(tree, seg_tree, subtree_range);
	int min_pos = min_pos_val.first; ll min_val = min_pos_val.second;
	vector<int> solution(queries.size()+1);
	solution[0] = min_pos;
	for (int i = 0; i < queries.size(); i++)
	{
		ll ammount_to_add = queries[i].first;
		int updated_node = queries[i].second;
		seg_tree.upd(subtree_range[updated_node].first, ammount_to_add);

		int l = min(first_occurence_euler[updated_node], first_occurence_euler[min_pos]);
		int r = max(first_occurence_euler[updated_node], first_occurence_euler[min_pos]);
		int lca = lca_tree.min_query(l, r+1);

		int temp = min_pos;
		int dist = 0;
		while (temp != lca)
		{
			temp = parent_arr[temp];
			dist++;
		}
		temp = updated_node;
		while (temp != lca)
		{
			temp = parent_arr[temp];
			dist++;
		}

		ll current_val = min_val + dist * ammount_to_add;
		min_val = current_val;
		temp = min_pos;
		ll tree_sum = seg_tree.sum(0, n);
		while (temp != lca)
		{
			int l = subtree_range[temp].first;
			int r = subtree_range[temp].second;
			ll subtree_sum = seg_tree.sum(l, r);
			ll to_sub = tree_sum - subtree_sum;
			current_val = current_val + subtree_sum - to_sub;
			temp = parent_arr[temp];
			if (current_val < min_val)
			{
				min_val = current_val;
				min_pos = temp;
			}
			else if (current_val == min_val)
			{
				min_pos = min(min_pos, temp);
			}
		}

		vector<int> path;
		temp = updated_node;
		while (temp != lca)
		{
			path.push_back(temp);
			temp = parent_arr[temp];
		}
		reverse(path.begin(), path.end());
		for (int node: path)
		{
			int l = subtree_range[node].first;
			int r = subtree_range[node].second;
			ll subtree_sum = seg_tree.sum(l, r);
			ll to_add = tree_sum - subtree_sum;
			current_val = current_val + to_add - subtree_sum;
			if (current_val < min_val)
			{
				min_val = current_val;
				min_pos = node;
			}
			else if (current_val == min_val)
			{
				min_pos = min(min_pos, node);
			}
		}

		solution[i + 1] = min_pos;
	}
	return solution;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int n; cin >> n;
	vector<vector<int>> tree(n, vector<int>());
	for (int i = 0; i < n-1; i++)
	{
		int a, b; cin >> a >> b;
		a--; b--;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}
	vector<ll> values(n);
	for (int i = 0; i < n; i++)
		cin >> values[i];

	int query_cnt; cin >> query_cnt;
	vector<pair<ll, int>> queries(query_cnt);
	for (int i = 0; i < query_cnt; i++)
	{
		cin >> queries[i].first >> queries[i].second;
		queries[i].second--;
	}
	auto sol = solve(tree, values, queries);
	for (int x: sol)
	{
		cout << x+1 << "\n";
	}
	return 0;
}


sgmnt_tr::sgmnt_tr(const vector<ll>& elements)
{
	el_cnt = elements.size();
	tree = vector<ll>(el_cnt * 2);
	copy(elements.begin(), elements.end(), tree.begin() + el_cnt);
	for (int i = el_cnt - 1; i > 0; i--)
		tree[i] = tree[i * 2] + tree[i * 2 + 1];
}

void sgmnt_tr::upd(int position, ll delta)
{
	position += el_cnt;
	tree[position] += delta;
	for (int i = position / 2; i > 0; i /= 2)
		tree[i] = tree[i * 2] + tree[i * 2 + 1];
}

ll sgmnt_tr::sum(int l, int r)
{
	l += el_cnt; r += el_cnt;
	ll sum = 0;
	while (l < r)
	{
		if (l % 2 == 1)
			sum += tree[l++];
		if (r % 2 == 1)
			sum += tree[--r];

		l /= 2; r /= 2;
	}
	return sum;
}

m_sgmnt_tr::m_sgmnt_tr(const vector<pair<int, int>>& elements)
{
	el_cnt = elements.size();
	tree = vector<pair<int, int>>(2 * el_cnt);
	copy(elements.begin(), elements.end(), tree.begin() + el_cnt);
	for (int i = el_cnt - 1; i > 0; i--)
	{
		tree[i] = min(tree[2 * i], tree[2 * i + 1]);
	}
}

int m_sgmnt_tr::min_query(int l, int r)
{
	l += el_cnt;
	r += el_cnt;
	pair<int, int> solution = { INT_MAX,INT_MAX };
	while (l < r)
	{
		if (l % 2 == 1)
		{
			solution = min(solution, tree[l++]);
		}
		if (r % 2 == 1)
		{
			solution = min(solution, tree[--r]);
		}
		l /= 2;
		r /= 2;
	}
	return solution.second;
}