#include <bits/stdc++.h>
using namespace std;
#define short int32_t
#define int int64_t
#define long __int128_t
const int inf{numeric_limits<int>::max() / 4};
struct Edge {
int to, w, w_rev;
};
struct SegmentTree {
int size{};
vector<int> added{};
vector<pair<int, int>> maxs{};
SegmentTree(int size) : size(size) {
added.assign(size * 4, 0);
maxs.resize(size * 4);
_build(1, 0, size);
}
void _build(int node, int low, int high) {
maxs[node] = {0, low};
if (low == high - 1) {
return;
}
int mid{(low + high) / 2};
_build(node * 2, low, mid);
_build(node * 2 + 1, mid, high);
}
void add(int low, int high, int val) {
_add(1, 0, size, low, high, val);
}
void _add(int node, int low, int high, int qlow, int qhigh, int val) {
if (qlow >= high || qhigh <= low) {
return;
}
if (qlow <= low && qhigh >= high) {
added[node] += val;
maxs[node].first += val;
return;
}
int mid{(low + high) / 2};
_add(node * 2, low, mid, qlow, qhigh, val);
_add(node * 2 + 1, mid, high, qlow, qhigh, val);
maxs[node] = max(maxs[node * 2], maxs[node * 2 + 1]);
maxs[node].first += added[node];
}
pair<int, int> get_max(int low, int high) {
return _get_max(1, 0, size, low, high);
}
pair<int, int> _get_max(int node, int low, int high, int qlow, int qhigh) {
if (qlow >= high || qhigh <= low) {
return {-inf, 0};
}
if (qlow <= low && qhigh >= high) {
return maxs[node];
}
int mid{(low + high) / 2};
pair<int, int> res{max(
_get_max(node * 2, low, mid, qlow, qhigh),
_get_max(node * 2 + 1, mid, high, qlow, qhigh)
)};
res.first += added[node];
return res;
}
};
short main() {
#ifndef LOCAL
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#endif
int n;
cin >> n;
vector<vector<Edge>> edges(n);
int total_w{0};
for (int i{0}; i < n - 1; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
a--;
b--;
edges[a].push_back({b, c, d});
edges[b].push_back({a, d, c});
total_w += c + d;
}
vector<int> w_up(n);
vector<int> tin(n);
vector<int> tout(n);
vector<int> parents(n);
int timer{0};
function<void(int, int)> dfs1 = [&](int node, int parent) {
tin[node] = timer++;
parents[node] = parent;
for (auto [to, w, w_rev] : edges[node]) {
if (to != parent) {
dfs1(to, node);
w_up[tin[node]] += w_up[tin[to]] + w_rev;
}
}
tout[node] = timer;
};
dfs1(0, -1);
int best_center{0};
vector<int> w_in(n);
SegmentTree st(n);
function<void(int, int, int)> dfs2 = [&](int node, int w_root, int _w_down) {
st.add(tin[node], tin[node] + 1, w_root);
w_in[tin[node]] = w_up[tin[node]] + _w_down;
best_center = max(best_center, w_in[tin[node]]);
for (auto [to, w, w_rev] : edges[node]) {
if (to != parents[node]) {
dfs2(to, w_root + w, _w_down + w + w_up[tin[node]] - w_up[tin[to]] - w_rev);
}
}
};
dfs2(0, 0, 0);
int best_dia_w{-1};
int best_dia1{};
int best_dia2{};
function<void(int)> dfs3 = [&](int node) {
auto [max_w, max]{st.get_max(0, n)};
max_w += w_in[tin[node]];
if (max_w > best_dia_w) {
best_dia_w = max_w;
best_dia1 = node;
best_dia2 = max;
}
for (auto [to, w, w_rev] : edges[node]) {
if (to != parents[node]) {
st.add(0, n, w_rev);
st.add(tin[to], tout[to], -w - w_rev);
dfs3(to);
st.add(tin[to], tout[to], w + w_rev);
st.add(0, n, -w_rev);
}
}
};
dfs3(0);
int q;
cin >> q;
for (int i{0}; i < q; i++) {
int e;
cin >> e;
cout << total_w - (e == 1 ? best_center : e == 2 ? best_dia_w : -1) << "\n";
}
return 0;
}