#include using namespace std; const int MaxN = (int)4e5 + 10; const int MOD = (int)1e9 + 7; const int INF = (int)1e9; const int MaxL = 19; int n, in[MaxN], out[MaxN]; int timer, s, p, m, up[MaxN][MaxL]; vector < int > g[MaxN]; long long dp[MaxN]; long long tr[4 * MaxN], add[4 * MaxN]; int who[MaxN]; long long readInt(long long l,long long r,char endd){ long long x=0; int cnt=0; int fi=-1; bool is_neg=false; while(true){ char g=getchar(); if(g=='-'){ assert(fi==-1); is_neg=true; continue; } if('0'<=g && g<='9'){ x*=10; x+=g-'0'; if(cnt==0){ fi=g-'0'; } cnt++; assert(fi!=0 || cnt==1); assert(fi!=0 || is_neg==false); assert(!(cnt>19 || ( cnt==19 && fi>1) )); } else if(g==endd){ if(is_neg){ x= -x; } assert(l<=x && x<=r); return x; } else { assert(false); } } } string readString(int l,int r,char endd){ string ret=""; int cnt=0; while(true){ char g=getchar(); assert(g!=-1); if(g==endd){ break; } cnt++; ret+=g; } assert(l<=cnt && cnt<=r); return ret; } long long readIntSp(long long l,long long r){ return readInt(l,r,' '); } long long readIntLn(long long l,long long r){ return readInt(l,r,'\n'); } string readStringLn(int l,int r){ return readString(l,r,'\n'); } string readStringSp(int l,int r){ return readString(l,r,' '); } void dfs(int v, int p) { in[v] = ++timer; up[v][0] = p; for (int i = 1; i < MaxL; ++i) { up[v][i] = up[up[v][i - 1]][i - 1]; } for (int i = 0; i < (int)g[v].size(); ++i) { int to = g[v][i]; if (to == p) { continue; } dfs(to, v); } out[v] = timer; } bool isPar(int u, int v) { return in[u] <= in[v] && out[v] <= out[u]; } int getPar(int u, int v) { for (int i = MaxL - 1; i >= 0; --i) { if (up[u][i] != v && isPar(v, up[u][i])) { u = up[u][i]; } } return u; } void push(int v, int L, int R) { if (L != R) { add[v + v] = max(add[v + v], add[v]); add[v + v + 1] = max(add[v + v + 1], add[v]); } tr[v] = max(tr[v], add[v]); } void upd(int v, int L, int R, int l, int r, long long val) { if (l > r) { return; } push(v, L, R); if (L == l && r == R) { add[v] = max(add[v], val); push(v, L, R); return; } int M = (L + R) / 2; push(v, L, R); if (r <= M) { upd(v + v, L, M, l, r, val); push(v + v + 1, M + 1, R); } else if (l > M) { push(v + v, L, M); upd(v + v + 1, M + 1, R, l, r, val); } else { upd(v + v, L, M, l, M, val); upd(v + v + 1, M + 1, R, M + 1, r, val); } tr[v] = max(tr[v + v], tr[v + v + 1]); tr[v] = max(tr[v], add[v]); } long long get(int v, int L, int R, int l, int r) { if (l > r) { return -1LL << 60; } tr[v] = max(tr[v], add[v]); push(v, L, R); if (L == l && r == R) { return tr[v]; } int M = (L + R) / 2; push(v, L, R); if (r <= M) { push(v + v + 1, M + 1, R); return get(v + v, L, M, l, r); } if (l > M) { push(v + v, L, M); return get(v + v + 1, M + 1, R, l, r); } return max(get(v + v, L, M, l, M), get(v + v + 1, M + 1, R, M + 1, r)); } void build(int v, int l, int r) { if (l != r) { build(v + v, l, (l + r) / 2); build(v + v + 1, (l + r) / 2 + 1, r); tr[v] = max(tr[v + v], tr[v + v + 1]); } else { tr[v] = dp[l]; } add[v] = -1LL << 60; } int getWho(int v) { return who[v] == v ? v : who[v] = getWho(who[v]); } int en, em; void solve() { // scanf("%d%d%d", &n, &s, &p); n = readIntSp(1, 4e5); en += n; assert (en <= 4e5); s = readIntSp(1, n); p = readIntLn(1, 1e9); for (int i = 1; i <= n; ++i) { dp[i] = -1LL << 60; who[i] = i; } for (int i = 0; i < n - 1; ++i) { int x, y; // scanf("%d%d", &x, &y); x = readIntSp(1, n); y = readIntLn(1, n); assert (getWho(x) != getWho(y)); who[getWho(x)] = getWho(y); g[x].push_back(y); g[y].push_back(x); } dfs(1, 0); dp[in[s]] = p; build(1, 1, n); // scanf("%d", &m); m = readIntLn(1, 4e5); em += m; assert (em <= 4e5); for (int it = 0; it < m; ++it) { int u, v, r, t; // scanf("%d%d%d%d", &u, &v, &r, &t); u = readIntSp(1, 4e5); v = readIntSp(1, 4e5); assert (u != v); r = readIntSp(1, 1e9); t = readIntLn(-1e9, 1e9); r++; if (isPar(u, v)) { int w = getPar(v, u); long long X = max(get(1, 1, n, 1, in[w] - 1), get(1, 1, n, out[w] + 1, n)); long long Y = get(1, 1, n, in[v], out[v]); if (X >= r) { upd(1, 1, n, in[v], out[v], X + t); } if (Y >= r) { upd(1, 1, n, 1, in[w] - 1, Y + t); upd(1, 1, n, out[w] + 1, n, Y + t); } } else if (isPar(v, u)) { int w = getPar(u, v); long long X = get(1, 1, n, in[u], out[u]); long long Y = max(get(1, 1, n, 1, in[w] - 1), get(1, 1, n, out[w] + 1, n)); if (X >= r) { upd(1, 1, n, 1, in[w] - 1, X + t); upd(1, 1, n, out[w] + 1, n, X + t); } if (Y >= r) { upd(1, 1, n, in[u], out[u], Y + t); } } else { long long X = get(1, 1, n, in[u], out[u]); long long Y = get(1, 1, n, in[v], out[v]); if (X >= r) { upd(1, 1, n, in[v], out[v], X + t); } if (Y >= r) { upd(1, 1, n, in[u], out[u], Y + t); } } } for (int i = 1; i <= n; ++i) { g[i].clear(); } cout << max(tr[1], add[1]) << "\n"; timer = 0; } int main() { // freopen("input.txt", "r", stdin); int t = readIntLn(1, 1e3); // scanf("%d", &t); // t = 10; while (t --> 0) { solve(); } assert (getchar() == EOF); return 0; }