// Bai 3
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
constexpr int MAXN = 10000;
constexpr int MAXS = 10000; // giới hạn tổng (kích thước bitset - 1)
int n, q;
int c[MAXN + 5], w[MAXN + 5], par[MAXN + 5], ans[MAXN + 5];
vector<int> adj[MAXN + 5];
vector<int> splitv[MAXN + 5];
bitset<MAXS + 1> dp[MAXN + 5];
vector<pair<int,int>> queries[MAXN + 5];
void preDfs(int u, int p) {
par[u] = p;
for (int v : adj[u])
if (v != p) preDfs(v, u);
}
void dfs(int u) {
dp[u].reset();
dp[u].set(0);
for (int v : adj[u]) {
if (v == par[u]) continue;
dfs(v);
// merge dp[v] into dp[u]
// use tmp = dp[u] (before merge) and for each set bit j in dp[v], do dp[u] |= tmp << j
bitset<MAXS + 1> tmp = dp[u];
const bitset<MAXS + 1> &dpv = dp[v];
for (size_t j = dpv._Find_first(); j < dpv.size(); j = dpv._Find_next(j)) {
if ((int)j > MAXS) break;
// shifting tmp by j; bits beyond MAXS are discarded automatically
dp[u] |= (tmp << j);
}
// also include sums that come solely from dp[v]
dp[u] |= dpv;
}
// apply split (binary-split of multiplicities at node u)
for (int W : splitv[u]) {
if (W <= 0) continue;
dp[u] |= (dp[u] << W);
}
// answer queries for node u
if (!queries[u].empty()) {
// queries[u] stored as {-S, idx} and sorted ascending, so -S ascending -> S descending
// we'll process them in order but maintain a pointer curMax to avoid repeated scans
int curMax = MAXS;
for (auto &qr : queries[u]) {
int S = -qr.first;
int idx = qr.second;
if (curMax > S) curMax = S;
while (curMax >= 0 && !dp[u].test(curMax)) --curMax;
// dp[u].test(0) should be true always, so curMax >= 0
ans[idx] = max(0, curMax);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
if (fopen("MAIN.INP", "r")) {
freopen("MAIN.INP", "r", stdin);
freopen("MAIN.OUT", "w", stdout);
}
if (!(cin >> n)) return 0;
for (int u = 1; u <= n; ++u) cin >> w[u] >> c[u];
for (int i = 1; i < n; ++i) {
int u, v; cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// root tree at 1
preDfs(1, 0);
cin >> q;
for (int i = 0; i < q; ++i) {
int u, S; cin >> u >> S;
queries[u].push_back({-S, i}); // store -S to sort descending S
}
// prepare splits (binary decomposition of c[u] counts)
for (int u = 1; u <= n; ++u) {
sort(queries[u].begin(), queries[u].end()); // queries sorted by -S ascending -> S descending
int cnt = c[u];
for (int k = 1; k <= cnt; k <<= 1) {
splitv[u].push_back(k * w[u]);
cnt -= k;
}
if (cnt > 0) splitv[u].push_back(cnt * w[u]);
}
dfs(1);
for (int i = 0; i < q; ++i) cout << ans[i] << '\n';
return 0;
}