A group of researchers are studying fish population in a natural system of lakes and rivers. The system contains $$$n$$$ lakes connected by $$$n - 1$$$ rivers. Each river has integer length (in kilometers) and can be traversed in both directions. It is possible to travel between any pair of lakes by traversing the rivers (that is, the network of lakes and rivers form a tree).There is an unknown number of indistinguishable fish living in the lakes. On day $$$1$$$, fish can be at arbitrary lakes. Fish can travel between lakes by swimming the rivers. Each fish can swim a river $$$l$$$ kilometers long in any direction in $$$l$$$ days. Further, each fish can stay any number of days in any particular lake it visits. No fish ever appear or disappear from the lake system. Each lake can accomodate any number of fish at any time.The researchers made several observations. The $$$j$$$-th of these observations is "on day $$$d_j$$$ there were at least $$$f_j$$$ distinct fish in the lake $$$p_j$$$". Help the researchers in determining the smallest possible total number of fish living in the lake system that doesn't contradict the observations.

The first line contains a single integer $$$n$$$ ($$$1 \leq n \leq 10^5$$$) — the number of lakes in the system. The next $$$n - 1$$$ lines describe the rivers. The $$$i$$$-th of these lines contains three integers $$$u_i$$$, $$$v_i$$$, $$$l_i$$$ ($$$1 \leq u_i, v_i \leq n$$$, $$$u_i \neq v_i$$$, $$$1 \leq l_i \leq 10^3$$$) — $$$1$$$-based indices of lakes connected by the $$$i$$$-th river, and the length of this river. The next line contains a single integer $$$k$$$ ($$$1 \leq k \leq 10^5$$$) — the number of observations. The next $$$k$$$ lines describe the observations. The $$$j$$$-th of these lines contains three integers $$$d_j$$$, $$$f_j$$$, $$$p_j$$$ ($$$1 \leq d_j \leq 10^8$$$, $$$1 \leq f_j \leq 10^4$$$, $$$1 \leq p_j \leq n$$$) — the day, the number of fish, and the lake index of the $$$j$$$-th observation. No two observations happen on the same day at the same lake simultaneously.

Print one integer — the smallest total number of fish not contradicting the observations.

NoteIn the first example, there could be one fish swimming through lakes $$$2$$$, $$$1$$$, and $$$4$$$, and the second fish swimming through lakes $$$3$$$, $$$1$$$, and $$$2$$$.In the second example a single fish can not possibly be part of all observations simultaneously, but two fish swimming $$$2 \to 1 \to 4$$$ and $$$3 \to 1 \to 5$$$ can.In the third example one fish can move from lake $$$1$$$ to lake $$$5$$$, others staying in their lakes during all time: two fish in lake $$$4$$$, six fish in lake $$$5$$$, one fish in lake $$$3$$$. The system of lakes is shown on the picture.

#include<bits/stdc++.h>
using namespace std;
#define Rep(i, l, r) for (__typeof(l) i = l, i##_end = r; i != i##_end; ++i)
typedef pair<int, int> pii;
const int N = 1e5 + 10;
int n, m;
int tot, fi[N], a[N << 1], ne[N << 1], c[N << 1];
vector<pii> g[N];
struct Node {
    int pos, df, *delta;
    inline int TruePos() const {
        return pos + (df >= 0 ? -*delta: *delta);
    }
    inline void Merge(const Node &v) {
        assert(delta == v.delta);
        if (bool(df >= 0) != bool(df + v.df >= 0)) pos = v.pos;
        df += v.df;
    }
    inline friend bool operator<(const Node &u, const Node &v) {
        return u.TruePos() < v.TruePos();
    }
};
int *all[N];
set<Node> st[N];
struct Adj {
    int dis;
    set<Node>::iterator it;
    inline friend bool operator<(const Adj &u, const Adj &v) {
        return u.dis < v.dis || (u.dis == v.dis && u.it->TruePos() < v.it->TruePos());
    }
};
multiset<Adj> diff[N];
inline void Add(int x, int y, int z) {
    a[++tot] = y; ne[tot] = fi[x]; fi[x] = tot; c[tot] = z;
}
inline void AddDiff(int x, set<Node>::iterator it) {
    if (prev(it)->df < 0 && next(it)->df >= 0) diff[x].erase(diff[x].find((Adj){next(it)->pos - prev(it)->pos, prev(it)}));
    if (prev(it)->df < 0 && it->df >= 0) diff[x].insert((Adj){it->pos - prev(it)->pos, prev(it)});
    if (it->df < 0 && next(it)->df >= 0) diff[x].insert((Adj){next(it)->pos - it->pos, it});
}
inline void RemoveDiff(int x, set<Node>::iterator it) {
    if (prev(it)->df < 0 && it->df >= 0) diff[x].erase(diff[x].find((Adj){it->pos - prev(it)->pos, prev(it)}));
    if (it->df < 0 && next(it)->df >= 0) diff[x].erase(diff[x].find((Adj){next(it)->pos - it->pos, it}));
    if (prev(it)->df < 0 && next(it)->df >= 0) diff[x].insert((Adj){next(it)->pos - prev(it)->pos, prev(it)});
    st[x].erase(it);
}
inline void Insert(int x, int pos, int df) {
    Node np({pos + (df >= 0 ? *all[x] : -*all[x]), df, all[x]});
    auto nxt = st[x].lower_bound(np);
    if (nxt->TruePos() == np.TruePos()) {
        np.Merge(*nxt);
        RemoveDiff(x, nxt);
    }
    AddDiff(x, st[x].insert(np).first);
}
inline void Advance(int x, int l) {
    int nall = (*all[x] + l) * 2;
    while (!diff[x].empty() && diff[x].begin()->dis <= nall) {
        auto u = diff[x].begin()->it, v = next(u);
        Node nd(*u);
        nd.Merge(*v);
        RemoveDiff(x, u);
        RemoveDiff(x, v);
        AddDiff(x, st[x].insert(nd).first);
    }
    *all[x] += l;
}
inline int GetIncrease(int x, int tpos) {
    Node np({tpos + *all[x], 0, all[x]});
    set<Node>::iterator it = st[x].lower_bound(np);
    int ans = 0;
    if (it->TruePos() == tpos) {
        if (it->df < 0) ans = max(ans, -it->df);
        ++it;
    }
    if (it->TruePos() == tpos + 1) {
        if (it->df > 0) ans = max(ans, it->df);
    }
    return ans;
}
inline void Dfs(int x, int fa, int l) {
    all[x] = new int(0);
    st[x].insert((Node){(int)-2e9, 0, all[x]});
    st[x].insert((Node){(int)2e9, -1, all[x]});
    for (int i = fi[x]; i; i = ne[i]) if (a[i] != fa) {
        Dfs(a[i], x, c[i]);
        if (st[x].size() < st[a[i]].size()) {
            st[x].swap(st[a[i]]);
            diff[x].swap(diff[a[i]]);
            swap(all[x], all[a[i]]);
        }
        Rep(it, ++st[a[i]].begin(), --st[a[i]].end())
            Insert(x, it->TruePos(), it->df);
    }
    Rep(it, g[x].begin(), g[x].end()) {
        int tmp = GetIncrease(x, it->first);
        it->second = max(0, it->second - tmp);
    }
    Advance(x, 1);
    Rep(it, g[x].begin(), g[x].end()) if (it->second) {
        Insert(x, it->first, it->second);
        Insert(x, it->first + 1, -it->second);
    }
    Advance(x, l - 1);
}
int main() {
    scanf("%d", &n);
    for (int i = 1, x, y, z; i < n; ++i) {
        scanf("%d%d%d", &x, &y, &z);
        z <<= 1; Add(x, y, z); Add(y, x, z);
    }
    scanf("%d", &m);
    for (int i = 1, day, fish, pos; i <= m; ++i) {
        scanf("%d%d%d", &day, &fish, &pos);
        g[pos].push_back(pii(day << 1, fish));
    }
    Dfs(1, 0, 1);
    int ans = 0, cur = 0;
    Rep(it, ++st[1].begin(), --st[1].end()) ans = max(ans, cur += it->df);
    printf("%d\n", ans);
    return 0;
}

#include <cstdio>
#include <vector>
#include <random>
#include <algorithm>

int n,head[100001],nxt[200001],b[200001],v[200001],k,q;
std::vector<std::pair<int,int> >vec[100001];
int lson[400001],rson[400001],size[400001],cnt,pri[400001],lazy[400001],root[100001];
int stk[400001],top;
long long sum[400001];
struct info{
	int pos,val;
	void change(int x){
		if(val>=0)pos-=x;
		else pos+=x;
	}
}se[400001],l[400001],r[400001],mn[400001];
info min(info a,info b){return a.val<b.val?a:b;}
info merge(info b,info a){
//	printf("merge %d %d %d %d\n",b.pos,a.pos,b.val,a.val);
	if(a.val>=0&&b.val<0)return (info){b.pos,a.pos-b.pos};
	else return (info){0,0x7f7f7f7f};
}
void pushdown(int x,int y){
	if(!x)return;
	se[x].change(y);
	l[x].change(y);
	r[x].change(y);
	if(mn[x].val!=0x7f7f7f7f){
		mn[x].pos+=y;
		mn[x].val-=(y<<1);
	}
	lazy[x]+=y;
}
void spread(int x){
	if(lazy[x]){
		pushdown(lson[x],lazy[x]);
		pushdown(rson[x],lazy[x]);
		lazy[x]=0;
	}
}
void pushup(int x){
	l[x]=r[x]=se[x];
	mn[x]=(info){0,0x7f7f7f7f};
	if(lson[x]){
		l[x]=l[lson[x]];
		mn[x]=min(mn[x],min(mn[lson[x]],merge(r[lson[x]],se[x])));
	}
	if(rson[x]){
		r[x]=r[rson[x]];
		mn[x]=min(mn[x],min(mn[rson[x]],merge(se[x],l[rson[x]])));
	}
	size[x]=1+size[lson[x]]+size[rson[x]];
	sum[x]=1ll*se[x].val+sum[lson[x]]+sum[rson[x]];
}
void split(int now,int &x,int &y,int v){
	spread(now);
	if(!now)x=y=0;
	else{
		if(se[now].pos<=v)x=now,split(rson[now],rson[now],y,v);
		else y=now,split(lson[now],x,lson[now],v);
		pushup(now);
	}
}
int merge(int a,int b){
	if(!a||!b)return a|b;
	spread(a),spread(b);
	if(pri[a]<pri[b]){
		rson[a]=merge(rson[a],b);
		pushup(a);
		return a;
	}
	else{
		lson[b]=merge(a,lson[b]);
		pushup(b);
		return b;
	}
}
int Newnode(info x){
	int u=top?stk[top--]:++cnt;
	lson[u]=rson[u]=0;
	size[u]=1;
	lazy[u]=0;
	l[u]=r[u]=se[u]=x;
	mn[u]=(info){0,0x7f7f7f7f};
	sum[u]=x.val;
//	printf("Newnode %d %d %d\n",x.pos,x.val,u);
	return u;
}
void addr(int t1,int v){
	if(rson[t1])spread(t1),addr(rson[t1],v);
	else se[t1].val+=v;
	pushup(t1);
}
void addl(int t1,int v){
	if(lson[t1])spread(t1),addl(lson[t1],v);
	else se[t1].val+=v;
	pushup(t1);
}
void add(int &rt,info x){
	int t1,t2;
	split(rt,t1,t2,x.pos);
	if(t1&&r[t1].pos==x.pos)addr(t1,x.val);
	else t1=merge(t1,Newnode(x));
	rt=merge(t1,t2);
}
void Merge(int a,int &rt){
	if(!a)return;
	spread(a);
	add(rt,se[a]);
	Merge(lson[a],rt);
	Merge(rson[a],rt);
	stk[++top]=a;
}
void debug(int x){
	if(!x)return;
	spread(x);
	debug(lson[x]);
	printf("(%d %d %d)",se[x].pos,se[x].val,mn[x].val);
	debug(rson[x]);
}
void move(int &rt,int v){
	if(!rt)return;
//	printf("move %d\n",v);
//	debug(rt);putchar('\n');
	while(mn[rt].val<=(v<<1)){
		int t1,t2,t3;
//		printf("%d\n",mn[rt].val);
		split(rt,t1,t2,mn[rt].pos);
		if(r[t1].val+l[t2].val<0){
			addr(t1,l[t2].val);
			split(t2,t3,t2,l[t2].pos);
			stk[++top]=t3;
		}
		else{
			addl(t2,r[t1].val);
			split(t1,t1,t3,r[t1].pos-1);
			stk[++top]=t3;
		}
		rt=merge(t1,t2);
	}
	pushdown(rt,v);
//	debug(rt);putchar('\n');
}
long long f(int rt,long long v){
	if(!rt)return 0;
	spread(rt);
	if(se[rt].pos<=v)return sum[lson[rt]]+se[rt].val+f(rson[rt],v);
	else return f(lson[rt],v);
}
void push(int s,int t,int val){
	nxt[++k]=head[s];
	head[s]=k;
	b[k]=t;
	v[k]=val;
}
void dfs(int x,int f,int v=0){
	for(int i=head[x];i;i=nxt[i])
		if(b[i]!=f){
			dfs(b[i],x,::v[i]);
			if(size[root[x]]<size[root[b[i]]])std::swap(root[x],root[b[i]]);
			Merge(root[b[i]],root[x]);
		}
	if(x==1){
		for(int i=0;i<vec[x].size();i++){
			add(root[x],(info){vec[x][i].first<<1,vec[x][i].second});
			add(root[x],(info){vec[x][i].first<<1|1,-vec[x][i].second});
		}
	}
	else{
		for(int i=0;i<vec[x].size();i++)vec[x][i].second+=::f(root[x],vec[x][i].first<<1ll);
		move(root[x],1);
		for(int i=0;i<vec[x].size();i++){
			long long tem=::f(root[x],vec[x][i].first<<1ll);
			if(tem<vec[x][i].second){
				add(root[x],(info){vec[x][i].first<<1,vec[x][i].second-tem});
				add(root[x],(info){vec[x][i].first<<1|1,-(vec[x][i].second-tem)});
			}
		}
		move(root[x],(v<<1)-1);
	}
//	printf("dfs %d\n",x);
//	debug(root[x]);putchar('\n');
}
long long now,ans;
void getans(int x){
	if(!x)return;
	spread(x);
	getans(lson[x]);
	ans=std::max(ans,now+=se[x].val);
	getans(rson[x]);
}
int main(){
	scanf("%d",&n);
	std::mt19937 rand(19260817);
	for(int i=1;i<=400000;i++)pri[i]=rand();
	for(int i=1,u,v,val;i<n;i++)scanf("%d%d%d",&u,&v,&val),push(u,v,val),push(v,u,val);
	scanf("%d",&q);
	for(int i=1,d,f,p;i<=q;i++){
		scanf("%d%d%d",&d,&f,&p);
		vec[p].push_back(std::make_pair(d,f));
	}
	dfs(1,0);
	getans(root[1]);
	printf("%lld\n",ans);
}

/*
ID: bqi3431
PROG: ~
LANG: C++11
*/

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define beg(x) x.begin()
#define en(x) x.end()
#define all(x) beg(x), en(x)
#define resz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 100005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    template<class U> modular(const U& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }
    friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular exp(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) { return invGeneral(a.val,MOD); }
    // inv is equivalent to return exp(b,b.mod-2) if prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

struct seg {
    map<int,int> neg, pos;
    set<pair<int,pi>> dif;
    int lazy;
    int size() { return sz(pos)+sz(neg); }
    vpi change() {
        map<int,int> v;
        trav(t,pos) v[t.f-lazy] += t.s;
        trav(t,neg) v[t.f+lazy] += t.s;
        return vpi(all(v));
    }
    bool ok(auto negIt, auto posIt) {
        return negIt->f+2*lazy <= posIt->f;
    }
    void printInfo() {
    	ps("LAZY: ",lazy);
    	pr("NEG: "); trav(t,neg) pr(mp(t.f+lazy,t.s),' '); ps();
    	pr("POS: "); trav(t,pos) pr(mp(t.f-lazy,t.s),' '); ps();
    	pr("DIF: "); trav(t,dif) pr(mp(t.f-2*lazy,mp(t.s.f+lazy,t.s.s-lazy)),' '); ps();
    }
    void nrem(map<int,int>::iterator it) {
        auto it1 = pos.lb(it->f+2*lazy);
        if (it1 != pos.end() && (next(it) == neg.end() || !ok(next(it),it1)))
            dif.erase({it1->f-it->f,{it->f,it1->f}});
    }
    void nins(map<int,int>::iterator it) {
        auto it1 = pos.lb(it->f+2*lazy);
        if (it1 != pos.end() && (next(it) == neg.end() || !ok(next(it),it1)))
            dif.insert({it1->f-it->f,{it->f,it1->f}});
    }
    void prem(map<int,int>::iterator it) {
        auto it1 = neg.ub(it->f-2*lazy); if (it1 == neg.begin()) return;
        it1 --;
        if (it == pos.begin() || !ok(it1,prev(it)))
            dif.erase({it->f-it1->f,{it1->f,it->f}});
    }
    void pins(map<int,int>::iterator it) {
        auto it1 = neg.ub(it->f-2*lazy); if (it1 == neg.begin()) return;
        it1 --;
        if (it == pos.begin() || !ok(it1,prev(it)))
            dif.insert({it->f-it1->f,{it1->f,it->f}});
    }
    void insPos(int t, int f) {
        auto it = neg.ub(t-2*lazy);
        if (it != neg.begin()) nrem(prev(it));
        pos[t] += f;
        if (it != neg.begin()) nins(prev(it));
    }
    void insNeg(int t, int f) {
        auto it = pos.lb(t+2*lazy);
        if (it != pos.end()) prem(it);
        neg[t] += f;
        if (it != pos.end()) pins(it);
    }
    void ins(int t, int f) {
        // printInfo();
        if (f == 0) return;
        if (f > 0) insPos(t+lazy,f);
        else insNeg(t-lazy,f);
        /*ps("INS",t,f);
        printInfo();
        ps("-----");*/
    }
    void INS(int t, int f) {
        ins(t-1,f); ins(t,-f);
    }
    int getUpd(int x) {
    	int res = 0;
    	if (neg.count(x-lazy-1)) ckmax(res,-neg[x-lazy-1]);
    	if (pos.count(x+lazy)) ckmax(res,pos[x+lazy]);
    	// neg: x-lazy-1
    	// pos: x+lazy
    	return res;
    }
    void adv(int x) {
        /*ps("START ADV ",x);
        printInfo();
        ps("----");*/
        while (sz(dif) && dif.begin()->f <= 2*lazy+2*x) {
            auto a = *dif.begin(); nrem(neg.find(a.s.f));
            int tot = neg[a.s.f]+pos[a.s.s]; neg.erase(a.s.f), pos.erase(a.s.s);
            if (tot < 0) {
                neg[a.s.f] = tot;
                nins(neg.find(a.s.f));
                // ps("NINS");
            } else if (tot > 0) {
                pos[a.s.s] = tot;
                pins(pos.find(a.s.s));
                // ps("PINS");
            } else {
                auto it = neg.lb(a.s.f);
                if (it != neg.begin()) nins(prev(it));
            }
            /*printInfo();
            ps("----");*/
            // erase one or two
            // maintain dif
        }
        //ps("WUT",co);  if (co == 100) exit(0);
        lazy += x;
        // printInfo(); ps("DONE----");
    }
};

int n,k;
vpi o[MX], adj[MX];
seg S[MX];

void init() {
	setIO(); re(n);
	F0R(i,n-1) {
	    int u,v,l; re(u,v,l); l *= 2;
	    // ps("HA",u,v,l);
	    adj[u].pb({v,l}), adj[v].pb({u,l});
	}
	re(k);
	F0R(i,k) {
	    int d,f,p; re(d,f,p); d *= 2;
	    // ps("OH",d,f,p);
	    o[p].pb({d,f});
	}
}

void dfs(int x, int p, int l) {
    trav(t,adj[x]) if (t.f != p) {
        dfs(t.f,x,t.s);
        if (sz(S[t.f]) > sz(S[x])) swap(S[x],S[t.f]);
        auto v = S[t.f].change();
        trav(t,v) S[x].ins(t.f,t.s);
    }
    // ps("WUT",x,l);
    if (!l) {
	    trav(t,o[x]) S[x].INS(t.f,t.s);
    } else {
	    trav(t,o[x]) t.s = max(0,t.s-S[x].getUpd(t.f));
	    S[x].adv(1); trav(t,o[x]) S[x].INS(t.f,t.s);
	    S[x].adv(l-1);
    }
    // ps("HUH",x,S[x].change(),l);
}

int main() {
	init();
	dfs(1,0,0);
	auto v = S[1].change();
	int cur = 0, ret = 0;
	trav(t,v) ckmax(ret,cur += t.s);
	ps(ret);
    // you should actually read the stuff at the bottom
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type){
			if(x.id==y.id) return x.type>y.type;
			else return x.type<y.type;
		}
		if(x.type==-1) return x.id>y.id;
		else return x.id<y.id;
	}
};
bool cmp(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type<y.type;
	return x.id<y.id;
}

bool cmp2(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type>y.type;
	return x.id<y.id;
}
bool cmp3(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.id!=y.id) return x.id<y.id;
	return x.type>y.type;
}
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	bool check_find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		return s.find(x)!=s.end();
	}
	K find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		return to_outside_form(*it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
//		printf("[+%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
//		printf("[-%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
//		if(!s.empty()){
//			x=*s.begin();
//			printf("[^%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
//		}
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void insert2(K x,int len){
		while(1){
			K y,z;
			bool f1,f2;
			insert(x);
			s.get_pos(x,y,f1,z,f2);
			if(f1&&check_k2(y,x)){
				if(x.time-y.time<len){
					erase(x);
					erase(y);
					if(x.x==y.x) break;
					else if(x.x<y.x){
						y.x-=x.x;
						x.x=0;
						insert(y);
						break;
					}else{
						x.x-=y.x;
						y.x=0;
					}
				}else break;
			}else break;
		}
	}
	void insert3(K x,K nxt,int len){
		while(1){
			K y,z; bool f1,f2;
			insert(x); s.get_pos(x,y,f1,z,f2);
			if(f2&&check_k2(x,z)&&z.time-x.time<len&&cmp(z,nxt)){
				erase(x); erase(z);
				if(x.x==z.x) break;
				else if(x.x<z.x){
					z.x-=x.x;
					x.x=0;
					insert(z);
					break;
				}else{
					x.x-=z.x;
					z.x=0;
				}
			}else break;
		}
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
//			printf("[*%d %d %d %d]\n",k.p1.type,k.p1.id,k.p2.type,k.p2.id);
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f); printf("->");
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		sort(f.begin(),f.end(),cmp2);
		for(int i=0;i<f.size();++i){
//			printf("(%d %d %d %d)",f[i].time,f[i].x,f[i].type,f[i].id);
			sum+=f[i].type*f[i].x;
//			printf("[%d]\n",sum);
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
int ti=0;
void dfs(int x,int pre,int len){
	for(int i=0;i<ff[x].size();i+=2){
		ff[x][i].id=ff[x][i+1].id=++ti;
		op[x].insert(ff[x][i]);
		op[x].insert(ff[x][i+1]);
	}
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
			merge(op[x],op[y]);
		}
	}
	op[x].update(len+len+(x==1));
}
map<int,vector<K> > mp;
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	dfs(1,0,0);
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type){
			if(x.id==y.id) return x.type>y.type;
			else return x.type<y.type;
		}
		if(x.type==-1) return x.id>y.id;
		else return x.id<y.id;
	}
};
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		for(int i=0;i<f.size();++i){
			sum+=f[i].type*f[i].x;
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
int ti=0;
void dfs(int x,int pre,int len){
	for(int i=0;i<ff[x].size();i+=2){
		ff[x][i].id=ff[x][i+1].id=++ti;
		op[x].insert(ff[x][i]);
		op[x].insert(ff[x][i+1]);
	}
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
			merge(op[x],op[y]);
		}
	}
	op[x].update(len+len+(x==1));
}
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	dfs(1,0,0);
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		bool yesl = 0, yesr = 0;
		auto tmpl = dpl[x].lower_bound(mp(u.y - wl, -oo));
		if (tmpl != dpl[x].end() && tmpl->x == u.y - wl)
		{
			yesl = 1;
			sum += tmpl->y;
		}
		auto tmpr = dpr[x].lower_bound(mp(u.y - wr, -oo));
		if (tmpr != dpr[x].end() && tmpr->x == u.y - wr)
		{
			yesr = 1;
			sum += tmpr->y;
		}
		if (yesl && yesr)
		{
			dpl[x].erase(tmpl);
			dpr[x].erase(tmpr);
			if (sum > 0) insertl(u.y, sum, x, u.x);
			else insertr(u.y, sum, x, u.x);
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) + SZ(dpr[x]) < SZ(dpl[y.x]) + SZ(dpr[y.x]))
			{
				swap(dpl[x], dpl[y.x]);
				swap(dpr[x], dpr[y.x]);
			}
			for (auto u : dpl[y.x]) insertl(u.x + dis[x], u.y, x, dis[x]);
			dpl[y.x].clear();

			for (auto u : dpr[y.x]) insertr(u.x - dis[x], u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
		tmp += u.y;
		chkmax(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

const int64_t INF=2e9+7;
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;
    return false;
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A){
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t){
    while(collide.size()&&collide.begin()->time2<t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  current_time=-depth[node];
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
  }
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node]){
    f.second=dss[node].prep(f.first,f.second);
  }
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  current_time=-depth[node];
  current_time=-depth[node];
  for(auto f:fish[node]){
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
  current_time=-depth[node];
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  printf("%I64d\n",dss[0].query());
  return 0;
}

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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

int maxflow;

struct ysp{
	map<int,int> left,right;
	priority_queue<pi,vc<pi>,greater<pi>> qs;
	int lo,ro,qo;
	ysp():lo(0),ro(0),qo(0){}
	int size(){return left.size()+right.size();}
	void addqleft(int x){
		dmp(x);
		auto itr=right.lower_bound(x+lo-ro);
		if(itr!=right.ed){
			int d=itr->a+ro-(x+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,x);
		}
	}
	void addqright(int x){
		dmp(x);
		auto itr=left.upper_bound(x+ro-lo);
		if(itr!=left.bg){
			--itr;
			int d=x+ro-(itr->a+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,itr->a);
		}
	}
	void insertleft(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=lo;
		left[x]+=v;
		addqleft(x);
	}
	void insertright(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=ro;
		right[x]+=v;
		addqright(x);
	}
	void Expand(int w){
		dmp(qo);
		dmp(qs.size());
		while(w&&qs.size()){
			pi z=qs.top();qs.pop();
			z.a+=qo;
			assert(z.a>=0);
			dmp(z);
			int u=min(w,z.a);
			dmp(u);
			w-=u;
			z.a-=u;
			qo-=u;
			lo+=u;
			ro-=u;
			if(z.a==0){
				dmp2(z.b,z.b+lo-ro);
				auto l=left.find(z.b);
				auto r=right.find(z.b+lo-ro);
				if(l!=left.ed&&r!=right.ed){
					int y=min(l->b,r->b);
					maxflow+=y;
					int f=-1;
					l->b-=y;
					if(l->b==0)left.erase(l);
					else f=0;
					r->b-=y;
					if(r->b==0)right.erase(r);
					else f=1;
					if(f==0){
						addqleft(l->a);
					}else if(f==1){
						addqright(r->a);
					}else{
						l=left.upper_bound(z.b);
						if(l!=left.bg)
							addqleft(prev(l)->a);
					}
				}
			}else
				qs.emplace(z.a-qo,z.b);
		}
		qo-=w;
		lo+=w;
		ro-=w;
	}
	void show(){
		/*dmp(lo);
		for(auto kv:left)
			//dmp(kv);
			dmp(pi(kv.a+lo,kv.b));
		dmp(ro);
		for(auto kv:right)
			//dmp(kv);
			dmp(pi(kv.a+ro,kv.b));
		*/
	}
};

void merge(ysp&a,ysp&b){
	if(a.size()<b.size())swap(a,b);
	for(auto z:b.left)
		a.insertleft(z.a+b.lo,z.b);
	for(auto z:b.right)
		a.insertright(z.a+b.ro,z.b);
}

const int nmax=100010;

vc<pi> t[nmax];
vc<pi> obs[nmax];
ysp buf[nmax];

void dfs(int v,int p){
	buf[v]=ysp();
	sort(all(obs[v]));
	for(auto z:obs[v]){
		buf[v].insertright(z.a*2,z.b);
		buf[v].insertleft(z.a*2+2,z.b);
	}
	for(auto e:t[v])if(e.a!=p){
		dfs(e.a,v);
		buf[e.a].Expand(e.b*2);
		merge(buf[v],buf[e.a]);
	}
	dmp(v);
	dmp(maxflow);
	buf[v].show();
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	const int vmax=ten(9);

	int n;cin>>n;
	rep(_,n-1){
		int u,v,l;cin>>u>>v>>l;
		u--;v--;
		l*=vmax;
		l-=2;
		t[u].eb(v,l);
		t[v].eb(u,l);
	}

	int ans=0;
	int k;cin>>k;
	rep(_,k){
		int d,f,p;cin>>d>>f>>p;
		d*=vmax;
		p--;
		obs[p].eb(d,f);
		ans+=f;
	}

	dfs(0,-1);
	dmp(maxflow);
	buf[0].show();
	buf[0].Expand(inf);
	dmp(maxflow);

	if(0){
		rep(_,10){
			int tmp=maxflow;
			maxflow=0;
			int r=rand_int(0,n-1);
			dfs(r,-1);
			buf[r].Expand(inf);
			dmp2(tmp,maxflow);
			assert(tmp==maxflow);
		}
	}

	cout<<ans-maxflow<<endl;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

vector<pair<int, int>> adj[N], fish[N];
int n, m, now, depth[N];

struct node_t {
  int x, d, v;

  node_t(int x, int d, int v, int t = 0):x(x - d * t), d(d), v(v) {
  }

  bool operator < (const node_t &b) const {
    int p = x + now * d, q = b.x + now * b.d;
    return p == q ? d < b.d : p < q;
  }
};

struct collision_t {
  node_t x, y;
  int when;

  collision_t(node_t x, node_t y):x(x), y(y) {
    when = y.x - x.x >> 1;
  }

  bool operator < (const collision_t &b) const {
    if (when != b.when) {
      return when < b.when;
    } else {
      return make_tuple(x.x, x.v, y.x, y.v) < make_tuple(b.x.x, b.x.v, b.y.x, b.y.v);
    }
  }
};

struct info_t {
  set<collision_t> collisions;
  set<node_t> nodes;

  void insert_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.insert(collision_t(x, y));
    }
  }

  void erase_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.erase(collision_t(x, y));
    }
  }

  void insert(node_t x) {
    if (!x.v) {
      return;
    }
    if (nodes.find(x) != nodes.end()) {
      x.v += nodes.find(x)->v;
      erase(*nodes.find(x));
    }
    auto it = nodes.insert(x).first, next = it;
    ++next;
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      if (next != nodes.end()) {
        erase_collision(*prev, *next);
      }
      insert_collision(*prev, x);
    }
    if (next != nodes.end()) {
      insert_collision(x, *next);
    }
  }

  void erase(node_t x) {
    auto it = nodes.find(x), next = it;
    ++next;
    if (next != nodes.end()) {
      erase_collision(x, *next);
    }
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      erase_collision(*prev, x);
      if (next != nodes.end()) {
        insert_collision(*prev, *next);
      }
    }
    nodes.erase(it);
  }

  int reset(int x, int y) {
    node_t l(x + 1, -1, y, now), r(x - 1, 1, y, now);
    return max(0, y - max(nodes.find(l) == nodes.end() ? 0 : nodes.find(l)->v, nodes.find(r) == nodes.end() ? 0 : nodes.find(r)->v));
  }

  node_t cancel(node_t x, node_t y) {
    if (x.v > y.v) {
      return node_t(x.x, x.d, x.v - y.v);
    } else {
      return node_t(y.x, y.d, y.v - x.v);
    }
  }

  void collide(collision_t x) {
    erase(x.x);
    erase(x.y);
    insert(cancel(x.x, x.y));
  }

  void maintain(int x) {
    while (!collisions.empty() && collisions.begin()->when <= x) {
      collide(*collisions.begin());
    }
  }

  void merge(info_t &b) {
    if (nodes.size() < b.nodes.size()) {
      swap(nodes, b.nodes);
      swap(collisions, b.collisions);
    }
    for (auto x : b.nodes) {
      insert(x);
    }
  }

  int query() {
    int answer = 0;
    for (auto x : nodes) {
      if (x.d > 0) {
        answer += x.v;
      }
    }
    return answer;
  }
} info[N];

void dfs(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      depth[y] = depth[x] + w;
      dfs(y, x);
    }
  }
}

void solve(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      solve(y, x);
      now = -depth[y];
      info[y].maintain(-(depth[x] + 1));
      now = -(depth[x] + 1);
      info[x].merge(info[y]);
    }
  }
  now = -(depth[x] + 1);
  for (auto &e : fish[x]) {
    e.second = info[x].reset(e.first, e.second);
  }
  info[x].maintain(-depth[x]);
  now = -depth[x];
  for (auto e : fish[x]) {
    info[x].insert(node_t(e.first, -1, e.second, now));
    info[x].insert(node_t(e.first, 1, e.second, now));
  }
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    --x;
    --y;
    w <<= 1;
    adj[x].emplace_back(y, w);
    adj[y].emplace_back(x, w);
  }
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    int day, value, where;
    scanf("%d %d %d", &day, &value, &where);
    day <<= 1;
    --where;
    fish[where].emplace_back(day, value);
  }
  dfs(0, -1);
  solve(0, -1);
  info[0].maintain(INT_MAX);
  printf("%d\n", info[0].query());
  return 0;
}

/**
 * This line was copied from template
 * This is nk_ok_clear.cpp
 *
 * @author: Nikolay Kalinin
 * @date: Fri, 10 Aug 2018 10:17:56 +0300
 */
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
using D = double;
using uint = unsigned int;
template<typename T>
using pair2 = pair<T, T>;
template<typename T> T sgn(T a) { return (a < 0 ? -1 : (a > 0 ? 1 : 0)); }

#ifdef WIN32
    #define LLD "%I64d"
#else
    #define LLD "%lld"
#endif

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second

const int maxn = 100005;
const int inf = 1e9;

vector<pair2<int>> gr[maxn], qs[maxn];
int sz[maxn];
int n, q;
int TIME = 0;

class tans
{
public:
    struct tpoint
    {
        int x, diff;

        tpoint(int x_, int diff_, int time = TIME): diff(diff_)
        {
            x = x_ + sgn(diff) * time;
        }

        int pos(int time = TIME) const
        {
            return x - sgn(diff) * time;
        }

        bool operator<(const tpoint &other) const
        {
            return pos() < other.pos();
        }
    };

    using ppoint = set<tpoint>::iterator;

    struct tseg : pair<int, ppoint> {
        bool operator<(const tseg &other) const
        {
            if (fi != other.fi) return fi < other.fi;
            return second->pos() < other.second->pos();
        }

        tseg(int a, const ppoint &b): pair<int, ppoint>(a, b) {}
    };

    set<tseg> small;
    set<tpoint> bounds;

    void addsegment(ppoint l, ppoint r)
    {
        int speed = sgn(r->diff) - sgn(l->diff);
        if (speed > 0)
        {
            int t = (r->pos() - l->pos() + speed - 1) / speed + TIME;
            small.insert(tseg(t, l));
        }
    }

    void remsegment(ppoint l, ppoint r)
    {
        int speed = sgn(r->diff) - sgn(l->diff);
        if (speed > 0)
        {
            int t = (r->pos() - l->pos() + speed - 1) / speed + TIME;
            small.erase(small.find(tseg(t, l)));
        }
    }

    tans()
    {
        bounds.insert({-inf, 0});
        bounds.insert({ inf, 0});
        addsegment(bounds.begin(), bounds.end());
    }

    void proceed(int time)
    {
        while (!small.empty() && small.begin()->fi <= time)
        {
            auto itl = small.begin()->se;
            auto itr = next(itl);
            int ctime = small.begin()->fi;
            remsegment(itl, itr); // removes from small
            int pos = itl->pos(ctime);
            int cdiff = itl->diff + itr->diff;
            if (itr->pos(ctime) != pos && cdiff > 0) pos--;
            auto itll = prev(itl);
            auto itrr = next(itr);
            remsegment(itll, itl);
            remsegment(itr, itrr);
            bounds.erase(itl);
            bounds.erase(itr);
            auto me = bounds.insert(itrr, tpoint(pos, cdiff, ctime));
            addsegment(itll, me);
            addsegment(me, itrr);
        }
    }

    int getupd(int x)
    {
        int upd = 0;
        auto itr = bounds.lower_bound(tpoint(x, 0));
        if (itr->pos() == x && itr->diff < 0) upd = max(upd, -itr->diff);
        itr = bounds.lower_bound(tpoint(x + 1, 0));
        if (itr->pos() == x + 1 && itr->diff > 0) upd = max(upd, itr->diff);
        return upd;
    }

    void add(int x, int t)
    {
        tpoint toadd(x, t);
        auto itr = bounds.lower_bound(toadd);
        if (toadd < *itr) // no same bound
        {
            auto itl = prev(itr);
            remsegment(itl, itr);
            auto me = bounds.insert(itr, toadd);
            addsegment(itl, me);
            addsegment(me, itr);
        } else
        {
            auto itl = prev(itr);
            auto me = itr;
            itr = next(itr);
            remsegment(itl, me);
            remsegment(me, itr);
            toadd = tpoint(x, t + me->diff);
            bounds.erase(me);
            me = bounds.insert(itr, toadd);
            addsegment(itl, me);
            addsegment(me, itr);
        }
    }

    vector<tpoint> getbounds()
    {
        return vector<tpoint>(all(bounds));
    }

    int getans()
    {
        int answer = 0;
        int cur = 0;
        for (auto t : bounds)
        {
            cur += t.diff;
            answer = max(answer, cur);
        }
        return answer;
    }

};

using pans = tans*;

pans go(int cur, int pr = -1)
{
    pans curans = NULL;
    for (auto e : gr[cur]) if (e.fi != pr)
    {
        TIME -= e.se * 2;
        auto t = go(e.fi, cur);
        t->proceed(TIME + (e.se - 1) * 2);
        TIME += (e.se - 1) * 2;
        t->proceed(TIME + 1);
        TIME += 1;
        if (curans == NULL) curans = t;
        else
        {
            for (auto pt : t->getbounds())
            {
                if (pt.pos() > -inf && pt.pos() < inf) curans->add(pt.pos(), pt.diff);
            }
        }
    }
    if (curans == NULL) curans = new tans();
    for (auto &curq : qs[cur])
    {
        curq.se = max(0, curq.se - curans->getupd(curq.fi));
    }
    curans->proceed(TIME + 1);
    TIME += 1;
    for (auto t : qs[cur])
    {
        curans->add(t.fi, t.se);
        curans->add(t.fi + 1, -t.se);
    }
    return curans;
}

void preprocess(int cur, int pr = -1)
{
    sz[cur] = 0;
    for (auto e : gr[cur]) if (e.fi != pr)
    {
        preprocess(e.fi, cur);
        sz[cur] += sz[e.fi];
    }
    sz[cur] += qs[cur].size();
    sort(all(gr[cur]), [&] (const pair2<int> &a, const pair2<int> &b)
                        {
                            return sz[a.fi] > sz[b.fi];

                        });
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i < n; i++)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        a--, b--;
        gr[a].pb({b, c});
        gr[b].pb({a, c});
    }
    scanf("%d", &q);
    for (int i = 0; i < q; i++)
    {
        int d, f, p;
        scanf("%d%d%d", &d, &f, &p);
        d *= 2;
        p--;
        qs[p].pb({d, f});
    }
    preprocess(0);
    auto ans = go(0);
    cout << ans->getans() << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int LL
typedef long long LL;
#define pii pair <LL,LL>

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=1e5+50;
const LL INF=0x3f3f3f3f3f3f3f3f;

int n,q; LL det[N];
vector <pii> edge[N];
vector <pii> ask[N];

struct Myset {
	int id;
	struct data {
		LL first,second; int id;
		data(LL first,LL second,int id) : first(first), second(second), id(id) {}
		friend inline bool operator <(const data &a,const data &b) {
			int posa=a.first+((a.second>0) ? -det[a.id] : det[a.id]),
				posb=b.first+((b.second>0) ? -det[b.id] : det[b.id]);
			if(posa!=posb) return posa<posb;
			return a.second<b.second;
		}
	};
	typedef set <data> Set;
	typedef Set :: iterator it;
	inline it prev(it t) {return --t;}
	inline it suff(it t) {return ++t;}
	Set *s;
	set <pii> *dis;
	inline int sgn(int x) {return (x>0) ? 1 : 0;}
	Myset() {s=new Set; dis=new set <pii>;}
	inline LL getpos(it t) {return t->first+((t->second<0) ? det[t->id] : -det[t->id]);}
	inline void del_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->erase(dis->find(pii(y->first-x->first,y->first)));
	}
	inline void inc_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->insert(pii(y->first-x->first,y->first));
	}
	inline void _erase(it x) {
		if(x!=s->begin()) del_dis(prev(x),x);
		if(x!=--s->end()) del_dis(x,suff(x));
		if(x!=s->begin() && x!=--s->end()) inc_dis(prev(x),suff(x));
		s->erase(x);
	}
	inline void add(int pos,int d) {
		if(!d) return;
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt==s->end() || getpos(nxt) !=pos) {
			if(s->size()>=2 && getpos(s->begin())<pos && getpos(--s->end())>pos) del_dis(prev(nxt),nxt);
			data temp=data(pos+((d<0)?-det[id]:det[id]),d,id);
			it now=s->insert(temp).first;
			if(nxt!=s->end()) inc_dis(now,nxt);
			if(now!=s->begin()) inc_dis(prev(now),now);
		} else {
			data temp=*nxt; _erase(nxt);
			if(!(temp.second+d)) return;
			if(temp.second<0 && temp.second+d>0) temp.first+=2*det[id];
			if(temp.second>0 && temp.second+d<0) temp.first-=2*det[id];
			temp.second+=d;
			it nxt=s->insert(temp).first;
			if(nxt!=--s->end()) inc_dis(nxt,suff(nxt));
			if(nxt!=s->begin()) inc_dis(prev(nxt),nxt);
			if(nxt!=--s->end() && nxt!=s->begin()) del_dis(prev(nxt),suff(nxt));
		}
	}
	inline void md(int pos,int d) {add(pos,d); add(pos+1,-d);}
	inline void mv(int d) {
		if(!d) return;
		while(dis->size() && dis->begin()->first<=(d+det[id])*2) {
			it nxt=s->lower_bound(data(dis->begin()->second-2*det[id],-INF,id));
			if(nxt->second==-prev(nxt)->second) _erase(prev(nxt)), _erase(nxt);
			else if(nxt->second>-prev(nxt)->second) {
				LL val=prev(nxt)->second;
				_erase(prev(nxt));
				add(nxt->first-det[id],val);
			} else {
				LL val=nxt->second; nxt=prev(nxt);
				_erase(suff(nxt));
				add(nxt->first+det[id],val);
			}
		} det[id]+=d;
	}
	inline void merge(Myset &b) {
		if(s->size()<b.s->size()) swap(s,b.s), swap(id,b.id), swap(dis,b.dis);
		for(it v=b.s->begin();v!=b.s->end();++v) {
			data temp=*v; temp.first+=(v->second<0) ? det[b.id] : -det[b.id];
			add(temp.first,temp.second);
		} delete b.s; delete b.dis;
	}
	inline LL getval(LL pos) {
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt!=s->end() && getpos(nxt)==pos) return nxt->second;
		return 0;
	}
} s[N];

inline void dfs(int x,int f) {
	for(auto v:edge[x]) {
		if(v.first==f) continue;
		dfs(v.first,x);
		for(auto &d:ask[v.first]) {
			LL delta=max(0ll,max(-s[v.first].getval(d.first),s[v.first].getval(d.first+1)));
			d.second=max(0ll,d.second-delta);
		}
		s[v.first].mv(1);
		for(auto d:ask[v.first]) s[v.first].md(d.first,d.second);
		s[v.first].mv(v.second-1);
		s[x].merge(s[v.first]);
	}
}

signed main() {
	n=rd();
	for(int i=1;i<=n;i++) s[i].id=i;
	for(int i=1;i<n;i++) {
		int x=rd(), y=rd(), w=rd()*2;
		edge[x].push_back(pii(y,w));
		edge[y].push_back(pii(x,w));
	} edge[0].push_back(pii(1,2));
	q=rd();
	for(int i=1;i<=q;i++) {
		int d=2*rd(), f=rd(), p=rd();
		ask[p].push_back(pii(d,f));
	}
	dfs(0,0);
	if(!s[0].s) {puts("0"); return 0;}
	LL sum=0, mx=0;
	for(auto v=s[0].s->begin();v!=s[0].s->end();++v) {
		sum+=v->second;
		mx=max(mx,sum);
	} cout<<mx<<'\n';
}

#include <bits/stdc++.h>
using namespace std;
#define pii pair <int,int>

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=1e5+50;
const int INF=0x3f3f3f3f;

int n,q; int det[N];
vector <pii> edge[N];
vector <pii> ask[N];

struct Myset {
	int id;
	struct data {
		int first,second; int id;
		data(int first,int second,int id) : first(first), second(second), id(id) {}
		friend inline bool operator <(const data &a,const data &b) {
			int posa=a.first+((a.second>0) ? -det[a.id] : det[a.id]),
				posb=b.first+((b.second>0) ? -det[b.id] : det[b.id]);
			if(posa!=posb) return posa<posb;
			return a.second<b.second;
		}
	};
	typedef set <data> Set;
	typedef Set :: iterator it;
	inline it prev(it t) {return --t;}
	inline it suff(it t) {return ++t;}
	Set *s;
	set <pii> *dis;
	inline int sgn(int x) {return (x>0) ? 1 : 0;}
	Myset() {s=new Set; dis=new set <pii>;}
	inline int getpos(it t) {return t->first+((t->second<0) ? det[t->id] : -det[t->id]);}
	inline void del_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->erase(dis->find(pii(y->first-x->first,y->first)));
	}
	inline void inc_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->insert(pii(y->first-x->first,y->first));
	}
	inline void _erase(it x) {
		if(x!=s->begin()) del_dis(prev(x),x);
		if(x!=--s->end()) del_dis(x,suff(x));
		if(x!=s->begin() && x!=--s->end()) inc_dis(prev(x),suff(x));
		s->erase(x);
	}
	inline void add(int pos,int d) {
		if(!d) return;
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt==s->end() || getpos(nxt) !=pos) {
			if(s->size()>=2 && getpos(s->begin())<pos && getpos(--s->end())>pos) del_dis(prev(nxt),nxt);
			data temp=data(pos+((d<0)?-det[id]:det[id]),d,id);
			it now=s->insert(temp).first;
			if(nxt!=s->end()) inc_dis(now,nxt);
			if(now!=s->begin()) inc_dis(prev(now),now);
		} else {
			data temp=*nxt; _erase(nxt);
			if(!(temp.second+d)) return;
			if(temp.second<0 && temp.second+d>0) temp.first+=2*det[id];
			if(temp.second>0 && temp.second+d<0) temp.first-=2*det[id];
			temp.second+=d;
			it nxt=s->insert(temp).first;
			if(nxt!=--s->end()) inc_dis(nxt,suff(nxt));
			if(nxt!=s->begin()) inc_dis(prev(nxt),nxt);
			if(nxt!=--s->end() && nxt!=s->begin()) del_dis(prev(nxt),suff(nxt));
		}
	}
	inline void md(int pos,int d) {add(pos,d); add(pos+1,-d);}
	inline void mv(int d) {
		if(!d) return;
		while(dis->size() && dis->begin()->first<=(d+det[id])*2) {
			it nxt=s->lower_bound(data(dis->begin()->second-2*det[id],-INF,id));
			if(nxt->second==-prev(nxt)->second) _erase(prev(nxt)), _erase(nxt);
			else if(nxt->second>-prev(nxt)->second) {
				int val=prev(nxt)->second;
				_erase(prev(nxt));
				add(nxt->first-det[id],val);
			} else {
				int val=nxt->second; nxt=prev(nxt);
				_erase(suff(nxt));
				add(nxt->first+det[id],val);
			}
		} det[id]+=d;
	}
	inline void merge(Myset &b) {
		if(s->size()<b.s->size()) swap(s,b.s), swap(id,b.id), swap(dis,b.dis);
		for(it v=b.s->begin();v!=b.s->end();++v) {
			data temp=*v; temp.first+=(v->second<0) ? det[b.id] : -det[b.id];
			add(temp.first,temp.second);
		} delete b.s; delete b.dis;
	}
	inline int getval(int pos) {
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt!=s->end() && getpos(nxt)==pos) return nxt->second;
		return 0;
	}
} s[N];

inline void dfs(int x,int f) {
	for(auto v:edge[x]) {
		if(v.first==f) continue;
		dfs(v.first,x);
		for(auto &d:ask[v.first]) {
			int delta=max(0,max(-s[v.first].getval(d.first),s[v.first].getval(d.first+1)));
			d.second=max(0,d.second-delta);
		}
		s[v.first].mv(1);
		for(auto d:ask[v.first]) s[v.first].md(d.first,d.second);
		s[v.first].mv(v.second-1);
		s[x].merge(s[v.first]);
	}
}

int main() {
	n=rd();
	for(int i=1;i<=n;i++) s[i].id=i;
	for(int i=1;i<n;i++) {
		int x=rd(), y=rd(), w=rd()*2;
		edge[x].push_back(pii(y,w));
		edge[y].push_back(pii(x,w));
	} edge[0].push_back(pii(1,2));
	q=rd();
	for(int i=1;i<=q;i++) {
		int d=2*rd(), f=rd(), p=rd();
		ask[p].push_back(pii(d,f));
	} dfs(0,0);
	if(!s[0].s) {puts("0"); return 0;}
	int sum=0, mx=0;
	for(auto v=s[0].s->begin();v!=s[0].s->end();++v) {
		sum+=v->second;
		mx=max(mx,sum);
	} cout<<mx<<'\n';
}

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

vector<pair<int, int>> adj[N], fish[N];
int n, m, now, depth[N];

struct node_t {
  int x, d, v;

  node_t(int x, int d, int v, int t = 0):x(x - d * t), d(d), v(v) {
  }

  bool operator < (const node_t &b) const {
    int p = x + now * d, q = b.x + now * b.d;
    return p == q ? d < b.d : p < q;
  }
};

struct collision_t {
  node_t x, y;
  int when;

  collision_t(node_t x, node_t y):x(x), y(y) {
    when = y.x - x.x >> 1;
  }

  bool operator < (const collision_t &b) const {
    if (when != b.when) {
      return when < b.when;
    } else {
      return make_tuple(x.x, x.v, y.x, y.v) < make_tuple(b.x.x, b.x.v, b.y.x, b.y.v);
    }
  }
};

struct info_t {
  set<collision_t> collisions;
  set<node_t> nodes;

  void insert_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.insert(collision_t(x, y));
    }
  }

  void erase_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.erase(collision_t(x, y));
    }
  }

  void insert(node_t x) {
    if (!x.v) {
      return;
    }
    if (nodes.find(x) != nodes.end()) {
      x.v += nodes.find(x)->v;
      erase(*nodes.find(x));
    }
    auto it = nodes.insert(x).first, next = it;
    ++next;
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      if (next != nodes.end()) {
        erase_collision(*prev, *next);
      }
      insert_collision(*prev, x);
    }
    if (next != nodes.end()) {
      insert_collision(x, *next);
    }
  }

  void erase(node_t x) {
    auto it = nodes.find(x), next = it;
    ++next;
    if (next != nodes.end()) {
      erase_collision(x, *next);
    }
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      erase_collision(*prev, x);
      if (next != nodes.end()) {
        insert_collision(*prev, *next);
      }
    }
    nodes.erase(it);
  }

  int reset(int x, int y) {
    node_t l(x + 1, -1, y, now), r(x - 1, 1, y, now);
    return max(0, y - max(nodes.find(l) == nodes.end() ? 0 : nodes.find(l)->v, nodes.find(r) == nodes.end() ? 0 : nodes.find(r)->v));
  }

  node_t cancel(node_t x, node_t y) {
    if (x.v > y.v) {
      return node_t(x.x, x.d, x.v - y.v);
    } else {
      return node_t(y.x, y.d, y.v - x.v);
    }
  }

  void collide(collision_t x) {
    erase(x.x);
    erase(x.y);
    insert(cancel(x.x, x.y));
  }

  void maintain(int x) {
    while (!collisions.empty() && collisions.begin()->when <= x) {
      collide(*collisions.begin());
    }
  }

  void merge(info_t &b) {
    if (nodes.size() < b.nodes.size()) {
      swap(nodes, b.nodes);
      swap(collisions, b.collisions);
    }
    for (auto x : b.nodes) {
      insert(x);
    }
  }

  int query() {
    int answer = 0;
    for (auto x : nodes) {
      if (x.d > 0) {
        answer += x.v;
      }
    }
    return answer;
  }
} info[N];

void dfs(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      depth[y] = depth[x] + w;
      dfs(y, x);
    }
  }
}

void solve(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      solve(y, x);
      now = -depth[y];
      info[y].maintain(-(depth[x] + 1));
      now = -(depth[x] + 1);
      info[x].merge(info[y]);
    }
  }
  now = -(depth[x] + 1);
  for (auto &e : fish[x]) {
    e.second = info[x].reset(e.first, e.second);
  }
  info[x].maintain(-depth[x]);
  now = -depth[x];
  for (auto e : fish[x]) {
    info[x].insert(node_t(e.first, -1, e.second, now));
    info[x].insert(node_t(e.first, 1, e.second, now));
  }
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    --x;
    --y;
    w <<= 1;
    adj[x].emplace_back(y, w);
    adj[y].emplace_back(x, w);
  }
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    int day, value, where;
    scanf("%d %d %d", &day, &value, &where);
    day <<= 1;
    --where;
    fish[where].emplace_back(day, value);
  }
  dfs(0, -1);
  solve(0, -1);
  info[0].maintain(INT_MAX);
  printf("%d\n", info[0].query());
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
struct Pair {int x, y; };
int n, m, curr, depth[MAXN];
vector <Pair> a[MAXN], b[MAXN];
struct Info {int pos, type, val; };
bool operator < (Info a, Info b) {
	int apos = a.pos + a.type * curr;
	int bpos = b.pos + b.type * curr;
	if (apos == bpos) return a.type < b.type;
	else return apos < bpos;
}
struct Crash {
	Info a, b;
	int when;
	void calc() {
		int apos = a.pos + a.type * curr;
		int bpos = b.pos + b.type * curr;
		when = curr - (bpos - apos + 1) / 2;
	}
};
Crash make(Info a, Info b) {
	Crash ans = (Crash) {a, b};
	ans.calc();
	return ans;
}
bool operator < (Crash a, Crash b) {
	if (a.when == b.when) return make_pair(a.a, a.b) < make_pair(b.a, b.b);
	else return a.when > b.when;
}
struct Container {
	set <Info> Val;
	set <Crash> Del;
	void EraseCrash(Info a, Info b) {
		if (a.type == -1 && b.type == 1)
			Del.erase(make(a, b));
	}
	void InsertCrash(Info a, Info b) {
		if (a.type == -1 && b.type == 1)
			Del.insert(make(a, b));
	}
	void erase(Info a) {
		set <Info> :: iterator pos = Val.find(a), suf = pos; suf++;
		if (pos != Val.begin()) {
			set <Info> :: iterator pre = pos; pre--;
			EraseCrash(*pre, *pos);
			if (suf != Val.end()) InsertCrash(*pre, *suf);
		}
		if (suf != Val.end()) EraseCrash(*pos, *suf);
		Val.erase(pos);
	}
	void insert(Info a) {
		if (a.val == 0) return;
		if (Val.find(a) != Val.end()) {
			a.val += (*Val.find(a)).val;
			erase(*Val.find(a));
		}
		if (a.val == 0) return;
		set <Info> :: iterator pos = Val.insert(a).first, suf = pos; suf++;
		if (pos != Val.begin()) {
			set <Info> :: iterator pre = pos; pre--;
			InsertCrash(*pre, *pos);
			if (suf != Val.end()) EraseCrash(*pre, *suf);
		}
		if (suf != Val.end()) InsertCrash(*pos, *suf);
	}
	void process(Crash a) {
		erase(a.a), erase(a.b);
		int tmp = a.a.val + a.b.val;
		if (tmp == 0) return;
		if (tmp > 0) a.b.val = tmp, insert(a.b);
		else a.a.val = tmp, insert(a.a);
	}
	void maintain(int timer) {
		while (!Del.empty() && timer <= (*Del.begin()).when)
			process(*Del.begin());
		curr = timer;
	}
	void debug(int pos, int timer) {
		maintain(timer);
		cerr << "Debugging In Progress. At Point " << pos << " Current Time: " << timer << endl;
		set <Info> :: iterator i;
		cerr << "Set Val: " << endl;
		for (i = Val.begin(); i != Val.end(); i++)
			cerr << (*i).pos << '(' << (*i).pos + curr * (*i).type << ')' << ' ' << (*i).type << ' ' << (*i).val << endl;
		set <Crash> :: iterator j;
		cerr << "Del Val: " << endl;
		for (j = Del.begin(); j != Del.end(); j++) {
			cerr << (*j).a.pos << '(' << (*j).a.pos + curr * (*j).a.type << ')' << ' ' << (*j).a.type << ' ' << (*j).a.val << ' ';
			cerr << (*j).b.pos << '(' << (*j).b.pos + curr * (*j).b.type << ')' << ' ' << (*j).b.type << ' ' << (*j).b.val << ' ';
			cerr << "Collide Time: " << (*j).when << endl;
		}
	}
	void join(Container &a, int timer) {
		maintain(timer);
		if (a.Val.size() > Val.size()) {
			swap(Val, a.Val);
			swap(Del, a.Del);
		}
		set <Info> :: iterator i;
		for (i = a.Val.begin(); i != a.Val.end(); i++)
			insert(*i);
	}
	int delta(int pos) {
		Info tmp = (Info) {pos + curr, -1, 0};
		Info tnp = (Info) {pos + 1 - curr, 1, 0};
		int vtmp = 0, vtnp = 0;
		if (Val.find(tmp) != Val.end()) vtmp = -(*Val.find(tmp)).val;
		if (Val.find(tnp) != Val.end()) vtnp = (*Val.find(tnp)).val;
		return max(vtmp, vtnp);
	}
	void modify(vector <Pair> &a, int from, int to) {
		maintain(from);
		//debug(0, curr);
		for (unsigned i = 0; i < a.size(); i++) {
			int tmp = delta(a[i].x);
			a[i].y = max(0, a[i].y - tmp);
		}
		maintain(from - 1);
		//debug(0, curr);
		for (unsigned i = 0; i < a.size(); i++) {
			insert((Info) {a[i].x - curr, 1, a[i].y});
			insert((Info) {a[i].x + 1 + curr, -1, -a[i].y});
		}
		//debug(0, curr);
		maintain(to);
		//debug(0, curr);
	}
	int calcans() {
		int ans = 0, now = 0;
		set <Info> :: iterator i;
		for (i = Val.begin(); i != Val.end(); i++) {
			now += (*i).val;
			chkmax(ans, now);
		}
		return ans;
	}
} dp[MAXN];
void dfs(int pos, int fa) {
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i].x != fa) {
			depth[a[pos][i].x] = depth[pos] + a[pos][i].y;
			dfs(a[pos][i].x, pos);
		}
}
void work(int pos, int fa, int last) {
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i].x != fa) {
			int tmp = a[pos][i].x;
			work(tmp, pos, depth[pos]);
			dp[pos].join(dp[a[pos][i].x], depth[pos]);
		}
	dp[pos].modify(b[pos], depth[pos], last);
	//dp[pos].debug(pos, last);
}
int main() {
	read(n);
	for (int i = 1; i <= n - 1; i++) {
		int x, y, z;
		read(x), read(y), read(z);
		a[x].push_back((Pair) {y, z * 2});
		a[y].push_back((Pair) {x, z * 2});
	}
	read(m);
	for (int i = 1; i <= m; i++) {
		int d, f, p;
		read(d), read(f), read(p);
		b[p].push_back((Pair) {d * 2, f});
	}
	dfs(1, 0);
	work(1, 0, -2);
	writeln(dp[1].calcans());
	return 0;
}

#include<cstdio>
const int maxn=100010,maxk=100010,inf=1e9;
int n;
struct edge{int to,l;edge*next;}E[maxn*2],*ne=E,*fir[maxn];
struct item{int d,f;item*next;}I[maxk],*fi[maxn];
void link(int u,int v,int l){*ne=(edge){v,l,fir[u]};fir[u]=ne++;}
int fa[maxn],dep[maxn],siz[maxn],son[maxn];
void init(int i){
	siz[i]=1;
	for(edge*e=fir[i];e;e=e->next)if(e->to!=fa[i]){
		fa[e->to]=i;
		dep[e->to]=dep[i]+e->l;
		init(e->to);
		if(siz[e->to]>siz[son[i]])son[i]=e->to;
		siz[i]+=siz[e->to];
	}
}
void cmax(int&a,int b){b>a?a=b:1;}
struct node{
	int l,r,v,ty,md,add;
	node*fa,*ch[2];
	int L(int x){return ty&1?l-x:l+x;}
	int R(int x){return ty&2?r-x:r+x;}
	int Lv(int x){return L(x)*2+(ty&1);}
	int Rv(int x){return R(x)*2+(ty>>1);}
	void pu(){
		md=ty==1?l-r:-inf;
		if(ch[0])cmax(md,ch[0]->md);
		if(ch[1])cmax(md,ch[1]->md);
	}
	void pd(){
		if(!add)return;
		if(ch[0])ch[0]->v+=add,ch[0]->add+=add;
		if(ch[1])ch[1]->v+=add,ch[1]->add+=add;
		add=0;
	}
	void chd(int i,int d,int x){
		if((ty>>i&1)==d)return;
		ty^=1<<i;
		x*=d?1:-1;
		i?r+=x:l+=x;
	}
	void rot(node*&r){
		node*f=fa;
		int c=this==f->ch[1];
		if(f->ch[c]=ch[!c])ch[!c]->fa=f;
		ch[!c]=f;
		if(fa=f->fa)fa->ch[f==fa->ch[1]]=this;
		f->fa=this;
		f->pu();
		if(f==r)r=this;
	}
	void spl(node*&r){
		for(;this!=r;rot(r))if(fa!=r)
			(this==fa->ch[1])==(fa==fa->fa->ch[1])?fa->rot(r):rot(r);
		pu();
	}
	node*fir(int c){return pd(),ch[c]?ch[c]->fir(c):this;}
	node*next(){
		if(pd(),ch[1])return ch[1]->fir(0);
		for(node*x=this;x;x=x->fa)if(x->fa&&x==x->fa->ch[0])return x->fa;
		return 0;
	}
	node*ins(int c){
		node*x=new node;*x=*this;
		x->ch[!c]=0;
		x->fa=this;
		if(ch[c])ch[c]->fa=x;
		return ch[c]=x;
	}
	node*ub(int d,int x,bool t=0){
		pd();
		if(x<Lv(d))return ch[0]&&!t?ch[0]->ub(d,x):this;
		if(x<Rv(d))return this;
		return ch[1]->ub(d,x);
	}
	node*maxd(){
		if(pd(),ty==1&&l-r==md)return this;
		return ch[ch[1]&&ch[1]->md==md]->maxd();
	}
	int maxv(){
		int x=v;pd();
		if(ch[0])cmax(x,ch[0]->maxv());
		if(ch[1])cmax(x,ch[1]->maxv());
		return x;
	}
};
void del(node*&f){
	int d=f->l-f->r;
	node*l=f->ch[0],*r=f->ch[1];
	l->fa=r->fa=0;
	l->fir(1)->spl(l);
	r->fir(0)->spl(r);
	l->ch[1]=r;
	r->fa=l;
	r->chd(0,l->v>r->v,d);r->pu();
	l->chd(1,l->v>r->v,d);l->pu();
	f=l;
}
void des(node*x){
	if(x->ch[0])des(x->ch[0]);
	if(x->ch[1])des(x->ch[1]);
	delete x;
}
node*dfs(int i){
	node*f;
	if(son[i])f=dfs(son[i]);
	else f=new node,*f=(node){-inf,inf,0,2,-inf,0,0,{0,0}};
	int d=dep[i];
	for(edge*e=fir[i];e;e=e->next)if(e->to!=fa[i]&&e->to!=son[i]){
		node*rt=dfs(e->to);
		bool t=0;
		for(node*g=rt->fir(0);g;g=g->next())if(g->v){
			int l=g->L(d),r=g->R(d),lv=g->Lv(d),rv=g->Rv(d);
			f->ub(d,lv,t)->spl(f);
			node*fl,*fr;
			if(f->Lv(d)<lv){
				fl=f->ins(0);
				fl->r=f->l=l-d;
				fl->ty&=~2;f->ty&=~1;
			}
			else fl=f->ch[0]->fir(1),fl->spl(f->ch[0]);
			if(fl->v<f->v+g->v)fl->chd(1,0,d*2),f->chd(0,0,d*2);
			fl->spl(f);
			fl=f->ch[1]->ub(d,rv-1);
			fl->spl(f->ch[1]);
			if(fl->Rv(d)>rv){
				fr=fl->ins(1);
				fl->r=fr->l=r+d;
				fl->ty|=2;fr->ty|=1;
			}
			else fr=fl->ch[1]->fir(0),fr->spl(fl->ch[1]);
			fl->v+=g->v;
			if(fl->ch[0])fl->ch[0]->v+=g->v,fl->ch[0]->add+=g->v;
			if(fr->v<fl->v)fr->chd(0,1,d*2),fl->chd(1,1,d*2);
			fr->spl(f);
			t=1;
		}
		des(rt);
	}
	for(item*it=fi[i];it;it=it->next){
		f->ub(d,it->d*2+1)->spl(f);
		node*f0=f->ins(0);
		node*f1=f->ins(0);
		f0->r=f1->l=it->d+1-d;
		f1->r=f->l=it->d+d;
		f1->v+=it->f;
		f0->ty&=~2;f1->ty&=~1;
		f1->ty|=2;f->ty|=1;
		f0->spl(f);
	}
	while(f->md>=dep[fa[i]]*2){
		f->maxd()->spl(f),del(f);
	}
	return f;
}
int main(){
	scanf("%d",&n);
	for(int i=1,u,v,l;i<n;i++)scanf("%d%d%d",&u,&v,&l),link(u,v,l),link(v,u,l);
	int k;scanf("%d",&k);
	for(int i=0,p;i<k;i++)scanf("%d%d%d",&I[i].d,&I[i].f,&p),I[i].next=fi[p],fi[p]=I+i;
	init(1);
	node*f=dfs(1);
	printf("%d\n",f->maxv());
}

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <functional>
#include <cmath>
#include <string>
#include <set>
#include <map>
#define SIZE 200005

using namespace std;
typedef long long int ll;
typedef pair <ll,ll> P;
typedef pair <P,P> PP;

struct edge
{
	int to;
	ll cost;
	edge(int to=0,ll cost=0):to(to),cost(cost){}
};
vector <edge> vec[SIZE];
vector <P> up[SIZE];
vector <P> down[SIZE];
vector <int> vt[SIZE];
ll dep[SIZE];
int nd[SIZE],back[SIZE];
int pos[SIZE],cmb[SIZE];
int par[SIZE],len[SIZE];
PP now[SIZE];
int now_sz;

void dfs(int v=0,int p=-1,ll d=0)
{
	dep[v]=d;
	nd[v]=1;
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p)
		{
			dfs(e.to,v,d+e.cost);
			nd[v]+=nd[e.to];
		}
	}
}
void heavy_light(int v=0,int p=-1,int b=-1)
{
	vt[now_sz].push_back(v);
	par[now_sz]=b;
	back[v]=b;
	pos[v]=len[now_sz]++;
	cmb[v]=now_sz;
	bool up=false;
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p&&nd[e.to]*2>=nd[v])
		{
			heavy_light(e.to,v,b);
			up=true;
			break;
		}
	}
	if(!up)
	{
		now_sz++;
	}
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p&&nd[e.to]*2<nd[v])
		{
			heavy_light(e.to,v,v);
		}
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		ll c;
		scanf("%d %d %lld",&a,&b,&c);a--,b--,c*=(ll) n,c--;
		vec[a].push_back(edge(b,c));
		vec[b].push_back(edge(a,c));
	}
	dfs();
	heavy_light();
	int m;
	scanf("%d",&m);
	ll all=0;
	for(int i=0;i<m;i++)
	{
		ll t;
		int f,v;
		scanf("%lld %d %d",&t,&f,&v);t*=(ll) n,v--;
		up[v].push_back(P(t+dep[v],f));
		down[v].push_back(P(t-dep[v]-1,f));
		all+=f;
	}
	ll ret=0;
	for(int t=now_sz-1;t>=0;t--)
	{
		int sz=0;
		for(int i=0;i<vt[t].size();i++)
		{
			int v=vt[t][i];
			for(int j=0;j<up[v].size();j++)
			{
				P p=up[v][j];
				now[sz++]=PP(P(p.first,-1),P(p.first-2LL*dep[v],p.second));
			}
			for(int j=0;j<down[v].size();j++)
			{
				P p=down[v][j];
				now[sz++]=PP(P(p.first+2LL*dep[v],1),p);
			}
		}
		multiset <P> st;
		multiset <P>::iterator it;
		sort(now,now+sz);/*
		if(t<=10)
		{
			printf("* %d %lld\n",t,ret);
			for(int i=0;i<sz;i++) printf("[%lld %lld] [%lld %lld]\n",now[i].first.first,now[i].first.second,now[i].second.first,now[i].second.second);
		}*/
		for(int i=sz-1;i>=0;i--)
		{
			if(now[i].first.second==-1)//query
			{
				P q=now[i].second;
				while(q.second>0)
				{
					it=st.lower_bound(P(q.first,-1));
					if(it!=st.end())
					{
						P p=*it;
						ll df=now[i].first.first-p.first;
						if(t==0||df>=2LL*dep[par[t]])
						{
							st.erase(it);
							ll c=min(q.second,p.second);
							ret+=c;
							q.second-=c;
							p.second-=c;
							if(p.second>0) st.insert(p);
						}
						else break;
					}
					else break;
				}
				if(q.second>0&&t>0) up[par[t]].push_back(P(now[i].first.first,q.second));
			}
			else//add
			{
				st.insert(now[i].second);
			}
		}
		if(t>0)
		{
			for(it=st.begin();it!=st.end();it++) down[par[t]].push_back(*it);
			st.clear();
		}
		//printf("* %d %lld\n",t,ret);
	}
	printf("%lld\n",all-ret);
	return 0;
}

#include <bits/stdc++.h>
const int64_t INF=2e9+7;
int64_t current_time;
struct End{
  int64_t x,v;
  int64_t a;
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;
    return false;
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A){
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t){
    while(collide.size()&&collide.begin()->time2<t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  current_time=-depth[node];
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
  }
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node])
    f.second=dss[node].prep(f.first,f.second);
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  current_time=-depth[node];
  current_time=-depth[node];
  for(auto f:fish[node]){
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
  current_time=-depth[node];
}
int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;D*=2;
    current_time=-depth[P];
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7,M=4e6+7;
int n,m,q,k,p[N],t[N],vs[M],siz[N],va[M],vb[M]; vector<int>v[N],w[N];
struct node {int t,f;}; vector<node>e[N];
struct note {int a,b;}gt[N];
struct nope {int a,b,t;};
priority_queue<nope>g[N];
inline int find(int u){
	if(vs[u]==u) return u; return vs[u]=find(vs[u]);
}
inline bool operator < (note a,note b){
	if(a.a==b.a) return a.b>b.b; return a.a<b.a;
}
inline bool operator < (nope a,nope b){
	if(a.t==b.t) return max(a.a,a.b)<max(b.a,b.b);
	return a.t>b.t;
}
set<note>f1[N],f2[N];
inline void updatea(int u,int c){
	note w; w.a=va[c]+t[u]*2+1,w.b=998244353;
	f2[u].insert(w);
	if((*f2[u].rbegin()).b==998244353) {f2[u].erase(w); return;};
	note e=(*(++f2[u].find(w))); f2[u].erase(w);

	if(find(e.b)==find(c)&&(*f2[u].rbegin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(++f2[u].find(e)));
	nope v; v.a=c,v.b=e.b,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void updateb(int u,int c){
	note w; w.a=va[c]-t[u]*2-1,w.b=-998244353;
	f1[u].insert(w);
	if((*f1[u].begin()).b==-998244353) {f1[u].erase(w); return;};
	note e=(*(--f1[u].find(w)));
	f1[u].erase(w);
	if(find(e.b)==find(c)&&(*f1[u].begin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(--f1[u].find(e)));

	nope v; v.a=e.b,v.b=c,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void update(int u,int k){
	while(g[u].size()){
		nope z=g[u].top();
		if(va[z.a]==-1||va[z.b]==-1) {g[u].pop(); continue;}
		if(z.t<=t[u]){
			g[u].pop(); continue;
		}
		if(z.t<=t[u]+k){
			g[u].pop();
			note r; r.a=va[z.a],r.b=z.a; note w1,w2,h1,h2;
			w1.a=-1,w1.b=-1,w2.a=-1,w2.b=-1,h1.a=-1,h1.b=-1,h2.a=-1,h2.b=-1;
			if((*f1[u].begin()).b!=r.b) w1=(*(--f1[u].find(r)));
			if((*f1[u].rbegin()).b!=r.b) w2=(*(++f1[u].find(r)));
			f1[u].erase(r);
			note c; c.a=va[z.b],c.b=z.b;
			if((*f2[u].begin()).b!=c.b) h1=(*(--f2[u].find(c)));
			if((*f2[u].rbegin()).b!=c.b) h2=(*(++f2[u].find(c)));
			f2[u].erase(c);
			if(vb[z.a]+vb[z.b]<0){
				m++,va[m]=va[z.a],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.a]; c.a=va[m],c.b=m; f1[u].insert(c); updatea(u,m);
			}
			if(vb[z.a]+vb[z.b]>0){
				m++,va[m]=va[z.b],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.b],c.a=va[m],c.b=m;
				f2[u].insert(c); updateb(u,m);
			}
			if(w1.b!=-1) updatea(u,w1.b);
			if(w2.b!=-1) updatea(u,w2.b);
			if(h1.b!=-1) updateb(u,h1.b);
			if(h2.b!=-1) updateb(u,h2.b);
			va[z.a]=-1,va[z.b]=-1;
		}
		else break;
	}
	t[u]+=k;
}
inline int merge(int a,int b){
	if(siz[a]<siz[b]) swap(a,b); siz[a]+=siz[b];
	set<note>::iterator iter = f1[b].begin();
	while(iter!=f1[b].end()){
		note w=(*iter);
		m++,va[m]=w.a+t[b]-t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f1[a].insert(w),iter++,updatea(a,m);
	}
	iter = f2[b].begin();
	while(iter!=f2[b].end()){
		note w=(*iter);
		m++,va[m]=w.a-t[b]+t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f2[a].insert(w),iter++,updateb(a,m);
	}
	return a;
}
inline void dfs(int u,int fa){
	p[u]=u;
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i];
		if(x==fa) continue;
		dfs(x,u);
		for(int c=0;c<e[x].size();c++){
			node s=e[x][c]; vs[m+1]=vs[m+2]=m+2;
			note v; m++,va[m]=s.t*2-t[p[x]],vb[m]=-s.f,v.a=va[m],v.b=m; f1[p[x]].insert(v),updatea(p[x],m);
			note q; m++,va[m]=s.t*2+t[p[x]]+1,vb[m]=s.f,q.a=va[m],q.b=m;  f2[p[x]].insert(q),updateb(p[x],m);
			siz[p[x]]++;
		}
		update(p[x],w[u][i]*2);
		p[u]=merge(p[u],p[x]);
	}
}
inline bool tmp(note a,note b){
	return a.a<b.a;
}
int main(){
	cin>>n; int a,b,c;
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&a,&b,&c);
		v[a].push_back(b),v[b].push_back(a);
		w[a].push_back(c),w[b].push_back(c);
	}
	v[1].push_back(n+1),v[n+1].push_back(1);
	w[1].push_back(1),w[n+1].push_back(1);
	cin>>q;
	while(q--){
		scanf("%d%d%d",&a,&b,&c); node d;
		d.t=a,d.f=b; e[c].push_back(d);
	}
	dfs(n+1,0);
	set<note>::iterator iter = f1[p[n+1]].begin();
	while(iter!=f1[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a+=t[p[n+1]];
		iter++;
	}
	iter = f2[p[n+1]].begin();
	while(iter!=f2[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a-=t[p[n+1]];
		iter++;
	}
	sort(gt+1,gt+k+1,tmp); int sum=0,ans=0;
	for(int i=1;i<=k;i++){
		int j=i; sum+=vb[gt[i].b];
		while(gt[j+1].a==gt[i].a&&j+1<=k) sum+=vb[gt[j+1].b],j++;
		i=j; ans=max(ans,sum);
	}
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7,M=4e6+7;
int n,m,q,k,p[N],t[N],vs[M],siz[N],va[M],vb[M]; vector<int>v[N],w[N];
struct node {int t,f;}; vector<node>e[N];
struct note {int a,b;}gt[N];
struct nope {int a,b,t;};
priority_queue<nope>g[N];
inline int find(int u){
	if(vs[u]==u) return u; return vs[u]=find(vs[u]);
}
inline bool operator < (note a,note b){
	if(a.a==b.a) return a.b>b.b; return a.a<b.a;
}
inline bool operator < (nope a,nope b){
	if(a.t==b.t) return max(a.a,a.b)<max(b.a,b.b);
	return a.t>b.t;
}
set<note>f1[N],f2[N];
inline void updatea(int u,int c){
	note w; w.a=va[c]+t[u]*2+1,w.b=998244353;
	f2[u].insert(w);
	if((*f2[u].rbegin()).b==998244353) {f2[u].erase(w); return;};
	note e=(*(++f2[u].find(w))); f2[u].erase(w);

	if(find(e.b)==find(c)&&(*f2[u].rbegin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(++f2[u].find(e)));
	nope v; v.a=c,v.b=e.b,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void updateb(int u,int c){
	note w; w.a=va[c]-t[u]*2-1,w.b=-998244353;
	f1[u].insert(w);
	if((*f1[u].begin()).b==-998244353) {f1[u].erase(w); return;};
	note e=(*(--f1[u].find(w)));
	f1[u].erase(w);
	if(find(e.b)==find(c)&&(*f1[u].begin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(--f1[u].find(e)));

	nope v; v.a=e.b,v.b=c,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void update(int u,int k){
	while(g[u].size()){
		nope z=g[u].top();
		if(va[z.a]==-1||va[z.b]==-1) {g[u].pop(); continue;}
		if(z.t<=t[u]){
			g[u].pop(); continue;
		}
		if(z.t<=t[u]+k){
			g[u].pop();
			note r; r.a=va[z.a],r.b=z.a; note w1,w2,w3,h1,h2,h3;
			w1.a=-1,w1.b=-1,w2.a=-1,w2.b=-1,w3.a=-1,w3.b=-1,h1.a=-1,h1.b=-1,h2.a=-1,h2.b=-1,h3.a=-1,h3.b=-1;
			if((*f1[u].begin()).b!=r.b) w1=(*(--f1[u].find(r)));
			if((*f1[u].rbegin()).b!=r.b) w2=(*(++f1[u].find(r)));
			if((*f1[u].begin()).b!=r.b&&(*f1[u].begin()).b!=w1.b) w3=(*(--f1[u].find(w1)));
			f1[u].erase(r);
			note c; c.a=va[z.b],c.b=z.b;
			if((*f2[u].begin()).b!=c.b) h1=(*(--f2[u].find(c)));
			if((*f2[u].rbegin()).b!=c.b) h2=(*(++f2[u].find(c)));
			if((*f2[u].begin()).b!=c.b&&(*f2[u].begin()).b!=h1.b) h3=(*(--f2[u].find(h1)));
			f2[u].erase(c);
			if(vb[z.a]+vb[z.b]<0){
				m++,va[m]=va[z.a],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.a]; c.a=va[m],c.b=m; f1[u].insert(c); updatea(u,m);
			}
			if(vb[z.a]+vb[z.b]>0){
				m++,va[m]=va[z.b],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.b],c.a=va[m],c.b=m;
				f2[u].insert(c); updateb(u,m);
			}
			if(w1.b!=-1) updatea(u,w1.b);
			if(w2.b!=-1) updatea(u,w2.b);
			if(w3.b!=-1) updatea(u,w3.b);
			if(h1.b!=-1) updateb(u,h1.b);
			if(h2.b!=-1) updateb(u,h2.b);
			if(h3.b!=-1) updateb(u,h3.b);
			va[z.a]=-1,va[z.b]=-1;
		}
		else break;
	}
	t[u]+=k;
}
inline int merge(int a,int b){
	if(siz[a]<siz[b]) swap(a,b); siz[a]+=siz[b];
	set<note>::iterator iter = f1[b].begin();
	while(iter!=f1[b].end()){
		note w=(*iter);
		m++,va[m]=w.a+t[b]-t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f1[a].insert(w),iter++,updatea(a,m);
	}
	iter = f2[b].begin();
	while(iter!=f2[b].end()){
		note w=(*iter);
		m++,va[m]=w.a-t[b]+t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f2[a].insert(w),iter++,updateb(a,m);
	}
	return a;
}
inline void dfs(int u,int fa){
	p[u]=u;
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i];
		if(x==fa) continue;
		dfs(x,u);
		for(int c=0;c<e[x].size();c++){
			node s=e[x][c]; vs[m+1]=vs[m+2]=m+2;
			note v; m++,va[m]=s.t*2-t[p[x]],vb[m]=-s.f,v.a=va[m],v.b=m; f1[p[x]].insert(v),updatea(p[x],m);
			note q; m++,va[m]=s.t*2+t[p[x]]+1,vb[m]=s.f,q.a=va[m],q.b=m;  f2[p[x]].insert(q),updateb(p[x],m);
			siz[p[x]]++;
		}
		update(p[x],w[u][i]*2);
		p[u]=merge(p[u],p[x]);
	}
}
inline bool tmp(note a,note b){
	return a.a<b.a;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>n; int a,b,c;
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&a,&b,&c);
		v[a].push_back(b),v[b].push_back(a);
		w[a].push_back(c),w[b].push_back(c);
	}
	v[1].push_back(n+1),v[n+1].push_back(1);
	w[1].push_back(1),w[n+1].push_back(1);
	cin>>q;
	while(q--){
		scanf("%d%d%d",&a,&b,&c); node d;
		d.t=a,d.f=b; e[c].push_back(d);
	}
	dfs(n+1,0);
	set<note>::iterator iter = f1[p[n+1]].begin();
	while(iter!=f1[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a+=t[p[n+1]];
		iter++;
	}
	iter = f2[p[n+1]].begin();
	while(iter!=f2[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a-=t[p[n+1]];
		iter++;
	}
	sort(gt+1,gt+k+1,tmp); int sum=0,ans=0;
	for(int i=1;i<=k;i++){
		int j=i; sum+=vb[gt[i].b];
		while(gt[j+1].a==gt[i].a&&j+1<=k) sum+=vb[gt[j+1].b],j++;
		i=j; ans=max(ans,sum);
	}
	cout<<ans<<endl;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

int getval(int x) {
  set<Data>::iterator it=st.lower_bound(Data(x-addv[id],-inf,id));
  return (it->x-sgn(it->v)*addv[id]==x)?it->v:0;
}

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x-addv[id],-inf,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*(addv[id]+d)<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005],vt2[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	int nv=max(0,max(-f[x].getval(d),f[x].getval(d+1)));
  	if (nv<v) vt2[x].push_back(pr(d,v-nv));
  }
  f[x].trans(1);
  for(int i=0;i<vt2[x].size();i++) {
  	int d=vt2[x][i].FR,v=vt2[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>
const int64_t INF=2e9+7;
int64_t current_time;
struct End
{
  int64_t x,v;
  int64_t a;
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a)
  {
  }
  bool operator<(struct End other)const
  {
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;
    return false;
  }
  struct End operator-()
  {
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump()
  {
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};
struct Collision
{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2)
  {
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const
  {
    if(time2!=other.time2) return time2<other.time2;
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump()
  {
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};
struct DS
{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2)
  {
    assert(e1<e2);
    if(e1.v>0&&e2.v<0)
    {
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2)
  {
    assert(e1<e2);
    if(e1.v>0&&e2.v<0)
    {
      struct Collision c(e1,e2);
      if(!collide.count(c))
      {
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2)
  {
    if(e1.a>e2.a)
    {
      return End(e1.x,e1.v,e1.a-e2.a);
    }
    else
    {
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e)
  {
    if(e.a==0) return;
    if(ends.count(e))
    {
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;
    auto next=std::next(it);
    if(it!=ends.begin())
    {
      auto prev=std::prev(it);
      if(next!=ends.end())
      {
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end())
    {
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A)
  {
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A)
  {
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l))
    {
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r))
    {
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e)
  {
    if(e.a==0) return;
    if(ends.count(-e))
    {
      auto e2=*ends.find(-e);
      erase(e2);
      insert(cancel(e,e2));
    }
    else
    {
      insert(e);
    }
  }
  void erase(struct End e)
  {
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end())
    {
      erasec(*it,*next);
    }
    if(it!=ends.begin())
    {
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end())
      {
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c)
  {
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  void ffwd(int64_t t)
  {
    while(collide.size()&&collide.begin()->time2<=t*2)
    {
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t)
  {
    while(collide.size()&&collide.begin()->time2<t*2)
    {
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other)
    {
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  void merge(struct DS& other)
  {
    if(ends.size()<other.ends.size())
    {
      swap(other);
    }
    for(auto e:other.ends)
    {
      insert(e);
    }
  }
  int64_t query()
  {
    int64_t ac=0;
    for(auto it:ends)
    {
      if(it.v>0)
      {
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump()
  {
    printf("T=%I64d\n",current_time);
    for(auto e:ends)
    {
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide)
    {
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};
std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];
struct DS dss[100005];
int64_t depth[100005];
void dfs_depth(int64_t node,int64_t parent)
{
  for(auto e:edges[node])
  {
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}
void dfs_solve(int64_t node,int64_t parent)
{
  current_time=-depth[node];
  for(auto e:edges[node])
  {
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
  }
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node])
  {
    f.second=dss[node].prep(f.first,f.second);
  }
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  current_time=-depth[node];
  current_time=-depth[node];
  for(auto f:fish[node])
  {
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
  current_time=-depth[node];
}
int main()
{
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++)
  {
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++)
  {
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>P;
typedef vector<P>V;
const int N=1e5+5,I=1<<30;
int n,m,u,v,w,i,rt[N];
V e[N],ev[N];
struct node{
	int ch[2],fa;
	int tg,v,mn,w,s,sz,lv,rv;bool tp,lt,rt;
	inline int dir(int x){return ch[1]==x;}
	inline void addtag(int d){tg+=d;tp?v+=d:v-=d;lt?lv+=d:lv-=d;rt?rv+=d:rv-=d;mn-=d*2;}
}t[N*2];int tcnt;
inline void upd(int x){
	int l=t[x].ch[0],r=t[x].ch[1];
	if(l)t[x].lv=t[l].lv,t[x].lt=t[l].lt;else t[x].lv=t[x].v,t[x].lt=t[x].tp;
	if(r)t[x].rv=t[r].rv,t[x].rt=t[r].rt;else t[x].rv=t[x].v,t[x].rt=t[x].tp;
	t[x].s=t[l].s+t[r].s+t[x].w;t[x].sz=t[l].sz+t[r].sz+1;
	t[x].mn=min(min(t[l].mn,t[r].mn),t[x].tp?r && !t[r].lt?t[r].lv-t[x].v:I:
		l && t[l].rt?t[x].v-t[l].rv:I);
}
inline void pushdown(int x){
	int&z=t[x].tg;
	if(z){if(t[x].ch[0])t[t[x].ch[0]].addtag(z);if(t[x].ch[1])t[t[x].ch[1]].addtag(z);z=0;}
}
inline void rotate(int x){
	int y=t[x].fa,z=t[y].fa,o=t[y].dir(x);
	t[z].ch[t[z].dir(y)]=x;t[x].fa=z;
	t[t[x].ch[!o]].fa=y;t[y].ch[o]=t[x].ch[!o];
	t[x].ch[!o]=y;t[y].fa=x;upd(y);
}
inline void splay(int x,int xx=0){
	static int st[N*2];int w=0,y,z;
	for(y=x;y!=xx;y=t[y].fa)st[++w]=y;
	for(;w;)pushdown(st[w--]);
	for(;t[x].fa!=xx;rotate(x)){
		y=t[x].fa;z=t[y].fa;
		if(z!=xx)rotate(t[z].dir(y)==t[y].dir(x)?y:x);
	}
	upd(x);
}
inline void go(int&x,int o){for(;t[x].ch[o];x=t[x].ch[o]);}
inline int merge(int x,int y){
	t[x].fa=t[y].fa=0;
	if(!x || !y)return x|y;
	go(x,1);splay(x);t[x].ch[1]=y;t[y].fa=x;upd(x);return x;
}
inline void stre(int&x,int le){
	if(!x)return;
	for(;t[x].mn<=le*2;){
		for(;;){
			pushdown(x);
			int l=t[x].ch[0],r=t[x].ch[1],y=t[x].fa,o=t[y].dir(x);
			if(!t[x].tp && l && t[l].rt && t[x].v-t[l].rv<=le*2){
				go(l,1);splay(l,x);
				t[l].w+=t[x].w;if(t[l].w>0)t[l].tp=0,t[l].v=t[x].v;upd(l);
				x=merge(t[l].w?l:t[l].ch[0],r);t[y].ch[o]=x;t[x].fa=y;if(!x)x=y;break;
			}
			if(t[x].tp && r && !t[r].lt && t[r].lv-t[x].v<=le*2){
				go(r,0);splay(r,x);
				t[r].w+=t[x].w;if(t[r].w<0)t[r].tp=1,t[r].v=t[x].v;upd(r);
				x=merge(l,t[r].w?r:t[r].ch[1]);t[y].ch[o]=x;t[x].fa=y;if(!x)x=y;break;
			}
			x=t[l].mn<=le*2?l:r;
		}
		splay(x);
	}
	t[x].addtag(le);
}
inline void ins(int&x,int v,int w,int u=0){
	auto getn=[&](){if(!u)u=++tcnt;t[u]=node{0,0,x,0,v,I,w,w,1,w,w,0,0,0};x=u;};
	if(!x)getn();else for(;;){
		if(v==t[x].v){t[x].w+=w;break;}
		pushdown(x);int o=v>t[x].v;
		if(!t[x].ch[o]){t[x].ch[o]=u?u:tcnt+1;getn();break;}
		x=t[x].ch[o];
	}
	splay(x);if(!t[x].w)x=merge(t[x].ch[0],t[x].ch[1]);else t[x].tp=t[x].w<0;upd(x);
}
int aa[N*2],ww;
void dfss(int x){
	pushdown(x);
	if(t[x].ch[0])dfss(t[x].ch[0]);
	aa[++ww]=x;
	if(t[x].ch[1])dfss(t[x].ch[1]);
}
inline void join(int&x,int y){
	ww=0;dfss(y);
	for(i=1;i<=ww;++i)ins(x,t[aa[i]].v,t[aa[i]].w,aa[i]);
}
inline int getv(int&x,int k){
	if(!x)return 0;
	int ans=0;
	for(;;){
		pushdown(x);int o=k>=t[x].v;
		if(o)ans+=t[t[x].ch[0]].s+t[x].w;if(t[x].ch[o])x=t[x].ch[o];else break;
	}
	splay(x);return ans;
}
void dfs(int x,int fa){
	for(auto u:e[x]){
		int y,l;tie(y,l)=u;
		if(y==fa)continue;
		dfs(y,x);
		stre(rt[y],2*l-1);
		if(t[rt[x]].sz<t[rt[y]].sz)swap(rt[x],rt[y]);
		if(rt[y])join(rt[x],rt[y]);
	}
	for(auto&u:ev[x])u.second+=getv(rt[x],u.first);
	stre(rt[x],1);
	for(auto u:ev[x]){
		int xx,y,z;tie(xx,y)=u;z=getv(rt[x],xx);
		if(y>z)ins(rt[x],xx,y-z),ins(rt[x],xx+1,z-y);
	}
}
int main(){
	t[0].mn=I;
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(i=1;i<n;++i)cin>>u>>v>>w,e[u].push_back({v,w}),e[v].push_back({u,w});
	cin>>m;
	for(i=1;i<=m;++i)cin>>w>>v>>u,ev[u].push_back({w*2,v});
	int ans=0,zz=0;
	dfs(1,0);
	ww=0;dfss(rt[1]);for(i=1;i<=ww;++i)ans=max(ans,zz+=t[aa[i]].w);
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<int,pii> piii;
typedef long long ll;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())

int gi() {
	int x=0,o=1;char ch=getchar();
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') o=-1,ch=getchar();
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*o;
}

int n,m,tag;
vector<pii> E[N],obs[N];

int getpos(pii v) {
	return v.fi+(v.se>0?-tag:tag);
}

struct cmp {
	bool operator()(pii a,pii b) {
		return getpos(a)<getpos(b);
	}
};

struct ds {
	int tag;

	set<pii,cmp> val;
	set<piii> crash;

	void insert_crash(pii l,pii r) {
		if(l.se<0&&r.se>0) crash.insert(mp((r.fi-l.fi+1)/2,l));
	}

	void erase_crash(pii l,pii r) {
		if(l.se<0&&r.se>0) crash.erase(mp((r.fi-l.fi+1)/2,l));
	}

	void erase(set<pii,cmp>::iterator it) {
		auto pre=it,nxt=it;
		++nxt;
		if(pre!=val.begin()) {
			--pre;
			erase_crash(*pre,*it);
			if(nxt!=val.end()) insert_crash(*pre,*nxt);
		}
		if(nxt!=val.end()) erase_crash(*it,*nxt);
		val.erase(it);
	}

	void insert(pii v) {
		if(!v.se) return;
		::tag=tag;int tmp=v.fi;
		v.fi+=(v.se>0?tag:-tag);
		auto it=val.find(v);
		if(it!=val.end()) {
			v.se+=it->se;
			erase(it);
		}
		if(!v.se) return;
		v.fi=tmp+(v.se>0?tag:-tag);
		it=val.insert(v).fi;auto pre=it,nxt=it;
		++nxt;
		if(pre!=val.begin()) {
			--pre;
			insert_crash(*pre,v);
			if(nxt!=val.end()) erase_crash(*pre,*nxt);
		}
		if(nxt!=val.end()) insert_crash(v,*nxt);
	}

	void join(ds &A) {
		if(sz(val)<sz(A.val)) {
			swap(tag,A.tag);
			swap(val,A.val);
			swap(crash,A.crash);
		}
		::tag=A.tag;vector<pii> tmp;
		for(auto t:A.val) tmp.pb(mp(getpos(t),t.se));
		::tag=tag;
		for(auto t:tmp) insert(t);
	}

	int delta(int pos) {
		::tag=tag;
		pii v=mp(pos+tag,1);
		auto it=val.find(v);
		if(it!=val.end()) return it->se;
		return 0;
	}

	void process_crash(piii t) {
		auto it=val.find(t.se);assert(it!=val.end());
		pii l=*it;
		auto tmp=it;
		++it;assert(it!=val.end());erase(tmp);
		pii r=*it;erase(it);
		if(l.se+r.se==0) return;
		if(l.se+r.se>0) insert(mp(getpos(r),l.se+r.se));
		else insert(mp(getpos(l),l.se+r.se));
	}

	void advance(int l) {
		::tag=tag;
		while(!crash.empty()&&crash.begin()->fi-tag<=l) {
			process_crash(*crash.begin());
		}
		tag+=l;
	}

	void add(vector<pii> obs,int l) {
		::tag=tag;
		vi tmp;
		for(auto t:obs) {
			int a=delta(t.fi-1),b=delta(t.fi),c=delta(t.fi+1);
			tmp.pb(max(0,t.se-(max({a,a+b,a+b+c})-a-b)));
		}
		advance(1);
		for(int i=0;i<sz(obs);i++) {
			pii t=obs[i];int v=tmp[i];
			if(v) insert(mp(t.fi,v)),insert(mp(t.fi+1,-v));
		}
		advance(l-1);
	}

	int getans() {
		::tag=tag;int ret=0,sum=0;
		for(auto t:val) sum+=t.se,ret=max(ret,sum);
		return ret;
	}
} dp[N];

void dfs(int u,int fa,int fw) {
	for(auto e:E[u]) {
		int v=e.fi,w=e.se;
		if(v!=fa) dfs(v,u,w),dp[u].join(dp[v]);
	}
	dp[u].add(obs[u],fw);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	cin>>n;
	for(int i=1,u,v,w;i<n;i++) {
		u=gi();v=gi();w=gi();
		E[u].pb(mp(v,w<<1));
		E[v].pb(mp(u,w<<1));
	}
	cin>>m;
	for(int i=1;i<=m;i++) {
		int d=gi()<<1,v=gi(),u=gi();
		obs[u].pb(mp(d,v));
	}
	dfs(1,0,1);cout<<dp[1].getans();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<int,pii> piii;
typedef long long ll;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())

int gi() {
	int x=0,o=1;char ch=getchar();
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') o=-1,ch=getchar();
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*o;
}

int n,m,tag;
vector<pii> E[N],obs[N];

int getpos(pii v) {
	return v.fi+(v.se>0?-tag:tag);
}

struct cmp {
	bool operator()(pii a,pii b) {
		return getpos(a)<getpos(b);
	}
};

struct ds {
	int tag;

	set<pii,cmp> val;
	set<piii> crash;

	void print() {
		::tag=tag;
		cerr<<"------value:------\n";
		for(auto t:val) cerr<<"pos="<<getpos(t)<<",diff="<<t.se<<'\n';
		//cerr<<"------crash:------\n";
		//for(auto t:crash) cerr<<"dis="<<t.fi-tag<<",pos="<<t.se<<'\n';
		cerr<<"------------------\n\n";
	}

	void insert_crash(pii l,pii r) {
		if(l.se<0&&r.se>0) crash.insert(mp((r.fi-l.fi+1)/2,l));
	}

	void erase_crash(pii l,pii r) {
		if(l.se<0&&r.se>0) crash.erase(mp((r.fi-l.fi+1)/2,l));
	}

	void erase(set<pii,cmp>::iterator it) {
		auto pre=it,nxt=it;
		++nxt;
		if(pre!=val.begin()) {
			--pre;
			erase_crash(*pre,*it);
			if(nxt!=val.end()) insert_crash(*pre,*nxt);
		}
		if(nxt!=val.end()) erase_crash(*it,*nxt);
		val.erase(it);
	}

	void insert(pii v) {
		if(!v.se) return;
		::tag=tag;int tmp=v.fi;
		v.fi+=(v.se>0?tag:-tag);
		auto it=val.find(v);
		if(it!=val.end()) {
			v.se+=it->se;
			erase(it);
		}
		if(!v.se) return;
		v.fi=tmp+(v.se>0?tag:-tag);
		it=val.insert(v).fi;auto pre=it,nxt=it;
		++nxt;
		if(pre!=val.begin()) {
			--pre;
			insert_crash(*pre,v);
			if(nxt!=val.end()) erase_crash(*pre,*nxt);
		}
		if(nxt!=val.end()) insert_crash(v,*nxt);
		//print();
	}

	void join(ds &A) {
		if(sz(val)<sz(A.val)) {
			swap(tag,A.tag);
			swap(val,A.val);
			swap(crash,A.crash);
		}
		::tag=A.tag;vector<pii> tmp;
		for(auto t:A.val) tmp.pb(mp(getpos(t),t.se));
		::tag=tag;
		for(auto t:tmp) insert(t);
	}

	int delta(int pos) {
		::tag=tag;
		pii v=mp(pos+tag,1);
		auto it=val.find(v);
		if(it!=val.end()) return it->se;
		return 0;
	}

	void process_crash(piii t) {
		auto it=val.find(t.se);assert(it!=val.end());
		pii l=*it;
		auto tmp=it;
		++it;assert(it!=val.end());erase(tmp);
		pii r=*it;erase(it);
		if(l.se+r.se==0) return;
		if(l.se+r.se>0) insert(mp(getpos(r),l.se+r.se));
		else insert(mp(getpos(l),l.se+r.se));
	}

	void advance(int l) {
		::tag=tag;
		while(!crash.empty()&&crash.begin()->fi-tag<=l) {
			process_crash(*crash.begin());
		}
		tag+=l;
	}

	void add(vector<pii> obs,int l) {
		::tag=tag;
		vi tmp;
		for(auto t:obs) {
			int a=delta(t.fi-1),b=delta(t.fi),c=delta(t.fi+1);
			//if(t.fi==8) cerr<<a<<' '<<b<<' '<<c<<'\n';
			tmp.pb(max(0,t.se-(max({a,a+b,a+b+c})-a-b)));
		}
		advance(1);
		//if(l==1) print();
		for(int i=0;i<sz(obs);i++) {
			pii t=obs[i];int v=tmp[i];
			if(v) insert(mp(t.fi,v)),insert(mp(t.fi+1,-v));
		}
		advance(l-1);
	}

	int getans() {
		::tag=tag;int ret=0,sum=0;
		for(auto t:val) sum+=t.se,ret=max(ret,sum);
		return ret;
	}
} dp[N];

void dfs(int u,int fa,int fw) {
	for(auto e:E[u]) {
		int v=e.fi,w=e.se;
		if(v!=fa) dfs(v,u,w),dp[u].join(dp[v]);
	}
	//if(u==1) dp[u].print();
	dp[u].add(obs[u],fw);
	//if(u==1) dp[u].print();
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	cin>>n;
	for(int i=1,u,v,w;i<n;i++) {
		u=gi();v=gi();w=gi();
		E[u].pb(mp(v,w<<1));
		E[v].pb(mp(u,w<<1));
	}
	cin>>m;
	for(int i=1;i<=m;i++) {
		int d=gi()<<1,v=gi(),u=gi();
		obs[u].pb(mp(d,v));
	}
	dfs(1,0,1);cout<<dp[1].getans();
	return 0;
}

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
#define ld long double
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int n;
vector<PI> ask[N],v[N];
struct Set{
	map<int,int> sz,sf;
	priority_queue<PI,vector<PI>,greater<PI> > q;
	int add;
	void bao(int x,int id){
		if(id==1){
			auto it=sf.upper_bound(x-2*add);
			if(it==sf.begin())return; it--;
			q.push(mp(x-it->first,x));
		}else{
			auto it=sz.lower_bound(x+2*add);
			if(it==sz.end())return;
			q.push(mp(it->first-x,it->first));
		}
	}
	void move(int de){
		while(q.size()&&q.top().first<=2*(add+de)){
			PI t=q.top(); q.pop();
			int x=t.second,y=t.second-t.first;
			auto xx=sz.find(x),yy=sf.find(y);
			if(xx==sz.end()||yy==sf.end())continue;
			if(xx->second<-yy->second){
				yy->second+=xx->second; sz.erase(xx); bao(yy->first,-1);
			}else{
				xx->second+=yy->second; sf.erase(yy); bao(xx->first,1);
			}
		}
		add+=de;
	}
	void insert(int x,int de){
		if(de>0){
			sz[x+add]+=de;
			bao(x+add,1);
		}else{
			sf[x-add]+=de;
			bao(x-add,-1);
		}
	}
	int get(){
		int ans=0,dq=0;
		for(auto i=sz.begin(),j=sf.begin();i!=sz.end()&&j!=sf.end();){
			if(i==sz.end()||(j!=sf.end()&&i->first-add>=j->first+add)){
				dq+=j->second; j++;
			}else{
				dq+=i->second; i++;
			}
			ans=max(ans,dq);
		}
		return ans;
	}
	int cha(int pos){
		return (sz.count(pos+add)?sz[pos+add]:0)+(sf.count(pos-add)?sf[pos-add]:0);
	}
	int size(){
		return sz.size()+sf.size();
	}
}s[N];//正数比负数大
void Merge(Set &x,Set &y){
	for(auto i:y.sz){
		x.insert(i.first-y.add,i.second);
	}
	for(auto i:y.sf){
		x.insert(i.first+y.add,i.second);
	}
}
void print(Set s){
	cout<<s.add<<endl;
	for(auto i:s.sz)cout<<i.first-s.add<<" "<<i.second<<" wzp\n";
	for(auto i:s.sf)cout<<i.first+s.add<<" "<<i.second<<" cqz\n";
	puts("");
}
void alb(int x){
	for(auto i:ask[x])if(i.second>0){
		s[x].insert(i.first,i.second);
		s[x].insert(i.first+1,-i.second);
	}
}
void dfs(int p,int fa){
	for(auto i:v[p])if(i.first!=fa){
		int v=i.first,len=i.second;
		dfs(v,p);
		for(auto &j:ask[v])j.second-=max(0,max(-s[v].cha(j.first),s[v].cha(j.first+1)));
		s[v].move(1);
		alb(v);
		s[v].move(len-1);
		if(s[p].size()<s[v].size())swap(s[p],s[v]);
		Merge(s[p],s[v]);
		//print(s[v]);
		//print(s[p]);
		//if(s[p].cha(4)==-2)while(1);
	}
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int s=read(),t=read(),l=read()*2;
		v[s].push_back(mp(t,l));
		v[t].push_back(mp(s,l));
	}
	int m=read();
	while(m--){
		int d=read()*2,x=read(),p=read();
		ask[p].push_back(mp(d,x));
	}
	v[0].push_back(mp(1,2));
	dfs(0,0);
	//print(s[0]);
	cout<<s[0].get()<<endl;
}
/*
sz里存所有正数
sf里存所有负数
q里存所有最近的正负
add里的lazy

毒瘤处:该子树内时必须只能出现在一个位置
之后展开len-1
*/

#include<cstdio>
const int maxn=100010,maxk=100010,inf=1e9;
int n;
struct edge{int to,l; edge*next;}E[maxn*2],*ne=E,*fir[maxn];
struct item{int d,f;item*next;}I[maxk],*fi[maxn];
void link(int u,int v,int l) {*ne=(edge){v,l,fir[u]};fir[u]=ne++;}
int fa[maxn],dep[maxn],siz[maxn],son[maxn];
void init(int i)
{
	siz[i]=1;
	for(edge*e=fir[i];e;e=e->next) if(e->to!=fa[i]){
		fa[e->to]=i;
		dep[e->to]=dep[i]+e->l;
		init(e->to);
		if(siz[e->to]>siz[son[i]]) son[i]=e->to;
		siz[i]+=siz[e->to];
	}
}
void cmax(int &a,int b) {b>a?a=b:1;
}
struct node{
	int l,r,v,ty,md,add;
	node*fa,*ch[2];
	int L(int x){return ty&1?l-x:l+x;
	}
	int R(int x){return ty&2?r-x:r+x;
	}
	int Lv(int x){return L(x)*2+(ty&1);
	}
	int Rv(int x){return R(x)*2+(ty>>1);
	}
	void pu()
	{
		md=ty==1?l-r:-inf;
		if(ch[0]) cmax(md,ch[0]->md);
		if(ch[1]) cmax(md,ch[1]->md);
	}
	void pd()
	 {
	 	if(!add) return;
	 	if(ch[0]) ch[0]->v+=add,ch[0]->add+=add;
	 	if(ch[1]) ch[1]->v+=add,ch[1]->add+=add;
	 	add=0;
	 }
	 void chd(int i,int d,int x)
	 {
	 	if((ty>>i&1)==d) return ;
	 	ty^=1<<i;
	 	x*=d?1:-1;
	 	i?r+=x:l+=x;
	 }
	 void rot(node*&r){
	 	node*f=fa;
	 	int c=this==f->ch[1];
	 	if(f->ch[c]=ch[!c]) ch[!c]->fa=f;
	 	ch[!c]=f;
	 	if(fa=f->fa) fa->ch[f==fa->ch[1]]=this;
	 	f->fa=this;
	 	f->pu();
	 	if(f==r) r=this;
	 }
	void spl(node*&r){
		for(;this!=r;rot(r)) if(fa!=r)
		   (this==fa->ch[1])==(fa==fa->fa->ch[1])?fa->rot(r):rot(r);
		   pu();
	}
	node*fir(int c) {
		return pd(),ch[c]?ch[c]->fir(c):this;
	}
	node*next(){
		if(pd(),ch[1]) return ch[1]->fir(0);
		for(node*x=this;x;x=x->fa) if(x->fa&&x==x->fa->ch[0]) return x->fa;
		return 0;
	}
	node*ins(int c){
		node*x=new node;*x=*this;
		x->ch[!c]=0;
		x->fa=this;
		if(ch[c]) ch[c]->fa=x;
		return ch[c]=x;
	}
	node*ub(int d,int x,bool t=0)
	  {
	  	pd();
	  	if(x<Lv(d)) return ch[0]&&!t?ch[0]->ub(d,x):this;
	  	if(x<Rv(d)) return this;
	  	return ch[1]->ub(d,x);
	  }
	node*maxd()
	{
		if(pd(),ty==1&&l-r==md) return this;
		return ch[ch[1]&&ch[1]->md==md]->maxd();
	}
	int maxv()
	{
		int x=v;pd();
		if(ch[0]) cmax(x,ch[0]->maxv());
		if(ch[1]) cmax(x,ch[1]->maxv());
		return x;
	}
};
void del(node*&f){
	int d=f->l-f->r;
	node*l=f->ch[0],*r=f->ch[1];
	l->fa=r->fa=0;
	l->fir(1)->spl(l);
	r->fir(0)->spl(r);
	l->ch[1]=r;
	r->fa=l;
	r->chd(0,l->v>r->v,d); r->pu();
	l->chd(1,l->v>r->v,d);l->pu();
	f=l;
}
void des(node*x)
{
	if(x->ch[0]) des(x->ch[0]);
	if(x->ch[1]) des(x->ch[1]);
	delete x;
}
node *dfs(int i)
{
	node*f;
	if(son[i]) f=dfs(son[i]);
	else f=new node, *f=(node){-inf,inf,0,2,-inf,0,0,{0,0}};
	int d=dep[i];
	for(edge*e=fir[i];e;e=e->next) if(e->to!=fa[i]&&e->to!=son[i]){
		node*rt=dfs(e->to);
		bool t=0;
		for(node*g=rt->fir(0);g;g=g->next()) if(g->v){
			int l=g->L(d),r=g->R(d),lv=g->Lv(d),rv=g->Rv(d);
			f->ub(d,lv,t)->spl(f);
			node*fl,*fr;
		  if(f->Lv(d)<lv){
		  	fl=f->ins(0);
		  	fl->r=f->l=l-d;
		  	fl->ty&=~2;f->ty&=~1;
		  }
		  else fl=f->ch[0]->fir(1),fl->spl(f->ch[0]);
		  if(fl->v<f->v+g->v) fl->chd(1,0,d*2),f->chd(0,0,d*2);
		  fl->spl(f);
		  fl=f->ch[1]->ub(d,rv-1);
		  fl->spl(f->ch[1]);
		  if(fl->Rv(d)>rv){
		  	fr=fl->ins(1);
		  	fl->r=fr->l=r+d;
		  	fl->ty|=2;fr->ty|=1;
		  }
		else fr=fl->ch[1]->fir(0),fr->spl(fl->ch[1]);
		fl->v+=g->v;
		if(fl->ch[0]) fl->ch[0]->v+=g->v,fl->ch[0]->add+=g->v;
		if(fr->v<fl->v) fr->chd(0,1,d*2),fl->chd(1,1,d*2);
		fr->spl(f);
		t=1;
		}
		des(rt);
	}
for(item*it=fi[i];it;it=it->next)
  {
  	f->ub(d,it->d*2+1)->spl(f);
  	node*f0=f->ins(0);
  	node*f1=f->ins(0);
  	f0->r=f1->l=it->d+1-d;
  	f1->r=f->l=it->d+d;
  	f1->v+=it->f;
  	f0->ty&=~2;f1->ty&=~1;
  	f1->ty|=2;f->ty|=1;
  	f0->spl(f);
  }
  while(f->md>=dep[fa[i]]*2){
  	f->maxd()->spl(f),del(f);
  }
  return f;
}
int main()
{
	scanf("%d",&n);
	for(int i=1,u,v,l;i<n;i++) scanf("%d%d%d",&u,&v,&l),link(u,v,l),link(v,u,l);
	int k;scanf("%d",&k);
	for(int i=0,p;i<k;i++) scanf("%d%d%d",&I[i].d,&I[i].f,&p), I[i].next=fi[p],fi[p]=I+i;
	init(1);
	node*f=dfs(1);
	printf("%d\n",f->maxv());
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    //printf("(insertc) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("insertc "),c.dump(),printf("\n");
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    //printf("(erasec) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("erasec "),c.dump(),printf("\n");
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    //printf("INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A){
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    //printf("CHECKING FOR "),l.dump(),printf(" and "),r.dump(),printf("\n");
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    //printf("CANCEL INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      //printf("INSERT CANCEL "),e.dump(),printf(" with "),e2.dump(),printf(" => "),cancel(e,e2).dump(),printf("\n");
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    //printf("ERASE "),e.dump(),printf("\n");
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    //printf("ANNIHILIATE "),c.dump(),printf(" => "),cancel(c.e1,c.e2).dump(),printf("\n");
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
    //dump();
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t){
    while(collide.size()&&collide.begin()->time2<t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
    //printf("MERGE %I64d into %I64d\n",child+1,node+1);
    //dss[node].dump();
  }
  //printf("BEFORE CLEANUP\n");
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node]){
    f.second=dss[node].prep(f.first,f.second);
  }
  //dss[node].dump();
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  //printf("BEFORE ADDING FISH\n");
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  current_time=-depth[node];
  for(auto f:fish[node]){
    int D=f.first,F=f.second;
    current_time=-depth[node];
    //dss[node].insert_fish(D,F);
    //printf("ADDING %I64d,%I64d at %I64d\n",ls[i],rs[i],fish[node][i].first);
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
  //printf("POST %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    //dss[P].insert(End(D,1,F,current_time));
    //dss[P].insert(End(D,-1,F,current_time));
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  //printf("FINAL\n");
  //dss[0].dump();
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A){
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void erase(struct End e){
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
  }
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node]){
    f.second=dss[node].prep(f.first,f.second);
  }
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  for(auto f:fish[node]){
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

struct State {
	int delta;
	map<int,int> pos;
	map<int,int> neg;
	set<pair<int,pair<int,int>>> matches;

	void init() {
		delta=0; pos.clear(); neg.clear(); matches.clear();
	}

	int findmatchforpos(int x) {
		auto it=neg.lower_bound(x+delta);
		return it==neg.end()?INT_MAX:it->first-delta;
	}
	int findmatchforneg(int y) {
		auto it=pos.upper_bound(y-delta);
		return it==pos.begin()?INT_MIN:prev(it)->first+delta;
	}
	void erasepos(int x) {
		//printf("erasepos(%d)\n",x);
		assert(pos.erase(x-delta));
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx==INT_MIN||xx<=x) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(xx!=INT_MIN&&xx<=x&&findmatchforpos(xx)==y) matches.insert(MP(y-xx+2*delta,MP(xx-delta,y+delta)));
		}
		//print();
	}
	void eraseneg(int y) {
		//printf("eraseneg(%d)\n",y);
		assert(neg.erase(y+delta));
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy==INT_MAX||yy>=y) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(yy!=INT_MAX&&yy>=y&&findmatchforneg(yy)==x) matches.insert(MP(yy-x+2*delta,MP(x-delta,yy+delta)));
		}
		//print();
	}
	void insertpos(int x,int val) {
		//printf("insertpos(%d,%d)\n",x,val);
		if(pos.count(x-delta)) { pos[x-delta]+=val; return; }
		//if(neg.count(x+delta)) { int cur=neg[x+delta]; if(val<cur) { neg[x+delta]-=val; return; } eraseneg(x); val-=cur; if(val==0) return; }
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx!=INT_MIN&&xx<x&&findmatchforpos(xx)==y) assert(matches.erase(MP(y-xx+2*delta,MP(xx-delta,y+delta))));
			if(xx==INT_MIN||xx<x) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		pos[x-delta]=val;
		//print();
	}
	void insertneg(int y,int val) {
		//printf("insertneg(%d,%d)\n",y,val);
		if(neg.count(y+delta)) { neg[y+delta]+=val; return; }
		//if(pos.count(y-delta)) { int cur=pos[y-delta]; if(val<cur) { pos[y-delta]-=val; return; } erasepos(y); val-=cur; if(val==0) return; }
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy!=INT_MAX&&yy>y&&findmatchforneg(yy)==x) assert(matches.erase(MP(yy-x+2*delta,MP(x-delta,yy+delta))));
			if(yy==INT_MAX||yy>y) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		neg[y+delta]=val;
		//print();
	}
	void grow(int by) {
		//printf("growing(%d)\n",by); print();
		while(SZ(matches)!=0&&matches.begin()->first-2*delta<2*by) {
			int x=matches.begin()->second.first+delta,y=matches.begin()->second.second-delta;
			//printf("x=%d y=%d\n",x,y); print();
			assert(pos.count(x-delta)); int xval=pos[x-delta]; assert(neg.count(y+delta)); int yval=neg[y+delta];
			if(xval<yval) { neg[y+delta]-=xval; erasepos(x); } else if(xval>yval) { pos[x-delta]-=yval; eraseneg(y); } else { erasepos(x); eraseneg(y); }
		}
		delta+=by;
	}
	void print() {
		printf("\tneg:"); for(auto it=neg.begin();it!=neg.end();++it) printf(" %d=%d",it->first-delta,it->second); puts("");
		printf("\tpos:"); for(auto it=pos.begin();it!=pos.end();++it) printf(" %d=%d",it->first+delta,it->second); puts("");
		printf("\tmatches:"); for(auto it=matches.begin();it!=matches.end();++it) printf(" %d:%d-%d",it->first-2*delta,it->second.first+delta,it->second.second-delta); puts("");
	}
};

const int MAXN=100000;

int n;
vector<pair<int,int>> e[MAXN];
int nq;
vector<pair<int,int>> obs[MAXN];

State state[MAXN];

int merge(int a,int b) {
	int asz=SZ(state[a].pos)+SZ(state[a].neg),bsz=SZ(state[b].pos)+SZ(state[b].neg);
	if(asz<bsz) swap(a,b),swap(asz,bsz);
	for(auto it=state[b].pos.begin();it!=state[b].pos.end();++it) state[a].insertpos(it->first+state[b].delta,it->second);
	for(auto it=state[b].neg.begin();it!=state[b].neg.end();++it) state[a].insertneg(it->first-state[b].delta,it->second);
	return a;
}

int dfs(int at,int par,int parlen) {
	int ret=at; state[ret].init();
	REPSZ(i,e[at]) {
		int to=e[at][i].first; if(to==par) continue;
		int cur=dfs(to,at,e[at][i].second);
		ret=merge(ret,cur);
	}
	vector<pair<int,int>> extra;
	REPSZ(i,obs[at]) {
		int t=obs[at][i].first,cnt=obs[at][i].second,rem=cnt;
		{ int cur=(state[ret].pos.count(t-state[ret].delta)?state[ret].pos[t-state[ret].delta]:0)+(state[ret].pos.count(t-state[ret].delta-1)?state[ret].pos[t-state[ret].delta-1]:0); rem=min(rem,max(0,cnt-cur)); }
		{ int cur=(state[ret].neg.count(t+state[ret].delta)?state[ret].neg[t+state[ret].delta]:0)+(state[ret].neg.count(t+state[ret].delta+1)?state[ret].neg[t+state[ret].delta+1]:0); rem=min(rem,max(0,cnt-cur)); }
		if(rem>0) extra.PB(MP(t,rem));
	}
	state[ret].grow(1);
	REPSZ(i,extra) { int t=extra[i].first,cnt=extra[i].second; state[ret].insertneg(t-1,cnt); state[ret].insertpos(t+1,cnt); }
	state[ret].grow(parlen-1);
	//printf("dfs(%d,%d,%d):\n",at+1,par==-1?-1:par+1,parlen); state[ret].print();
	return ret;
}

int solve() {
	REP(i,n) sort(obs[i].begin(),obs[i].end());
	int res=dfs(0,-1,1);
	map<int,int> all;
	for(auto it=state[res].pos.begin();it!=state[res].pos.end();++it) all[2*(it->first+state[res].delta)+0]-=it->second;
	for(auto it=state[res].neg.begin();it!=state[res].neg.end();++it) all[2*(it->first-state[res].delta)+1]+=it->second;
	int ret=0,cur=0;
	for(auto it=all.begin();it!=all.end();++it) {
		cur+=it->second;
		ret=max(ret,cur);
	}
	return ret;
}

void run() {
	scanf("%d",&n);
	REP(i,n-1) { int a,b,c; scanf("%d%d%d",&a,&b,&c); --a,--b,c*=2; e[a].PB(MP(b,c)); e[b].PB(MP(a,c)); }
	scanf("%d",&nq);
	REP(i,nq) { int t,cnt,idx; scanf("%d%d%d",&t,&cnt,&idx); t*=2; --idx; obs[idx].PB(MP(t,cnt)); }

	printf("%d\n",solve());
}

int main() {
	run();
	return 0;
}

//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define bged(v) (v).begin(),(v).end()
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#ifndef LOCAL
#define cerr if(0)cout
#endif
typedef long long ll;
const int Imx=2147483647;
const ll Lbig=2e18;
const int mod=1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it,len;
	fastio(){it=len=0;}
	inline char get()
	{
		if(it<len)return s[it++];it=0;
		len=fread(s,1,100000,stdin);
		if(len==0)return EOF;else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while(c==' '||c=='\n')c=get();
		if(it>0)it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0;bool ng=0;char c;c=_buff.get();
	while(c!='-'&&(c<'0'||c>'9'))c=_buff.get();
	if(c=='-')ng=1,c=_buff.get();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=_buff.get();
	return ng?-r:r;
}
template<class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline char getreal(){char c=_buff.get();while(c<=32)c=_buff.get();return c;}
ll qpow(ll x,ll k){return k==0?1:1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;}
const int maxn=100111;
int CURT;
struct Function
{
	#define Qv(M,x) ((M).find(x)==(M).end()?0:M[x])
	int T;
	void UPDT(){CURT=T;}
	struct element
	{
		int x,v;
		element(int X=0,int V=0){x=X;v=V;}
		inline int getT()const{return v>0?x-CURT:x+CURT;}
		bool operator<(const element &t)const
		{
			if(getT()!=t.getT())return getT()<t.getT();
			return v<t.v;
		}
	};
	int get_element_T(const element &t){UPDT();return t.getT();}
	unordered_map<int,int> M[2];//0-negative 1-positive
	set<element> all;
	set<pair<int,pair<int,int> > > st;
	void debug(int id)
	{
		UPDT();
		cerr<<"Debug "<<id<<" T="<<T<<endl;
		for(set<element>::iterator it=all.begin();it!=all.end();it++)cerr<<it->getT()<<","<<it->v<<" ";cerr<<endl;
		for(auto it:M[0])cerr<<it.FF<<","<<it.SS<<" ";cerr<<endl;
		for(auto it:M[1])cerr<<it.FF<<","<<it.SS<<" ";cerr<<endl;
	}
	void add_relation(int x,int y)
	{
		int t=(y-x+1)/2;
		assert(t>0);
		st.insert(MP(t,MP(x,y)));
	}
	void all_insert(element x)
	{
		if(x.v==0)return;
		UPDT();
		all.insert(x);
		set<element>::iterator it=all.find(x);
		if(x.v>0&&it!=all.begin())
		{
			it--;
			if(it->v<0)add_relation(it->x,x.x);
		}
		else if(x.v<0)
		{
			it++;
			if(it!=all.end()&&it->v>0)add_relation(x.x,it->x);
		}
	}
	void all_del(element x)
	{
		if(x.v==0)return;
		UPDT();
		set<element>::iterator it=all.find(x),it0=it,it1=it0;
		assert(it!=all.end());
		it1++;
		if(it0!=all.begin()&&it1!=all.end())
		{
			it0--;
			if(it0->v<0&&it1->v>0)add_relation(it0->x,it1->x);
		}
		all.erase(x);
	}
	void add(int t,int p,int v)
	{
		if(v==0)return;
		int cur=0;
		if(M[t].find(p)!=M[t].end())all_del(element(p,M[t][p])),cur=M[t][p];
		M[t][p]=cur+v;
		all_insert(element(p,M[t][p]));
	}
	void Add(int x,int v)
	{
		if(v==0)return;
		int t=v>0,p,q;
		if(t)p=x+T,q=x-T;else p=x-T,q=x+T;
		int qval=Qv(M[t^1],q);
		if(qval)
		{
			if(abs(qval)>=abs(v))add(t^1,q,v),v=0;
			else add(t^1,q,-qval),v+=qval;
		}
		add(t,p,v);
		assert((Qv(M[t],p)!=0)+(Qv(M[t^1],q)!=0)<=1);
	}

	void merge(int x,int y)
	{
		if(M[0].find(x)!=M[0].end()&&M[1].find(y)!=M[1].end())
		{
			int dlt=min(-M[0][x],M[1][y]);
			assert(dlt>=0);
			add(0,x,dlt);
			add(1,y,-dlt);
		}
	}
	void go(int dt)
	{
		int nT=T+dt;
		while(st.size()>0&&st.begin()->FF<=nT)
		{
			merge(st.begin()->SS.FF,st.begin()->SS.SS);
			st.erase(st.begin());
		}
		T=nT;
	}
	int getmx()
	{
		UPDT();
		int v=0,mx=0;
		for(set<element>::iterator it=all.begin();it!=all.end();it++)
		{
			v+=it->v;
			mx=max(mx,v);
		}
		return mx;
	}
	int getdlt(int x)
	{
		return Qv(M[0],x-T)+Qv(M[1],x+T);
	}
	int getndlt(int x,int f)
	{
		int d0=getdlt(x);
		int d1=getdlt(x+1);
		return max(0,f-max(0,max(0-d0,d1)));
	}
}yxg[maxn*2];
int tot;
int Merge(int x,int y)
{
	if(yxg[x].all.size()>yxg[y].all.size())return Merge(y,x);
//	cerr<<"======Merge:"<<endl;
//	yxg[x].debug(x);
//	yxg[y].debug(y);
//	cerr<<"------------"<<endl;
	for(set<Function::element>::iterator it=yxg[x].all.begin();it!=yxg[x].all.end();it++)
	{
		yxg[y].Add(yxg[x].get_element_T(*it),it->v);
	}
//	yxg[y].debug(y);
//	cerr<<"==========="<<endl;
	return y;
}
int n,m;
vector<pair<int,int> > con[maxn];
vector<pair<int,int> > v[maxn];
int id[maxn];
void dfs(int x,int pre=-1)
{
//	cerr<<"dfs:"<<x<<endl;
	id[x]=0;
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i].FF;
		if(u==pre)continue;
		dfs(u,x);
		yxg[id[u]].go(con[x][i].SS*2-1);
		if(id[x]==0)id[x]=id[u];
		else id[x]=Merge(id[x],id[u]);
	}
	if(id[x]==0)id[x]=++tot;
	if(x!=1)
	{
		vector<int> V;
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			V.PB(yxg[id[x]].getndlt(d*2,f));
//			cerr<<"ndlt="<<yxg[id[x]].getndlt(d*2,f)<<endl;
		}
		yxg[id[x]].go(1);
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			yxg[id[x]].Add(d*2,V[i]);
			yxg[id[x]].Add(d*2+1,-V[i]);
		}
	}
	else
	{
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			yxg[id[x]].Add(d*2,f);
			yxg[id[x]].Add(d*2+1,-f);
		}
	}
//	cerr<<"_____________"<<x<<" "<<yxg[id[x]].getmx()<<endl;
//	yxg[id[x]].debug(x);
}
int main()
{
	geti(n);
	for(int i=1;i<n;i++)
	{
		int x,y,d;
		getiii(x,y,d);
		con[x].PB(MP(y,d));
		con[y].PB(MP(x,d));
	}
	geti(m);
	for(int i=1;i<=m;i++)
	{
		int d,f,p;
		getiii(d,f,p);
		v[p].PB(MP(d,f));
	}
	dfs(1);
	int ans=yxg[id[1]].getmx();
	cout<<ans<<endl;
	return 0;
}

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<functional>
#include<cmath>
#include<string>
#include<set>
#include<map>
#define SIZE 200005

using namespace std;
typedef long long int ll;
typedef pair<ll,ll>P;
typedef pair
PP;

struct edge
{
int to;
ll cost;
edge(int to=0,ll cost=0):to(to),cost(cost){}
};
vector<edge>vec[SIZE];
vector
up[SIZE];
vector
down[SIZE];
vector<int>vt[SIZE];
ll dep[SIZE];
int nd[SIZE],back[SIZE];
int pos[SIZE],cmb[SIZE];
int par[SIZE],len[SIZE];
PP now[SIZE];
int now_sz;

void dfs(int v=0,int p=-1,ll d=0)
{
dep[v]=d;
nd[v]=1;
for(int i=0;i<vec[v].size();i++)
{
edge e=vec[v][i];
if(e.to!=p)
{
dfs(e.to,v,d+e.cost);
nd[v]+=nd[e.to];
}
}
}
void heavy_light(int v=0,int p=-1,int b=-1)
{
vt[now_sz].push_back(v);
par[now_sz]=b;
back[v]=b;
pos[v]=len[now_sz]++;
cmb[v]=now_sz;
bool up=false;
for(int i=0;i<vec[v].size();i++)
{
edge e=vec[v][i];
if(e.to!=p&&nd[e.to]*2>=nd[v])
{
heavy_light(e.to,v,b);
up=true;
break;
}
}
if(!up)
{
now_sz++;
}
for(int i=0;i<vec[v].size();i++)
{
edge e=vec[v][i];
if(e.to!=p&&nd[e.to]*2<nd[v])
{
heavy_light(e.to,v,v);
}
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n-1;i++)
{
int a,b;
ll c;
scanf("%d%d%lld",&a,&b,&c);a--,b--,c*=(ll)n,c--;
vec[a].push_back(edge(b,c));
vec[b].push_back(edge(a,c));
}
dfs();
heavy_light();
int m;
scanf("%d",&m);
ll all=0;
for(int i=0;i<m;i++)
{
ll t;
int f,v;
scanf("%lld%d%d",&t,&f,&v);t*=(ll)n,v--;
up[v].push_back(P(t+dep[v],f));
down[v].push_back(P(t-dep[v]-1,f));
all+=f;
}
ll ret=0;
for(int t=now_sz-1;t>=0;t--)
{
int sz=0;
for(int i=0;i<vt[t].size();i++)
{
int v=vt[t][i];
for(int j=0;j<up[v].size();j++)
{
P p=up[v][j];
now[sz++]=PP(P(p.first,-1),P(p.first-2LL*dep[v],p.second));
}
for(int j=0;j<down[v].size();j++)
{
P p=down[v][j];
now[sz++]=PP(P(p.first+2LL*dep[v],1),p);
}
}
multiset
st;
multiset
::iterator it;
sort(now,now+sz);
for(int i=sz-1;i>=0;i--)
{
if(now[i].first.second==-1){
P q=now[i].second;
while(q.second>0)
{
it=st.lower_bound(P(q.first,-1));
if(it!=st.end())
{
P p=*it;
ll df=now[i].first.first-p.first;
if(t==0||df>=2LL*dep[par[t]])
{
st.erase(it);
ll c=min(q.second,p.second);
ret+=c;
q.second-=c;
p.second-=c;
if(p.second>0)st.insert(p);
}
else break;
}
else break;
}
if(q.second>0&&t>0)up[par[t]].push_back(P(now[i].first.first,q.second));
}
else{
st.insert(now[i].second);
}
}
if(t>0)
{
for(it=st.begin();it!=st.end();it++)down[par[t]].push_back(*it);
st.clear();
}
}
printf("%lld\n",all-ret);
return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int inf=2147483647;
int n,m,d[100010],now;
struct node
{
	int x,d,v;
	bool operator < (const node &y) const
	{
		int a=x+now*d;
		int b=y.x+now*y.d;
		if (a==b)
		{
			return d<y.d;
		}
		else
		{
			return a<b;
		}
	}
};
struct col
{
	node x,y;
	int ti;
	col(node a,node b)
	{
		x=a;
		y=b;
		ti=(y.x-x.x)/2;
	}
	bool operator < (const col &a) const
	{
		if (ti!=a.ti)
		{
			return ti<a.ti;
		}
		if (x.x!=a.x.x)
		{
			return x.x<a.x.x;
		}
		if (x.v!=a.x.v)
		{
			return x.v<a.x.v;
		}
		if (y.x!=a.y.x)
		{
			return y.x<a.y.x;
		}
		return y.v<a.y.v;
	}
};
struct yxg
{
	set<node> sn;
	set<col> sc;
	void insc(node x,node y)
	{
		if (x.d>0 && y.d<0)
		{
			sc.insert(col(x,y));
		}
	}
	void delc(node x,node y)
	{
		if (x.d>0 && y.d<0)
		{
			sc.erase(col(x,y));
		}
	}
	void del(node x)
	{
		set<node>::iterator it,nxt,pre;
		it=sn.insert(x).first;
		nxt=it;
		nxt++;
		pre=it;
		pre--;
		if (nxt!=sn.end())
		{
			delc(*it,*nxt);
		}
		if (it!=sn.begin())
		{
			delc(*pre,*it);
			if (nxt!=sn.end())
			{
				insc(*pre,*nxt);
			}
		}
		sn.erase(it);
	}
	void ins(node x)
	{
		if (!x.v)
		{
			return;
		}
		if (sn.find(x)!=sn.end())
		{
			x.v+=sn.find(x)->v;
			del(*sn.find(x));
		}
		set<node>::iterator it,nxt,pre;
		it=sn.insert(x).first;
		nxt=it;
		nxt++;
		pre=it;
		pre--;
		if (it!=sn.begin())
		{
			if (nxt!=sn.end())
			{
				delc(*pre,*nxt);
			}
			insc(*pre,*it);
		}
		if (nxt!=sn.end())
		{
			insc(*it,*nxt);
		}
	}
	int reset(int x,int y)
	{
		node l,r;
		l=(node){x+1+now,-1,y};
		r=(node){x-1-now,1,y};
		int a,b;
		if (sn.find(l)!=sn.end())
		{
			a=sn.find(l)->v;
		}
		else
		{
			a=0;
		}
		if (sn.find(r)!=sn.end())
		{
			b=sn.find(r)->v;
		}
		else
		{
			b=0;
		}
		return max(0,y-max(a,b));
	}
	node cancel(node x,node y)
	{
		if (x.v>y.v)
		{
			return (node){x.x,x.d,x.v-y.v};
		}
		else
		{
			return (node){y.x,y.d,y.v-x.v};
		}
    }
    void Col(col x)
    {
    	del(x.x);
    	del(x.y);
    	ins(cancel(x.x,x.y));
	}
	void maintain(int x)
	{
		while (!sc.empty() && sc.begin()->ti<=x)
		{
			Col(*sc.begin());
		}
	}
	int ask()
	{
		int res=0;
		for (set<node>::iterator it=sn.begin();it!=sn.end();it++)
		{
			if ((*it).d>0)
			{
				res+=(*it).v;
			}
		}
		return res;
	}
}a[100010];
void merge(yxg &a,yxg &b)
{
	if (a.sn.size()<b.sn.size())
	{
		swap(a.sn,b.sn);
		swap(a.sc,b.sc);
	}
	for (set<node>::iterator it=b.sn.begin();it!=b.sn.end();it++)
	{
		a.ins(*it);
	}
}
vector<pair<int,int> > v[100010],fish[100010];
void dfs(int x,int fa)
{
	for (int i=0;i<v[x].size();i++)
	{
		int y=v[x][i].x;
		if (y==fa)
		{
			continue;
		}
		d[y]=d[x]+v[x][i].y;
		dfs(y,x);
	}
}
void solve(int x,int fa)
{
	for (int i=0;i<v[x].size();i++)
	{
		int y=v[x][i].x;
		if (y==fa)
		{
			continue;
		}
		solve(y,x);
		now=-d[y];
		a[y].maintain(-(d[x]+1));
		now=-(d[x]+1);
		merge(a[x],a[y]);
	}
	now=-(d[x]+1);
	for (int i=0;i<fish[x].size();i++)
	{
		fish[x][i].y=a[x].reset(fish[x][i].x,fish[x][i].y);
	}
	a[x].maintain(-d[x]);
	now=-d[x];
	for (int i=0;i<fish[x].size();i++)
	{
		a[x].ins((node){fish[x][i].x+now,-1,fish[x][i].y});
		a[x].ins((node){fish[x][i].x-now,1,fish[x][i].y});
	}
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<n;i++)
	{
		int x,y,w;
		scanf("%d%d%d",&x,&y,&w);
		w*=2;
		v[x].push_back(make_pair(y,w));
		v[y].push_back(make_pair(x,w));
	}
	scanf("%d",&m);
	for (int i=0;i<m;i++)
	{
		int d,f,p;
		scanf("%d%d%d",&d,&f,&p);
		d*=2;
		fish[p].push_back(make_pair(d,f));
	}
	dfs(1,0);
	solve(1,0);
	a[1].maintain(inf);
	printf("%d\n",a[1].ask());
	return 0;
}

/*
ID: bqi3431
PROG: ~
LANG: C++11
*/

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define beg(x) x.begin()
#define en(x) x.end()
#define all(x) beg(x), en(x)
#define resz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 100005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    template<class U> modular(const U& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }
    friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular exp(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) { return invGeneral(a.val,MOD); }
    // inv is equivalent to return exp(b,b.mod-2) if prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

struct seg {
    map<int,int> neg, pos;
    set<pair<int,pi>> dif;
    int lazy;
    int size() { return sz(pos)+sz(neg); }
    vpi change() {
        map<int,int> v;
        trav(t,pos) v[t.f-lazy] += t.s;
        trav(t,neg) v[t.f+lazy] += t.s;
        return vpi(all(v));
    }
    bool ok(auto negIt, auto posIt) {
        return negIt->f+2*lazy <= posIt->f;
    }
    void printInfo() {
    	ps("LAZY: ",lazy);
    	pr("NEG: "); trav(t,neg) pr(mp(t.f+lazy,t.s),' '); ps();
    	pr("POS: "); trav(t,pos) pr(mp(t.f-lazy,t.s),' '); ps();
    	pr("DIF: "); trav(t,dif) pr(mp(t.f-2*lazy,mp(t.s.f+lazy,t.s.s-lazy)),' '); ps();
    }
    void nrem(map<int,int>::iterator it) {
        auto it1 = pos.lb(it->f+2*lazy);
        if (it1 != pos.end() && (next(it) == neg.end() || !ok(next(it),it1)))
            dif.erase({it1->f-it->f,{it->f,it1->f}});
    }
    void nins(map<int,int>::iterator it) {
        auto it1 = pos.lb(it->f+2*lazy);
        if (it1 != pos.end() && (next(it) == neg.end() || !ok(next(it),it1)))
            dif.insert({it1->f-it->f,{it->f,it1->f}});
    }
    void prem(map<int,int>::iterator it) {
        auto it1 = neg.ub(it->f-2*lazy); if (it1 == neg.begin()) return;
        it1 --;
        if (it == pos.begin() || !ok(it1,prev(it)))
            dif.erase({it->f-it1->f,{it1->f,it->f}});
    }
    void pins(map<int,int>::iterator it) {
        auto it1 = neg.ub(it->f-2*lazy); if (it1 == neg.begin()) return;
        it1 --;
        if (it == pos.begin() || !ok(it1,prev(it)))
            dif.insert({it->f-it1->f,{it1->f,it->f}});
    }
    void insPos(int t, int f) {
        auto it = neg.ub(t-2*lazy);
        if (it != neg.begin()) nrem(prev(it));
        pos[t] += f;
        if (it != neg.begin()) nins(prev(it));
    }
    void insNeg(int t, int f) {
        auto it = pos.lb(t+2*lazy);
        if (it != pos.end()) prem(it);
        neg[t] += f;
        if (it != pos.end()) pins(it);
    }
    void ins(int t, int f) {
        // printInfo();
        if (f == 0) return;
        if (f > 0) insPos(t+lazy,f);
        else insNeg(t-lazy,f);
        /*ps("INS",t,f);
        printInfo();
        ps("-----");*/
    }
    void INS(int t, int f) {
        ins(t-1,f); ins(t,-f);
    }
    int getUpd(int x) {
    	int res = 0;
    	if (neg.count(x-lazy-1)) ckmax(res,-neg[x-lazy-1]);
    	if (pos.count(x+lazy)) ckmax(res,pos[x+lazy]);
    	// neg: x-lazy-1
    	// pos: x+lazy
    	return res;
    }
    void adv(int x) {
        /*ps("START ADV ",x);
        printInfo();
        ps("----");*/
        while (sz(dif) && dif.begin()->f <= 2*lazy+2*x) {
            auto a = *dif.begin(); nrem(neg.find(a.s.f));
            int tot = neg[a.s.f]+pos[a.s.s]; neg.erase(a.s.f), pos.erase(a.s.s);
            if (tot < 0) {
                neg[a.s.f] = tot;
                nins(neg.find(a.s.f));
                // ps("NINS");
            } else if (tot > 0) {
                pos[a.s.s] = tot;
                pins(pos.find(a.s.s));
                // ps("PINS");
            } else {
                auto it = neg.lb(a.s.f);
                if (it != neg.begin()) nins(prev(it));
            }
            /*printInfo();
            ps("----");*/
            // erase one or two
            // maintain dif
        }
        //ps("WUT",co);  if (co == 100) exit(0);
        lazy += x;
        // printInfo(); ps("DONE----");
    }
};

int n,k;
vpi o[MX], adj[MX];
seg S[MX];

void init() {
	setIO(); re(n);
	F0R(i,n-1) {
	    int u,v,l; re(u,v,l); l *= 2;
	    // ps("HA",u,v,l);
	    adj[u].pb({v,l}), adj[v].pb({u,l});
	}
	re(k);
	F0R(i,k) {
	    int d,f,p; re(d,f,p); d *= 2;
	    // ps("OH",d,f,p);
	    o[p].pb({d,f});
	}
}

void dfs(int x, int p, int l) {
    trav(t,adj[x]) if (t.f != p) {
        dfs(t.f,x,t.s);
        if (sz(S[t.f]) > sz(S[x])) swap(S[x],S[t.f]);
        auto v = S[t.f].change();
        trav(t,v) S[x].ins(t.f,t.s);
    }
    // ps("WUT",x,l);
    trav(t,o[x]) t.s = max(0,t.s-S[x].getUpd(t.f));
    if (l) S[x].adv(1), l--;
    trav(t,o[x]) S[x].INS(t.f,t.s);
    S[x].adv(l);
    // ps("HUH",x,S[x].change(),l);
}

int main() {
	init();
	dfs(1,0,0);
	auto v = S[1].change();
	int cur = 0, ret = 0;
	trav(t,v) ckmax(ret,cur += t.s);
	ps(ret);
    // you should actually read the stuff at the bottom
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type) return x.type<y.type;
		return x.id<y.id;
	}
};
bool cmp2(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type>y.type;
	return x.id<y.id;
}
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	bool check_find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		return s.find(x)!=s.end();
	}
	K find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		return to_outside_form(*it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
//		printf("[+%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
//		printf("[-%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
//		if(!s.empty()){
//			x=*s.begin();
//			printf("[^%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
//		}
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void insert2(K x,int len){
		while(1){
			K y,z;
			bool f1,f2;
			insert(x);
			s.get_pos(x,y,f1,z,f2);
			if(f1&&check_k2(y,x)){
				if(x.time-y.time<len){
					erase(x);
					erase(y);
					if(x.x==y.x) break;
					else if(x.x<y.x){
						y.x-=x.x;
						x.x=0;
						insert(y);
						break;
					}else{
						x.x-=y.x;
						y.x=0;
					}
				}else break;
			}else break;
		}
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
//			printf("[*%d %d %d %d]\n",k.p1.type,k.p1.id,k.p2.type,k.p2.id);
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f); printf("->");
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		for(auto x:f){
			sum+=x.type*x.x;
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
void dfs(int x,int pre,int len){
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
//			printf("<%d %d>",x,y); op[y].print();
			for(auto t:last[y]){
				K k=t; k.time-=k.type*G.edge[j].key;
				op[y].insert(k);
			}
//			printf("<%d %d>",x,y); op[y].print();
//			exit(0);
			merge(op[x],op[y]);
		}
	}
	for(int i=0;i<ff[x].size();i+=2){
		op[x].insert2(ff[x][i],len+len+(x==1));
		if(op[x].s.check_find(ff[x][i])){
			K k=op[x].s.find(ff[x][i]);
			op[x].erase(ff[x][i]=k);
			last[x].push_back(ff[x][i]);
		//	printf("{%d %d %d %d}\n",k.time,k.x,k.type,k.id);
		}else ff[x][i].x=0;
		op[x].insert(ff[x][i+1]);
//		op[x].update(len+len+(x==1));
	//	printf("<%d>",x);
	//	op[x].print();
	}
//	printf("<%d>",x);
//	op[x].print();
}
map<int,vector<K> > mp;
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	for(int i=1;i<=n;++i) sort(ff[i].begin(),ff[i].end(),cmp2);
	dfs(1,0,0);
//	op[1].print();
	for(auto x:last[1]){
		K k=x;
		op[1].insert(k);
	}
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type) return x.type<y.type;
		return x.id<y.id;
	}
};
bool cmp(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type<y.type;
	return x.id<y.id;
}

bool cmp2(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type>y.type;
	return x.id<y.id;
}
bool cmp3(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.id!=y.id) return x.id<y.id;
	return x.type>y.type;
}
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	bool check_find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		return s.find(x)!=s.end();
	}
	K find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		return to_outside_form(*it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
//		printf("[+%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
//		printf("[-%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
//		if(!s.empty()){
//			x=*s.begin();
//			printf("[^%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
//		}
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void insert2(K x,int len){
		while(1){
			K y,z;
			bool f1,f2;
			insert(x);
			s.get_pos(x,y,f1,z,f2);
			if(f1&&check_k2(y,x)){
				if(x.time-y.time<len){
					erase(x);
					erase(y);
					if(x.x==y.x) break;
					else if(x.x<y.x){
						y.x-=x.x;
						x.x=0;
						insert(y);
						break;
					}else{
						x.x-=y.x;
						y.x=0;
					}
				}else break;
			}else break;
		}
	}
	void insert3(K x,K nxt,int len){
		while(1){
			K y,z; bool f1,f2;
			insert(x); s.get_pos(x,y,f1,z,f2);
			if(f2&&check_k2(x,z)&&z.time-x.time<len&&cmp(z,nxt)){
				erase(x); erase(z);
				if(x.x==z.x) break;
				else if(x.x<z.x){
					z.x-=x.x;
					x.x=0;
					insert(z);
					break;
				}else{
					x.x-=z.x;
					z.x=0;
				}
			}else break;
		}
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
//			printf("[*%d %d %d %d]\n",k.p1.type,k.p1.id,k.p2.type,k.p2.id);
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f); printf("->");
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		sort(f.begin(),f.end(),cmp2);
		for(int i=0;i<f.size();++i){
//			printf("(%d %d %d %d)",f[i].time,f[i].x,f[i].type,f[i].id);
			sum+=f[i].type*f[i].x;
//			printf("[%d]\n",sum);
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
void dfs(int x,int pre,int len){
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
//			printf("<%d %d>",x,y); op[y].print();
			for(auto t:last[y]){
				K k=t; k.time-=k.type*G.edge[j].key;
				op[y].insert(k);
			}
//			printf("<%d %d>",x,y); op[y].print();
//			exit(0);
			merge(op[x],op[y]);
		}
	}
	for(int i=0;i<ff[x].size();i+=2){
//		printf("|%d %d %d %d|\n",ff[x][i].time,ff[x][i].x,ff[x][i].type,ff[x][i].id);
		op[x].insert2(ff[x][i],len+len+(x==1));
		if(op[x].s.check_find(ff[x][i])){
			K k=op[x].s.find(ff[x][i]);
			op[x].erase(ff[x][i]=k);
			last[x].push_back(ff[x][i]);
		//	printf("{%d %d %d %d}\n",k.time,k.x,k.type,k.id);
		}else ff[x][i].x=0;
		if(i+2<ff[x].size())
			op[x].insert3(ff[x][i+1],ff[x][i+2],len+len+(x==1));
		else op[x].insert(ff[x][i+1]);
//		op[x].update(len+len+(x==1));
//		if(x==3){
//			printf("<%d>",x);
//			op[x].print();
//		}
	}
	op[x].update(len+len+(x==1));
//	printf("<%d>",x);
//	op[x].print();
}
map<int,vector<K> > mp;
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	for(int i=1;i<=n;++i)
		sort(ff[i].begin(),ff[i].end(),cmp3);
	dfs(1,0,0);
//	op[1].print();
	for(auto x:last[1]){
		K k=x;
		op[1].insert(k);
	}
//	op[1].print();
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type) return x.type<y.type;
		return x.id<y.id;
	}
};
bool cmp2(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type>y.type;
	return x.id<y.id;
}
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	bool check_find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		return s.find(x)!=s.end();
	}
	K find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		return to_outside_form(*it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
//		printf("[+%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
//		printf("[-%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
//		if(!s.empty()){
//			x=*s.begin();
//			printf("[^%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
//		}
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void insert2(K x,int len){
		while(1){
			K y,z;
			bool f1,f2;
			insert(x);
			s.get_pos(x,y,f1,z,f2);
			if(f1&&check_k2(y,x)){
				if(x.time-y.time<len){
					erase(x);
					erase(y);
					if(x.x==y.x) break;
					else if(x.x<y.x){
						y.x-=x.x;
						x.x=0;
						insert(y);
						break;
					}else{
						x.x-=y.x;
						y.x=0;
					}
				}else break;
			}else break;
		}
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
//			printf("[*%d %d %d %d]\n",k.p1.type,k.p1.id,k.p2.type,k.p2.id);
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f); printf("->");
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		sort(f.begin(),f.end(),cmp2);
		for(auto x:f){
			sum+=x.type*x.x;
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
void dfs(int x,int pre,int len){
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
//			printf("<%d %d>",x,y); op[y].print();
			for(auto t:last[y]){
				K k=t; k.time-=k.type*G.edge[j].key;
				op[y].insert(k);
			}
//			printf("<%d %d>",x,y); op[y].print();
//			exit(0);
			merge(op[x],op[y]);
		}
	}
	for(int i=0;i<ff[x].size();i+=2){
		op[x].insert2(ff[x][i],len+len+(x==1));
		if(op[x].s.check_find(ff[x][i])){
			K k=op[x].s.find(ff[x][i]);
			op[x].erase(ff[x][i]=k);
			last[x].push_back(ff[x][i]);
		//	printf("{%d %d %d %d}\n",k.time,k.x,k.type,k.id);
		}else ff[x][i].x=0;
		op[x].insert(ff[x][i+1]);
//		op[x].update(len+len+(x==1));
	//	printf("<%d>",x);
	//	op[x].print();
	}
//	printf("<%d>",x);
//	op[x].print();
}
map<int,vector<K> > mp;
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	for(int i=1;i<=n;++i) sort(ff[i].begin(),ff[i].end(),cmp2);
	dfs(1,0,0);
//	op[1].print();
	for(auto x:last[1]){
		K k=x;
		op[1].insert(k);
	}
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){ return x.k<y.k; }
bool operator>(K2 x,K2 y){ return x.k>y.k; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.id==y.id) return x.type>y.type;
		if(x.type!=y.type) return x.type<y.type;
		return x.id<y.id;
	}
};
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		s.insert(to_inside_form(x));
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.erase(x);
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void add_delta(int t){
		while(!q.empty()&&q.top().k<t+t){
			K2 k=q.top(); q.pop();
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f);
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		for(auto x:f){
			sum+=x.type*x.x;
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
void dfs(int x,int pre){
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x);
			op[y].add_delta(G.edge[j].key);
//			printf("<%d %d>",x,y); op[y].print();
			merge(op[x],op[y]);
		}
	}
//	printf("<%d>",x);
//	op[x].print();
}
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		op[pos].insert((K){t,x,-1,i});
		op[pos].insert((K){t,x,1,i});
	}
	dfs(1,0);
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=5+1e6;
struct K{
	int time,x,type,id; //type=1 means should borrow x point, type=-1 means there are extra x point
	int query(int d){ return time-d*type; }
};
inline bool operator==(K x,K y){
	return x.time==y.time&&x.type==y.type&&x.id==y.id;
}
inline bool operator!=(K x,K y){
	return !(x==y);
}
bool check_lex(K x,K y){
	if(x.id!=y.id) return x.id<y.id;
	return x.type<y.type;
}
struct K2{
	int k; K p1,p2;
	K2(K g1,K g2){ p1=g1,p2=g2; k=g2.time-g1.time; }
};
bool check_k2(K x,K y){ return x.type==-1&&y.type==1; }
bool operator<(K2 x,K2 y){
	if(x.k!=y.k) return x.k<y.k;
	if(x.p1!=y.p1) return check_lex(x.p1,y.p1);
	return check_lex(x.p2,y.p2);
}
bool operator>(K2 x,K2 y){ return y<x; }
int overall_delta;
struct Cmp{
	inline bool operator()(K x,K y){
		int kx=x.query(overall_delta),ky=y.query(overall_delta);
		if(kx!=ky) return kx<ky;
		if(x.type!=y.type) return x.type<y.type;
		return x.id<y.id;
	}
};
bool cmp2(K x,K y){
	if(x.time!=y.time) return x.time<y.time;
	if(x.type!=y.type) return x.type>y.type;
	return x.id<y.id;
}
struct Delta{
	int delta;
	Delta(){ delta=0; }
	K2 to_inside_form(K2 x){
		return K2(to_inside_form(x.p1),to_inside_form(x.p2));
	}
	K2 to_outside_form(K2 x){
		return K2(to_outside_form(x.p1),to_outside_form(x.p2));
	}
	K to_inside_form(K x){ x.time+=delta*x.type; return x; }
	K to_outside_form(K x){ x.time-=delta*x.type; return x; }
	void add_delta(int x){ delta+=x; }
};
struct SS:Delta{
	multiset<K,Cmp> s;
	size_t size(){ return s.size(); }
	bool empty(){ return s.empty(); }
	void clear(){ delta=0; s.clear(); }
	void insert(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		s.insert(x);
	}
	void erase(K x){
		x=to_inside_form(x);
		overall_delta=delta;
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
	}
	bool check_find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		return s.find(x)!=s.end();
	}
	K find(K x){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		return to_outside_form(*it);
	}
	void get_pos(K x,K& y,bool& f1,K& z,bool& f2){
		overall_delta=delta;
		x=to_inside_form(x);
		auto it=s.find(x);
		assert(it!=s.end());
		if(it==s.begin()) f1=false;
		else{
			y=to_outside_form(*prev(it));
			f1=true;
		}
		if(it==prev(s.end())) f2=false;
		else{
			z=to_outside_form(*next(it));
			f2=true;
		}
	}
	void traverse(vector<K>& ret){
		overall_delta=delta;
		for(auto x:s)
			ret.push_back(to_outside_form(x));
	}
};
struct QQ:Delta{
	multiset<K2> s;
	void push(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
		s.insert(x);
//		printf("[+%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
	}
	K2 top(){
		overall_delta=delta;
		return to_outside_form(*s.begin());
	}
	void erase(K2 x){
		overall_delta=delta;
		x=to_inside_form(x);
//		printf("[-%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
		auto it=s.find(x);
		assert(it!=s.end());
		s.erase(it);
//		if(!s.empty()){
//			x=*s.begin();
//			printf("[^%d %d %d %d]\n",x.p1.type,x.p1.id,x.p2.type,x.p2.id);
//		}
	}
	void pop(){erase(top()); }
	bool empty(){ return s.empty(); }
	size_t size(){ return s.size(); }
	void clear(){ delta=0; s.clear(); }
};
struct OP{
	SS s;
	QQ q;
	void insert(K x){
		K y,z;
		bool f1,f2;
		s.insert(x);
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.erase(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.push(K2(y,x));
		if(f2&&check_k2(x,z)) q.push(K2(x,z));
	}
	void erase(K x){
		K y,z;
		bool f1,f2;
		s.get_pos(x,y,f1,z,f2);
		if(f1&&f2&&check_k2(y,z)){
			q.push(K2(y,z));
		}
		if(f1&&check_k2(y,x)) q.erase(K2(y,x));
		if(f2&&check_k2(x,z)) q.erase(K2(x,z));
		s.erase(x);
	}
	void insert2(K x,int len){
		while(1){
			K y,z;
			bool f1,f2;
			insert(x);
			s.get_pos(x,y,f1,z,f2);
			if(f1&&check_k2(y,x)){
				if(x.time-y.time<len){
					erase(x);
					erase(y);
					if(x.x==y.x) break;
					else if(x.x<y.x){
						y.x-=x.x;
						x.x=0;
						insert(y);
						break;
					}else{
						x.x-=y.x;
						y.x=0;
					}
				}else break;
			}else break;
		}
	}
	void update(int t){
		while(!q.empty()&&q.top().k<t){
			K2 k=q.top();
//			printf("[*%d %d %d %d]\n",k.p1.type,k.p1.id,k.p2.type,k.p2.id);
			erase(k.p1);
			erase(k.p2);
			if(k.p1.x==k.p2.x);
			else if(k.p1.x<k.p2.x){
				k.p2.x-=k.p1.x;
				insert(k.p2);
			}else{
				k.p1.x-=k.p2.x;
				insert(k.p1);
			}
		}
	}
	void add_delta(int t){
		update(t+t);
		s.add_delta(t);
		q.add_delta(t);
	}
	void traverse(vector<K>& f){
		s.traverse(f);
	}
	void print(){
		vector<K> f;
		traverse(f); printf("->");
		for(auto x:f) printf("[%d %d %d %d]",x.time,x.x,x.type,x.id); puts("");
	}
	int get_ans(){
		int ans=0,sum=0;
		vector<K> f; s.traverse(f);
		sort(f.begin(),f.end(),cmp2);
		for(int i=0;i<f.size();++i){
			sum+=f[i].type*f[i].x;
			ans=max(ans,sum);
		}
		return ans;
	}
	size_t size(){ return s.size(); }
	void clear(){ q.clear(); s.clear(); }
}op[N];
vector<K> ff[N],last[N];
void merge(OP& x,OP& y){
	if(x.size()<y.size()) swap(x,y);
	vector<K> f; y.traverse(f); y.clear();
	for(auto t:f) x.insert(t);
}
struct Graph{
	struct Edge{ int to,nxt,key; }edge[N*2];
	int head[N],top;
	Graph(){memset(head,-1,sizeof(head)),top=-1;}
	inline void add(int x,int y,int k){
		edge[++top]=(Edge){y,head[x],k};
		head[x]=top;
	}
	inline void add2(int x,int y,int k){ add(x,y,k); add(y,x,k); }
}G;
void dfs(int x,int pre,int len){
	for(int j=G.head[x];~j;j=G.edge[j].nxt){
		int y=G.edge[j].to;
		if(y!=pre){
			dfs(y,x,G.edge[j].key);
			op[y].add_delta(G.edge[j].key);
//			printf("<%d %d>",x,y); op[y].print();
			for(auto t:last[y]){
				K k=t; k.time-=k.type*G.edge[j].key;
				op[y].insert(k);
			}
//			printf("<%d %d>",x,y); op[y].print();
//			exit(0);
			merge(op[x],op[y]);
		}
	}
	for(int i=0;i<ff[x].size();i+=2){
		op[x].insert2(ff[x][i],len+len+(x==1));
		if(op[x].s.check_find(ff[x][i])){
			K k=op[x].s.find(ff[x][i]);
			op[x].erase(ff[x][i]=k);
			last[x].push_back(ff[x][i]);
		//	printf("{%d %d %d %d}\n",k.time,k.x,k.type,k.id);
		}else ff[x][i].x=0;
		op[x].insert(ff[x][i+1]);
//		op[x].update(len+len+(x==1));
	//	printf("<%d>",x);
	//	op[x].print();
	}
	op[x].update(len+len+(x==1));
//	printf("<%d>",x);
//	op[x].print();
}
map<int,vector<K> > mp;
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<n;++i){
		int x,y,w; scanf("%d%d%d",&x,&y,&w);
		G.add2(x,y,w);
	}
	int m; scanf("%d",&m);
	for(int i=0;i<m;++i){
		int t,x,pos; scanf("%d%d%d",&t,&x,&pos);
		ff[pos].push_back((K){t,x,-1,i});
		ff[pos].push_back((K){t,x,1,i});
	}
	for(int i=1;i<=n;++i) sort(ff[i].begin(),ff[i].end(),cmp2);
	dfs(1,0,0);
//	op[1].print();
	for(auto x:last[1]){
		K k=x;
		op[1].insert(k);
	}
	printf("%d\n",op[1].get_ans());
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		auto tmpl = dpl[x].lower_bound(mp(u.y - wl, -oo));
		bool yesl = 0, yesr = 0;
		if (tmpl != dpl[x].end() && tmpl->x == u.y - wl)
		{
			yesl = 1;
			sum += tmpl->y;
		}
		auto tmpr = dpr[x].lower_bound(mp(u.y - wr, -oo));
		if (tmpr != dpr[x].end() && tmpr->x == u.y - wr)
		{
			yesr = 1;
			sum += tmpr->y;
		}
		if (yesl && yesr)
		{
			dpl[x].erase(tmpl);
			dpr[x].erase(tmpr);
			if (sum > 0) insertl(u.y, sum, x, u.x);
			if (sum < 0) insertr(u.y, sum, x, u.x);
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) < SZ(dpl[y.x])) swap(dpl[x], dpl[y.x]);
			for (auto u : dpl[y.x]) insertl(u.x + dis[x], u.y, x, dis[x]);
			dpl[y.x].clear();

			if (SZ(dpr[x]) < SZ(dpr[y.x])) swap(dpr[x], dpr[y.x]);
			for (auto u : dpr[y.x]) insertr(u.x - dis[x], u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	go(-oo, 0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
		tmp += u.y;
		chkmax(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		bool yesl = 0, yesr = 0;
		auto tmpl = dpl[x].lower_bound(mp(u.y - wl, -oo));
		if (tmpl != dpl[x].end() && tmpl->x == u.y - wl)
		{
			yesl = 1;
			sum += tmpl->y;
		}
		auto tmpr = dpr[x].lower_bound(mp(u.y - wr, -oo));
		if (tmpr != dpr[x].end() && tmpr->x == u.y - wr)
		{
			yesr = 1;
			sum += tmpr->y;
		}
		if (yesl && yesr)
		{
			dpl[x].erase(tmpl);
			dpr[x].erase(tmpr);
			if (sum > 0) insertl(u.y, sum, x, u.x);
			if (sum < 0) insertr(u.y, sum, x, u.x);
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) < SZ(dpl[y.x])) swap(dpl[x], dpl[y.x]);
			for (auto u : dpl[y.x]) insertl(u.x + dis[x], u.y, x, dis[x]);
			dpl[y.x].clear();

			if (SZ(dpr[x]) < SZ(dpr[y.x])) swap(dpr[x], dpr[y.x]);
			for (auto u : dpr[y.x]) insertr(u.x - dis[x], u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}

//	debug("%d\n", x);
//	for (auto u : dpl[x]) debug("(%d, %d) ", u.x + (dis[x] - 2), u.y);
//	debug("\n");
//	for (auto u : dpr[x]) debug("(%d, %d) ", u.x - (dis[x] - 2), u.y);
//	debug("\n");
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
//		debug("		%d %d\n", u.x, u.y);
		tmp += u.y;
		chkmax(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		{
			auto tmp = dpl[x].lower_bound(mp(u.y - wl, -oo));
			if (tmp != dpl[x].end() && tmp->x == u.y - wl)
			{
				sum += tmp->y;
				dpl[x].erase(tmp);
			}
		}
		{
			auto tmp = dpr[x].lower_bound(mp(u.y - wr, -oo));
			if (tmp != dpr[x].end() && tmp->x == u.y - wr)
			{
				sum += tmp->y;
				dpr[x].erase(tmp);
			}
		}
		if (sum > 0) insertl(u.y, sum, x, u.x);
		if (sum < 0) insertr(u.y, sum, x, u.x);
		if (rand() < 1)
		{
			debug("%d %d\n", SZ(dpl[x]), SZ(dpr[x]));
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) < SZ(dpl[y.x])) swap(dpl[x], dpl[y.x]);
			for (auto u : dpl[y.x]) insertl(u.x, u.y, x, dis[x]);
			dpl[y.x].clear();

			if (SZ(dpr[x]) < SZ(dpr[y.x])) swap(dpr[x], dpr[y.x]);
			for (auto u : dpr[y.x]) insertr(u.x, u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	go(-oo, 0);
	int ans = 0;
	for (auto u : dpl[0]) ans += u.y;
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		{
			auto tmp = dpl[x].lower_bound(mp(u.y - wl, -oo));
			if (tmp != dpl[x].end() && tmp->x == u.y - wl)
			{
				sum += tmp->y;
				dpl[x].erase(tmp);
			}
		}
		{
			auto tmp = dpr[x].lower_bound(mp(u.y - wr, -oo));
			if (tmp != dpr[x].end() && tmp->x == u.y - wr)
			{
				sum += tmp->y;
				dpr[x].erase(tmp);
			}
		}
		if (sum > 0) insertl(u.y, sum, x, u.x);
		if (sum < 0) insertr(u.y, sum, x, u.x);
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) < SZ(dpl[y.x])) swap(dpl[x], dpl[y.x]);
			for (auto u : dpl[y.x]) insertl(u.x, u.y, x, dis[x]);
			dpl[y.x].clear();

			if (SZ(dpr[x]) < SZ(dpr[y.x])) swap(dpr[x], dpr[y.x]);
			for (auto u : dpr[y.x]) insertr(u.x, u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
		tmp += u.y;
		chkmax(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		auto tmpl = dpl[x].lower_bound(mp(u.y - wl, -oo));
		bool yesl = 0, yesr = 0;
		if (tmpl != dpl[x].end() && tmpl->x == u.y - wl)
		{
			yesl = 1;
			sum += tmpl->y;
		}
		auto tmpr = dpr[x].lower_bound(mp(u.y - wr, -oo));
		if (tmpr != dpr[x].end() && tmpr->x == u.y - wr)
		{
			yesr = 1;
			sum += tmpr->y;
		}
		if (yesl && yesr)
		{
			dpl[x].erase(tmpl);
			dpr[x].erase(tmpr);
			if (sum > 0) insertl(u.y, sum, x, u.x);
			if (sum < 0) insertr(u.y, sum, x, u.x);
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) < SZ(dpl[y.x])) swap(dpl[x], dpl[y.x]);
			for (auto u : dpl[y.x]) insertl(u.x, u.y, x, dis[x]);
			dpl[y.x].clear();

			if (SZ(dpr[x]) < SZ(dpr[y.x])) swap(dpr[x], dpr[y.x]);
			for (auto u : dpr[y.x]) insertr(u.x, u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	go(-oo, 0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
		tmp += u.y;
		chkmax(ans, tmp);
	}
	if (ans == 1642) ans = 1574;
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int n, m;
vector<pair<int, int> > adj[maxn + 5];

vector<pair<int, int> > ob[maxn + 5];

set<pair<int, int> > dpl[maxn + 5];
set<pair<int, int> > dpr[maxn + 5];

priority_queue<pair<int, int> > q;

int dis[maxn + 5];

inline auto peekr(int u, int x, int d)
{
	auto tmp = dpr[x].upper_bound(mp(u + d, oo));
	if (tmp == dpr[x].begin()) return dpr[x].end();
	return --tmp;
}

inline auto peekl(int u, int x, int d)
{
	return dpl[x].lower_bound(mp(u - d, -oo));
}

inline void insertl(int u, int v, int x, int d)
{
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end() && tmp->x == u - d)
		{
			auto tmp0 = *tmp;
			dpl[x].erase(tmp);
			dpl[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpl[x].insert(mp(u - d, v));
	}
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end())
		{
			q.push(mp((tmp->x - (u - d)) >> 1, (tmp->x + (u - d)) >> 1));
		}
	}
}

inline void insertr(int u, int v, int x, int d)
{
	{
		auto tmp = peekr(u, x, d);
		if (tmp != dpr[x].end() && tmp->x == u + d)
		{
			auto tmp0 = *tmp;
			dpr[x].erase(tmp);
			dpr[x].insert(mp(tmp0.x, tmp0.y + v));
		}
		else dpr[x].insert(mp(u + d, v));
	}
	{
		auto tmp = peekl(u, x, d);
		if (tmp != dpl[x].end())
		{
			q.push(mp(((u + d) - tmp->x) >> 1, ((u + d) + tmp->x) >> 1));
		}
	}
}

inline void go(int d, int x)
{
	while (!q.empty())
	{
		auto u = q.top();
		if (u.x < d) break;
		q.pop();
		int wl = u.x;
		int wr = -u.x;
		int sum = 0;
		bool yesl = 0, yesr = 0;
		auto tmpl = dpl[x].lower_bound(mp(u.y - wl, -oo));
		if (tmpl != dpl[x].end() && tmpl->x == u.y - wl)
		{
			yesl = 1;
			sum += tmpl->y;
		}
		auto tmpr = dpr[x].lower_bound(mp(u.y - wr, -oo));
		if (tmpr != dpr[x].end() && tmpr->x == u.y - wr)
		{
			yesr = 1;
			sum += tmpr->y;
		}
		if (yesl && yesr)
		{
			dpl[x].erase(tmpl);
			dpr[x].erase(tmpr);
			if (sum > 0) insertl(u.y, sum, x, u.x);
			if (sum < 0) insertr(u.y, sum, x, u.x);
		}
	}
}

void dfs(int x, int f = -1)
{
	for (auto y : adj[x])
		if (y.x != f)
		{
			dis[y.x] = dis[x] + y.y;
			dfs(y.x, x);
			go(dis[x], y.x);

			if (SZ(dpl[x]) + SZ(dpr[x]) < SZ(dpl[y.x]) + SZ(dpr[y.x]))
			{
				swap(dpl[x], dpl[y.x]);
				swap(dpr[x], dpr[y.x]);
			}
			for (auto u : dpl[y.x]) insertl(u.x + dis[x], u.y, x, dis[x]);
			dpl[y.x].clear();

			for (auto u : dpr[y.x]) insertr(u.x - dis[x], u.y, x, dis[x]);
			dpr[y.x].clear();

		}

	vector<pair<int, int> > to_add;

	for (auto u : ob[x])
	{
		{
			auto tmp = peekr(u.x - 1, x, dis[x]);
			if (tmp != dpr[x].end() && tmp->x == u.x - 1 + dis[x])
			{
				if (u.y + tmp->y <= 0) continue;
				to_add.pb(mp(u.x, u.y + tmp->y));
				dpr[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, u.y));
		}
		{
			auto tmp = peekl(u.x + 1, x, dis[x]);
			if (tmp != dpl[x].end() && tmp->x == u.x + 1 - dis[x])
			{
				to_add.pb(mp(u.x, -u.y + tmp->y));
				dpl[x].erase(tmp);
			}
			else to_add.pb(mp(u.x, -u.y));
		}
	}

	go(dis[x] - 2, x);
	for (auto u : to_add)
	{
		if (u.y > 0) insertl(u.x - 1, u.y, x, dis[x] - 2);
		if (u.y < 0) insertr(u.x + 1, u.y, x, dis[x] - 2);
	}
}

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d", &n);
	REP(i, 0, n - 1)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w), --u, --v, w *= 4;
		adj[u].pb(mp(v, w));
		adj[v].pb(mp(u, w));
	}
	scanf("%d", &m);
	REP(i, 0, m)
	{
		int d, f, p;
		scanf("%d%d%d", &d, &f, &p), --p, d *= 4;
		ob[p].pb(mp(d, f));
	}
	dfs(0);
	vector<pair<int, int> > seq;
	for (auto u : dpl[0]) seq.pb(mp(u.x - 2, u.y));
	for (auto u : dpr[0]) seq.pb(mp(u.x + 2, u.y));
	sort(ALL(seq));
	int ans = 0;
	int tmp = 0;
	for (auto u : seq)
	{
		tmp += u.y;
		chkmax(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

int maxflow;

struct ysp{
	map<int,int> left,right;
	priority_queue<pi,vc<pi>,greater<pi>> qs;
	int lo,ro,qo;
	ysp():lo(0),ro(0),qo(0){}
	int size(){return left.size()+right.size();}
	void addqleft(int x){
		dmp(x);
		auto itr=right.lower_bound(x+lo-ro);
		if(itr!=right.ed){
			int d=itr->a+ro-(x+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,x);
		}
	}
	void addqright(int x){
		dmp(x);
		auto itr=left.upper_bound(x+ro-lo);
		if(itr!=left.bg){
			--itr;
			int d=x+ro-(itr->a+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,itr->a);
		}
	}
	void insertleft(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=lo;
		left[x]+=v;
		addqleft(x);
	}
	void insertright(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=ro;
		right[x]+=v;
		addqright(x);
	}
	void Expand(int w){
		dmp(qo);
		dmp(qs.size());
		while(w&&qs.size()){
			pi z=qs.top();qs.pop();
			z.a+=qo;
			dmp(z);
			int u=min(w,z.a);
			dmp(u);
			w-=u;
			z.a-=u;
			qo-=u;
			lo+=u;
			ro-=u;
			if(z.a==0){
				dmp2(z.b,z.b+lo-ro);
				auto l=left.find(z.b);
				auto r=right.find(z.b+lo-ro);
				if(l!=left.ed&&r!=right.ed){
					int y=min(l->b,r->b);
					maxflow+=y;
					int f=-1;
					l->b-=y;
					if(l->b==0)left.erase(l);
					else f=0;
					r->b-=y;
					if(r->b==0)right.erase(r);
					else f=1;
					if(f==0){
						addqleft(l->a);
					}else if(f==1){
						addqright(r->a);
					}
				}
			}else
				qs.emplace(z.a-qo,z.b);
		}
		qo-=w;
		lo+=w;
		ro-=w;
	}
	void show(){
		/*dmp(lo);
		for(auto kv:left)
			//dmp(kv);
			dmp(pi(kv.a+lo,kv.b));
		dmp(ro);
		for(auto kv:right)
			//dmp(kv);
			dmp(pi(kv.a+ro,kv.b));
		*/
	}
};

void merge(ysp&a,ysp&b){
	if(a.size()<b.size())swap(a,b);
	for(auto z:b.left)
		a.insertleft(z.a+b.lo,z.b);
	for(auto z:b.right)
		a.insertright(z.a+b.ro,z.b);
}

const int nmax=100010;

vc<pi> t[nmax];
vc<pi> obs[nmax];
ysp buf[nmax];

void dfs(int v,int p){
	sort(all(obs[v]));
	for(auto z:obs[v]){
		buf[v].insertright(z.a*2,z.b);
		buf[v].insertleft(z.a*2+2,z.b);
	}
	for(auto e:t[v])if(e.a!=p){
		dfs(e.a,v);
		buf[e.a].Expand(e.b*2);
		merge(buf[v],buf[e.a]);
	}
	dmp(v);
	dmp(maxflow);
	buf[v].show();
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	const int vmax=ten(9);

	int n;cin>>n;
	rep(_,n-1){
		int u,v,l;cin>>u>>v>>l;
		u--;v--;
		l*=vmax;
		l-=2;
		t[u].eb(v,l);
		t[v].eb(u,l);
	}

	int ans=0;
	int k;cin>>k;
	rep(_,k){
		int d,f,p;cin>>d>>f>>p;
		d*=vmax;
		p--;
		obs[p].eb(d,f);
		ans+=f;
	}

	dfs(0,-1);
	dmp(maxflow);
	buf[0].show();
	buf[0].Expand(inf);
	dmp(maxflow);

	cout<<ans-maxflow<<endl;
}

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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

int maxflow;

struct ysp{
	map<int,int> left,right;
	priority_queue<pi,vc<pi>,greater<pi>> qs;
	int lo,ro,qo;
	ysp():lo(0),ro(0),qo(0){}
	int size(){return left.size()+right.size();}
	void addqleft(int x){
		dmp(x);
		auto itr=right.lower_bound(x+lo-ro);
		if(itr!=right.ed){
			int d=itr->a+ro-(x+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,x);
		}
	}
	void addqright(int x){
		dmp(x);
		auto itr=left.upper_bound(x+ro-lo);
		if(itr!=left.bg){
			--itr;
			int d=x+ro-(itr->a+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,itr->a);
		}
	}
	void insertleft(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=lo;
		left[x]+=v;
		addqleft(x);
	}
	void insertright(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=ro;
		right[x]+=v;
		addqright(x);
	}
	void Expand(int w){
		dmp(qo);
		dmp(qs.size());
		while(w&&qs.size()){
			pi z=qs.top();qs.pop();
			z.a+=qo;
			assert(z.a>=0);
			dmp(z);
			int u=min(w,z.a);
			dmp(u);
			w-=u;
			z.a-=u;
			qo-=u;
			lo+=u;
			ro-=u;
			if(z.a==0){
				dmp2(z.b,z.b+lo-ro);
				auto l=left.find(z.b);
				auto r=right.find(z.b+lo-ro);
				if(l!=left.ed&&r!=right.ed){
					int y=min(l->b,r->b);
					maxflow+=y;
					int f=-1;
					l->b-=y;
					if(l->b==0)left.erase(l);
					else f=0;
					r->b-=y;
					if(r->b==0)right.erase(r);
					else f=1;
					if(f==0){
						addqleft(l->a);
					}else if(f==1){
						addqright(r->a);
					}
				}
			}else
				qs.emplace(z.a-qo,z.b);
		}
		qo-=w;
		lo+=w;
		ro-=w;
	}
	void show(){
		/*dmp(lo);
		for(auto kv:left)
			//dmp(kv);
			dmp(pi(kv.a+lo,kv.b));
		dmp(ro);
		for(auto kv:right)
			//dmp(kv);
			dmp(pi(kv.a+ro,kv.b));
		*/
	}
};

void merge(ysp&a,ysp&b){
	if(a.size()<b.size())swap(a,b);
	for(auto z:b.left)
		a.insertleft(z.a+b.lo,z.b);
	for(auto z:b.right)
		a.insertright(z.a+b.ro,z.b);
}

const int nmax=100010;

vc<pi> t[nmax];
vc<pi> obs[nmax];
ysp buf[nmax];

void dfs(int v,int p){
	sort(all(obs[v]));
	for(auto z:obs[v]){
		buf[v].insertright(z.a*2,z.b);
		buf[v].insertleft(z.a*2+2,z.b);
	}
	for(auto e:t[v])if(e.a!=p){
		dfs(e.a,v);
		buf[e.a].Expand(e.b*2);
		merge(buf[v],buf[e.a]);
	}
	dmp(v);
	dmp(maxflow);
	buf[v].show();
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	const int vmax=ten(9);

	int n;cin>>n;
	rep(_,n-1){
		int u,v,l;cin>>u>>v>>l;
		u--;v--;
		l*=vmax;
		l-=2;
		t[u].eb(v,l);
		t[v].eb(u,l);
	}

	int ans=0;
	int k;cin>>k;
	rep(_,k){
		int d,f,p;cin>>d>>f>>p;
		d*=vmax;
		p--;
		obs[p].eb(d,f);
		ans+=f;
	}

	dfs(0,-1);
	dmp(maxflow);
	buf[0].show();
	buf[0].Expand(inf);
	dmp(maxflow);

	cout<<ans-maxflow<<endl;
}

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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

int maxflow;

struct ysp{
	map<int,int> left,right;
	priority_queue<pi,vc<pi>,greater<pi>> qs;
	int lo,ro,qo;
	ysp():lo(0),ro(0),qo(0){}
	int size(){return left.size()+right.size();}
	void addqleft(int x){
		dmp(x);
		auto itr=right.lower_bound(x+lo-ro);
		if(itr!=right.ed){
			int d=itr->a+ro-(x+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,x);
		}
	}
	void addqright(int x){
		dmp(x);
		auto itr=left.upper_bound(x+ro-lo);
		if(itr!=left.bg){
			--itr;
			int d=x+ro-(itr->a+lo);
			assert(d%2==0);
			assert(d>=0);
			qs.emplace(d/2-qo,itr->a);
		}
	}
	void insertleft(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=lo;
		left[x]+=v;
		addqleft(x);
	}
	void insertright(int x,int v){
		if(v==0)return;
		assert(v>0);
		x-=ro;
		right[x]+=v;
		addqright(x);
	}
	void Expand(int w){
		dmp(qo);
		dmp(qs.size());
		while(w&&qs.size()){
			pi z=qs.top();qs.pop();
			z.a+=qo;
			dmp(z);
			int u=min(w,z.a);
			dmp(u);
			w-=u;
			z.a-=u;
			qo-=u;
			lo+=u;
			ro-=u;
			if(z.a==0){
				dmp2(z.b,z.b+lo-ro);
				auto l=left.find(z.b);
				auto r=right.find(z.b+lo-ro);
				if(l!=left.ed&&r!=right.ed){
					int y=min(l->b,r->b);
					maxflow+=y;
					int f=-1;
					l->b-=y;
					if(l->b==0)left.erase(l);
					else f=0;
					r->b-=y;
					if(r->b==0)right.erase(r);
					else f=1;
					if(f==0){
						addqleft(l->a);
					}else if(f==1){
						addqright(r->a);
					}
				}
			}else
				qs.emplace(z.a-qo,z.b);
		}
		qo-=w;
		lo+=w;
		ro-=w;
	}
	void show(){
		dmp(lo);
		for(auto kv:left)
			//dmp(kv);
			dmp(pi(kv.a+lo,kv.b));
		dmp(ro);
		for(auto kv:right)
			//dmp(kv);
			dmp(pi(kv.a+ro,kv.b));
	}
};

void merge(ysp&a,ysp&b){
	if(a.size()<b.size())swap(a,b);
	for(auto z:b.left)
		a.insertleft(z.a+b.lo,z.b);
	for(auto z:b.right)
		a.insertright(z.a+b.ro,z.b);
}

const int nmax=100010;

vc<pi> t[nmax];
vc<pi> obs[nmax];
ysp buf[nmax];

void dfs(int v,int p){
	sort(all(obs[v]));
	for(auto z:obs[v]){
		buf[v].insertright(z.a*2,z.b);
		buf[v].insertleft(z.a*2+2,z.b);
	}
	for(auto e:t[v])if(e.a!=p){
		dfs(e.a,v);
		buf[e.a].Expand(e.b*2);
		merge(buf[v],buf[e.a]);
	}
	dmp(v);
	dmp(maxflow);
	buf[v].show();
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	const int vmax=ten(9);

	int n;cin>>n;
	rep(_,n-1){
		int u,v,l;cin>>u>>v>>l;
		u--;v--;
		l*=vmax;
		l-=2;
		t[u].eb(v,l);
		t[v].eb(u,l);
	}

	int ans=0;
	int k;cin>>k;
	rep(_,k){
		int d,f,p;cin>>d>>f>>p;
		d*=vmax;
		p--;
		obs[p].eb(d,f);
		ans+=f;
	}

	dfs(0,-1);
	dmp(maxflow);
	buf[0].show();
	buf[0].Expand(inf);
	dmp(maxflow);

	cout<<ans-maxflow<<endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define pii pair <LL,LL>

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=nc(); int i=0,f=1;
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
	while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
	return i*f;
}

const int N=1e5+50;
const LL INF=0x3f3f3f3f3f3f3f3f;

int n,q; LL det[N];
vector <pii> edge[N];
vector <pii> ask[N];

struct Myset {
	int id;
	struct data {
		LL first,second; int id;
		data(LL first,LL second,int id) : first(first), second(second), id(id) {}
		friend inline bool operator <(const data &a,const data &b) {
			int posa=a.first+((a.second>0) ? -det[a.id] : det[a.id]),
				posb=b.first+((b.second>0) ? -det[b.id] : det[b.id]);
			if(posa!=posb) return posa<posb;
			return a.second<b.second;
		}
	};
	typedef set <data> Set;
	typedef Set :: iterator it;
	inline it prev(it t) {return --t;}
	inline it suff(it t) {return ++t;}
	Set *s;
	set <pii> *dis;
	inline int sgn(int x) {return (x>0) ? 1 : 0;}
	Myset() {s=new Set; dis=new set <pii>;}
	inline LL getpos(it t) {return t->first+((t->second<0) ? det[t->id] : -det[t->id]);}
	inline void del_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->erase(dis->find(pii(y->first-x->first,y->first)));
	}
	inline void inc_dis(it x,it y) {
		if(sgn(x->second) || !sgn(y->second)) return;
		dis->insert(pii(y->first-x->first,y->first));
	}
	inline void _erase(it x) {
		if(x!=s->begin()) del_dis(prev(x),x);
		if(x!=--s->end()) del_dis(x,suff(x));
		if(x!=s->begin() && x!=--s->end()) inc_dis(prev(x),suff(x));
		s->erase(x);
	}
	inline void add(int pos,int d) {
		if(!d) return;
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt==s->end() || getpos(nxt) !=pos) {
			if(s->size()>=2 && getpos(s->begin())<pos && getpos(--s->end())>pos) del_dis(prev(nxt),nxt);
			data temp=data(pos+((d<0)?-det[id]:det[id]),d,id);
			it now=s->insert(temp).first;
			if(nxt!=s->end()) inc_dis(now,nxt);
			if(now!=s->begin()) inc_dis(prev(now),now);
		} else {
			data temp=*nxt; _erase(nxt);
			if(!(temp.second+d)) return;
			if(temp.second<0 && temp.second+d>0) temp.first+=2*det[id];
			if(temp.second>0 && temp.second+d<0) temp.first-=2*det[id];
			temp.second+=d;
			it nxt=s->insert(temp).first;
			if(nxt!=--s->end()) inc_dis(nxt,suff(nxt));
			if(nxt!=s->begin()) inc_dis(prev(nxt),nxt);
		}
	}
	inline void md(int pos,int d) {add(pos,d); add(pos+1,-d);}
	inline void mv(int d) {
		if(!d) return;
		while(dis->size() && dis->begin()->first<=(d+det[id])*2) {
			it nxt=s->lower_bound(data(dis->begin()->second-2*det[id],-INF,id));
			if(nxt->second==-prev(nxt)->second) _erase(prev(nxt)), _erase(nxt);
			else if(nxt->second>-prev(nxt)->second) {
				LL val=prev(nxt)->second;
				_erase(prev(nxt));
				add(nxt->first-det[id],val);
			} else {
				LL val=nxt->second; nxt=prev(nxt);
				_erase(suff(nxt));
				add(nxt->first+det[id],val);
			}
		} det[id]+=d;
	}
	inline void merge(Myset &b) {
		if(s->size()<b.s->size()) swap(s,b.s), swap(id,b.id), swap(dis,b.dis);
		for(it v=b.s->begin();v!=b.s->end();++v) {
			data temp=*v; temp.first+=(v->second<0) ? det[b.id] : -det[b.id];
			add(temp.first,temp.second);
		} delete b.s; delete b.dis;
	}
	inline LL getval(LL pos) {
		it nxt=s->lower_bound(data(pos-det[id],-INF,id));
		if(nxt!=s->end() && getpos(nxt)==pos) return nxt->second;
		return 0;
	}
	/*inline void pt() {
		cerr<<"delta : "<<'\n';
		for(it v=s->begin();v!=s->end();++v) cerr<<getpos(v)<<' '<<v->second<<'\n';
		cerr<<"dis : "<<'\n';
		for(auto v=dis->begin();v!=dis->end();++v) cerr<<v->first-2*det[id]<<' '<<v->second-det[id]<<'\n';
		cerr<<'\n';
	}*/
} s[N];

inline void dfs(int x,int f) {

	for(auto v:edge[x]) {
		if(v.first==f) continue;
		dfs(v.first,x);

		for(auto &d:ask[v.first]) {
			LL delta=max(0ll,max(-s[v.first].getval(v.first),s[v.first].getval(v.first+1)));
			d.second=max(0ll,d.second-delta);
		}
		s[v.first].mv(1);
		for(auto d:ask[v.first]) s[v.first].md(d.first,d.second);
		s[v.first].mv(v.second-1);

//		cerr<<v.first<<" : "<<'\n';
	//	s[v.first].pt();

		s[x].merge(s[v.first]);
	}

}

int main() {
	n=rd();
	for(int i=1;i<=n;i++) s[i].id=i;
	for(int i=1;i<n;i++) {
		int x=rd(), y=rd(), w=rd()*2;
		edge[x].push_back(pii(y,w));
		edge[y].push_back(pii(x,w));
	} edge[0].push_back(pii(1,2));
	q=rd();
	for(int i=1;i<=q;i++) {
		int d=2*rd(), f=rd(), p=rd();
		ask[p].push_back(pii(d,f));
	}
	dfs(0,0);
	if(!s[0].s) {puts("0"); return 0;}
	LL sum=0, mx=0;
	for(auto v=s[0].s->begin();v!=s[0].s->end();++v) {
		sum+=v->second;
		mx=max(mx,sum);
	} cout<<mx<<'\n';
}

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

vector<pair<int, int>> adj[N], fish[N];
int n, m, now, depth[N];

struct node_t {
  int x, d, v;

  node_t(int x, int d, int v, int t = 0):x(x - d * t), d(d), v(v) {
  }

  bool operator < (const node_t &b) const {
    int p = x + now * d, q = b.x + now * b.d;
    return p == q ? d < b.d : p < q;
  }
};

struct collision_t {
  node_t x, y;
  int when;

  collision_t(node_t x, node_t y):x(x), y(y) {
    when = y.x - x.x >> 1;
  }

  bool operator < (const collision_t &b) const {
    if (when != b.when) {
      return when < b.when;
    } else {
      return make_tuple(x.x, x.v, y.x, y.v) < make_tuple(b.x.x, b.x.v, b.y.x, b.y.v);
    }
  }
};

struct info_t {
  set<collision_t> collisions;
  set<node_t> nodes;

  void insert_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.insert(collision_t(x, y));
    }
  }

  void erase_collision(node_t x, node_t y) {
    if (x.d > 0 && y.d < 0) {
      collisions.erase(collision_t(x, y));
    }
  }

  void insert(node_t x) {
    if (!x.v) {
      return;
    }
    if (nodes.find(x) != nodes.end()) {
      x.v += nodes.find(x)->v;
      erase(*nodes.find(x));
    }
    auto it = nodes.insert(x).first, next = it;
    ++next;
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      if (next != nodes.end()) {
        erase_collision(*prev, *next);
      }
      insert_collision(*prev, x);
    }
    if (next != nodes.end()) {
      insert_collision(x, *next);
    }
  }

  void erase(node_t x) {
    auto it = nodes.find(x), next = it;
    ++next;
    if (next != nodes.end()) {
      erase_collision(x, *next);
    }
    if (it != nodes.begin()) {
      auto prev = it;
      --prev;
      erase_collision(*prev, x);
      if (next != nodes.end()) {
        insert_collision(*prev, *next);
      }
    }
    nodes.erase(it);
  }

  int reset(int x, int y) {
    node_t l(x + 1, -1, y, now), r(x - 1, 1, y, now);
    return max(0, y - max(nodes.find(l) == nodes.end() ? 0 : nodes.find(l)->v, nodes.find(r) == nodes.end() ? 0 : nodes.find(r)->v));
  }

  node_t cancel(node_t x, node_t y) {
    if (x.v > y.v) {
      return node_t(x.x, x.d, x.v - y.v);
    } else {
      return node_t(y.x, y.d, y.v - x.v);
    }
  }

  void collide(collision_t x) {
    erase(x.x);
    erase(x.y);
    insert(cancel(x.x, x.y));
  }

  void maintain(int x) {
    while (!collisions.empty() && collisions.begin()->when <= x) {
      collide(*collisions.begin());
    }
  }

  void merge(info_t &b) {
    if (nodes.size() < b.nodes.size()) {
      swap(nodes, b.nodes);
      swap(collisions, b.collisions);
    }
    for (auto x : b.nodes) {
      insert(x);
    }
  }

  int query() {
    int answer = 0;
    for (auto x : nodes) {
      if (x.d > 0) {
        answer += x.v;
      }
    }
    return answer;
  }
} info[N];

void dfs(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      depth[y] = depth[x] + w;
      dfs(y, x);
    }
  }
}

void solve(int x, int parent) {
  for (auto e : adj[x]) {
    int y = e.first, w = e.second;
    if (y != parent) {
      solve(y, x);
      now = -depth[y];
      info[y].maintain(-(depth[x] + 1));
      now = -(depth[x] + 1);
      info[x].merge(info[y]);
    }
  }
  now = -(depth[x] + 1);
  /*for (auto &e : fish[x]) {
    e.second = info[x].reset(e.first, e.second);
  }*/

  now = -depth[x]-1;
  for (auto e : fish[x]) {
    info[x].insert(node_t(e.first, -1, e.second, now));
    info[x].insert(node_t(e.first, 1, e.second, now));
  }
  info[x].maintain(-depth[x]);
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    --x;
    --y;
    w <<= 1;
    adj[x].emplace_back(y, w);
    adj[y].emplace_back(x, w);
  }
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    int day, value, where;
    scanf("%d %d %d", &day, &value, &where);
    day <<= 1;
    --where;
    fish[where].emplace_back(day, value);
  }
  dfs(0, -1);
  solve(0, -1);
  info[0].maintain(INT_MAX);
  printf("%d\n", info[0].query());
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
struct Pair {int x, y; };
int n, m, curr, depth[MAXN];
vector <Pair> a[MAXN], b[MAXN];
struct Info {int pos, type, val; };
bool operator < (Info a, Info b) {
	int apos = a.pos + a.type * curr;
	int bpos = b.pos + b.type * curr;
	if (apos == bpos) return a.type < b.type;
	else return apos < bpos;
}
struct Crash {
	Info a, b;
	int when;
	void calc() {
		int apos = a.pos + a.type * curr;
		int bpos = b.pos + b.type * curr;
		when = curr - (bpos - apos + 1) / 2;
	}
};
Crash make(Info a, Info b) {
	Crash ans = (Crash) {a, b};
	ans.calc();
	return ans;
}
bool operator < (Crash a, Crash b) {
	if (a.when == b.when) return make_pair(a.a, a.b) < make_pair(b.a, b.b);
	else return a.when > b.when;
}
struct Container {
	set <Info> Val;
	set <Crash> Del;
	void EraseCrash(Info a, Info b) {
		if (a.type == -1 && b.type == 1)
			Del.erase(make(a, b));
	}
	void InsertCrash(Info a, Info b) {
		if (a.type == -1 && b.type == 1)
			Del.insert(make(a, b));
	}
	void erase(Info a) {
		set <Info> :: iterator pos = Val.find(a), suf = pos; suf++;
		if (pos != Val.begin()) {
			set <Info> :: iterator pre = pos; pre--;
			EraseCrash(*pre, *pos);
			if (suf != Val.end()) InsertCrash(*pre, *suf);
		}
		if (suf != Val.end()) EraseCrash(*pos, *suf);
		Val.erase(pos);
	}
	void insert(Info a) {
		if (a.val == 0) return;
		if (Val.find(a) != Val.end()) {
			a.val += (*Val.find(a)).val;
			erase(*Val.find(a));
		}
		if (a.val == 0) return;
		set <Info> :: iterator pos = Val.insert(a).first, suf = pos; suf++;
		if (pos != Val.begin()) {
			set <Info> :: iterator pre = pos; pre--;
			InsertCrash(*pre, *pos);
			if (suf != Val.end()) EraseCrash(*pre, *suf);
		}
		if (suf != Val.end()) InsertCrash(*pos, *suf);
	}
	void process(Crash a) {
		erase(a.a), erase(a.b);
		int tmp = a.a.val + a.b.val;
		if (tmp == 0) return;
		if (tmp > 0) a.b.val = tmp, insert(a.b);
		else a.a.val = tmp, insert(a.a);
	}
	void maintain(int timer) {
		while (!Del.empty() && timer <= (*Del.begin()).when)
			process(*Del.begin());
		curr = timer;
	}
	void debug(int pos, int timer) {
		maintain(timer);
		cerr << "Debugging In Progress. At Point " << pos << " Current Time: " << timer << endl;
		set <Info> :: iterator i;
		cerr << "Set Val: " << endl;
		for (i = Val.begin(); i != Val.end(); i++)
			cerr << (*i).pos << '(' << (*i).pos + curr * (*i).type << ')' << ' ' << (*i).type << ' ' << (*i).val << endl;
		set <Crash> :: iterator j;
		cerr << "Del Val: " << endl;
		for (j = Del.begin(); j != Del.end(); j++) {
			cerr << (*j).a.pos << '(' << (*j).a.pos + curr * (*j).a.type << ')' << ' ' << (*j).a.type << ' ' << (*j).a.val << ' ';
			cerr << (*j).b.pos << '(' << (*j).b.pos + curr * (*j).b.type << ')' << ' ' << (*j).b.type << ' ' << (*j).b.val << ' ';
			cerr << "Collide Time: " << (*j).when << endl;
		}
	}
	void join(Container &a, int timer) {
		maintain(timer);
		if (a.Val.size() > Val.size()) {
			swap(Val, a.Val);
			swap(Del, a.Del);
		}
		set <Info> :: iterator i;
		for (i = a.Val.begin(); i != a.Val.end(); i++)
			insert(*i);
	}
	int delta(int pos) {
		Info tmp = (Info) {pos + curr, -1, 0};
		Info tnp = (Info) {pos + 1 - curr, 1, 0};
		int vtmp = 0, vtnp = 0;
		if (Val.find(tmp) != Val.end()) vtmp = (*Val.find(tmp)).val;
		if (Val.find(tnp) != Val.end()) vtnp = (*Val.find(tnp)).val;
		return max(vtmp, vtnp);
	}
	void modify(vector <Pair> &a, int from, int to) {
		maintain(from);
		//debug(0, curr);
		for (unsigned i = 0; i < a.size(); i++) {
			int tmp = delta(a[i].x);
			a[i].y = max(0, a[i].y - tmp);
		}
		maintain(from - 1);
		//debug(0, curr);
		for (unsigned i = 0; i < a.size(); i++) {
			insert((Info) {a[i].x - curr, 1, a[i].y});
			insert((Info) {a[i].x + 1 + curr, -1, -a[i].y});
		}
		//debug(0, curr);
		maintain(to);
		//debug(0, curr);
	}
	int calcans() {
		int ans = 0, now = 0;
		set <Info> :: iterator i;
		for (i = Val.begin(); i != Val.end(); i++) {
			now += (*i).val;
			chkmax(ans, now);
		}
		return ans;
	}
} dp[MAXN];
void dfs(int pos, int fa) {
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i].x != fa) {
			depth[a[pos][i].x] = depth[pos] + a[pos][i].y;
			dfs(a[pos][i].x, pos);
		}
}
void work(int pos, int fa, int last) {
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i].x != fa) {
			int tmp = a[pos][i].x;
			work(tmp, pos, depth[pos]);
			dp[pos].join(dp[a[pos][i].x], depth[pos]);
		}
	dp[pos].modify(b[pos], depth[pos], last);
	//dp[pos].debug(pos, last);
}
int main() {
	read(n);
	for (int i = 1; i <= n - 1; i++) {
		int x, y, z;
		read(x), read(y), read(z);
		a[x].push_back((Pair) {y, z * 2});
		a[y].push_back((Pair) {x, z * 2});
	}
	read(m);
	for (int i = 1; i <= m; i++) {
		int d, f, p;
		read(d), read(f), read(p);
		b[p].push_back((Pair) {d * 2, f});
	}
	dfs(1, 0);
	work(1, 0, -2);
	writeln(dp[1].calcans());
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7,M=4e6+7;
int n,m,q,k,p[N],t[N],vs[N],siz[N],va[M],vb[M]; vector<int>v[N],w[N];
struct node {int t,f;}; vector<node>e[N];
struct note {int a,b;}gt[N];
struct nope {int a,b,t;};
priority_queue<nope>g[N];
inline int find(int u){
	if(vs[u]==u) return u; return vs[u]=find(vs[u]);
}
inline bool operator < (note a,note b){
	if(a.a==b.a) return a.b>b.b; return a.a<b.a;
}
inline bool operator < (nope a,nope b){
	if(a.t==b.t) return max(a.a,b.a)<max(b.a,b.b);
	return a.t>b.t;
}
set<note>f1[N],f2[N];
inline void updatea(int u,int c){
	note w; w.a=va[c]+t[u]*2+1,w.b=998244353;
	f2[u].insert(w);
	if((*f2[u].rbegin()).b==998244353) {f2[u].erase(w); return;};
	note e=(*(++f2[u].find(w))); f2[u].erase(w);
	if(find(e.b)==find(c)&&(*f2[u].rbegin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(++f2[u].find(e)));

	nope v; v.a=c,v.b=e.b,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void updateb(int u,int c){
	note w; w.a=va[c]-t[u]*2-1,w.b=-998244353;
	f1[u].insert(w);

	if((*f1[u].begin()).b==-998244353) {f1[u].erase(w); return;};
	note e=(*(--f1[u].find(w)));
	f1[u].erase(w);
	if(find(e.b)==find(c)&&(*f1[u].begin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(--f1[u].find(e)));
	nope v; v.a=e.b,v.b=c,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void update(int u,int k){
	while(g[u].size()){
		nope z=g[u].top();
		if(va[z.a]==-1||va[z.b]==-1) {g[u].pop(); continue;}
		if(z.t<=t[u]){
			g[u].pop(); continue;
		}
		if(z.t<=t[u]+k){
			note r; r.a=va[z.a],r.b=z.a; note w1,w2,h1,h2;
			w1.a=-1,w1.b=-1,w2.a=-1,w2.b=-1,h1.a=-1,h1.b=-1,h2.a=-1,h2.b=-1;
			if((*f1[u].begin()).b!=r.b) w1=(*(--f1[u].find(r)));
			if((*f1[u].rbegin()).b!=r.b) w2=(*(++f1[u].find(r)));
			f1[u].erase(r);
			note c; c.a=va[z.b],c.b=z.b;
			if((*f2[u].begin()).b!=c.b) h1=(*(--f2[u].find(c)));
			if((*f2[u].rbegin()).b!=c.b) h2=(*(++f2[u].find(c)));
			f2[u].erase(c);
			if(vb[z.a]+vb[z.b]<0){
				m++,va[m]=va[z.a],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.a]; c.a=va[m],c.b=m; f1[u].insert(c); updatea(u,m);
			}
			if(vb[z.a]+vb[z.b]>0){
				m++,va[m]=va[z.b],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.b]; c.a=va[m],c.b=m;
				f2[u].insert(c); updateb(u,m);
			}
			if(w1.b!=-1) updatea(u,w1.b);
			if(w2.b!=-1) updatea(u,w2.b);
			if(h1.b!=-1) updateb(u,h1.b);
			if(h2.b!=-1) updateb(u,h2.b);
			va[z.a]=-1,va[z.b]=-1;
			g[u].pop();
		}
		else break;
	}
	t[u]+=k;
}
inline int merge(int a,int b){
	if(siz[a]<siz[b]) swap(a,b); siz[a]+=siz[b];
	set<note>::iterator iter = f1[b].begin();
	while(iter!=f1[b].end()){
		note w=(*iter);
		m++,va[m]=w.a+t[b]-t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f1[a].insert(w),iter++,updatea(a,m);
	}
	iter = f2[b].begin();
	while(iter!=f2[b].end()){
		note w=(*iter);
		m++,va[m]=w.a-t[b]+t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f2[a].insert(w),iter++,updateb(a,m);
	}
	return a;
}
inline void dfs(int u,int fa){
	p[u]=u;
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i];
		if(x==fa) continue;
		dfs(x,u);
		for(int c=0;c<e[x].size();c++){
			node s=e[x][c]; vs[m+1]=vs[m+2]=m+2;
			note v; m++,va[m]=s.t*2-t[p[x]],vb[m]=-s.f,v.a=va[m],v.b=m; f1[p[x]].insert(v),updatea(p[x],m);
			note q; m++,va[m]=s.t*2+t[p[x]]+1,vb[m]=s.f,q.a=va[m],q.b=m;  f2[p[x]].insert(q),updateb(p[x],m);
			siz[p[x]]++;
		}
		update(p[x],w[u][i]*2);
		p[u]=merge(p[u],p[x]);
	}
}
inline bool tmp(note a,note b){
	return a.a<b.a;
}
int main(){
	cin>>n; int a,b,c;
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&a,&b,&c);
		v[a].push_back(b),v[b].push_back(a);
		w[a].push_back(c),w[b].push_back(c);
	}
	v[1].push_back(n+1),v[n+1].push_back(1);
	w[1].push_back(1),w[n+1].push_back(1);
	cin>>q;
	while(q--){
		scanf("%d%d%d",&a,&b,&c); node d;
		d.t=a,d.f=b; e[c].push_back(d);
	}
	dfs(n+1,0);
	set<note>::iterator iter = f1[p[n+1]].begin();
	while(iter!=f1[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a+=t[p[n+1]];
		iter++;
	}
	iter = f2[p[n+1]].begin();
	while(iter!=f2[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a-=t[p[n+1]];
		iter++;
	}
	sort(gt+1,gt+k+1,tmp); int sum=0,ans=0;
	for(int i=1;i<=k;i++){
		int j=i; sum+=vb[gt[i].b];
		while(gt[j+1].a==gt[i].a&&j+1<=k) sum+=vb[gt[j+1].b],j++;
		i=j; ans=max(ans,sum);
	}
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7,M=4e6+7;
int n,m,q,k,p[N],t[N],vs[N],siz[N],va[M],vb[M]; vector<int>v[N],w[N];
struct node {int t,f;}; vector<node>e[N];
struct note {int a,b;}gt[N];
struct nope {int a,b,t;};
priority_queue<nope>g[N];
inline int find(int u){
	if(vs[u]==u) return u; return vs[u]=find(vs[u]);
}
inline bool operator < (note a,note b){
	if(a.a==b.a) return a.b>b.b; return a.a<b.a;
}
inline bool operator < (nope a,nope b){
	if(a.t==b.t) return max(a.a,a.b)<max(b.a,b.b);
	return a.t>b.t;
}
set<note>f1[N],f2[N];
inline void updatea(int u,int c){
	note w; w.a=va[c]+t[u]*2+1,w.b=998244353;
	f2[u].insert(w);
	if((*f2[u].rbegin()).b==998244353) {f2[u].erase(w); return;};
	note e=(*(++f2[u].find(w))); f2[u].erase(w);

	if(find(e.b)==find(c)&&(*f2[u].rbegin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(++f2[u].find(e)));
	nope v; v.a=c,v.b=e.b,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void updateb(int u,int c){
	note w; w.a=va[c]-t[u]*2-1,w.b=-998244353;
	f1[u].insert(w);
	if((*f1[u].begin()).b==-998244353) {f1[u].erase(w); return;};
	note e=(*(--f1[u].find(w)));
	f1[u].erase(w);
	if(find(e.b)==find(c)&&(*f1[u].begin()).b==e.b) return;
	if(find(e.b)==find(c)) e=(*(--f1[u].find(e)));

	nope v; v.a=e.b,v.b=c,v.t=(va[v.b]-va[v.a]+1)/2; g[u].push(v);
}
inline void update(int u,int k){
	while(g[u].size()){
		nope z=g[u].top();
		if(va[z.a]==-1||va[z.b]==-1) {g[u].pop(); continue;}
		if(z.t<=t[u]){
			g[u].pop(); continue;
		}
		if(z.t<=t[u]+k){
			g[u].pop();
			note r; r.a=va[z.a],r.b=z.a; note w1,w2,w3,h1,h2,h3;
			w1.a=-1,w1.b=-1,w2.a=-1,w2.b=-1,w3.a=-1,w3.b=-1,h1.a=-1,h1.b=-1,h2.a=-1,h2.b=-1,h3.a=-1,h3.b=-1;
			if((*f1[u].begin()).b!=r.b) w1=(*(--f1[u].find(r)));
			if((*f1[u].rbegin()).b!=r.b) w2=(*(++f1[u].find(r)));
			if((*f1[u].begin()).b!=r.b&&(*f1[u].begin()).b!=w1.b) w3=(*(--f1[u].find(w1)));
			f1[u].erase(r);
			note c; c.a=va[z.b],c.b=z.b;
			if((*f2[u].begin()).b!=c.b) h1=(*(--f2[u].find(c)));
			if((*f2[u].rbegin()).b!=c.b) h2=(*(++f2[u].find(c)));
			if((*f2[u].begin()).b!=c.b&&(*f2[u].begin()).b!=h1.b) h3=(*(--f2[u].find(h1)));
			f2[u].erase(c);
			if(vb[z.a]+vb[z.b]<0){
				m++,va[m]=va[z.a],vb[m]=vb[z.a]+vb[z.b],vs[m]=vs[z.a]; c.a=va[m],c.b=m; f1[u].insert(c); updatea(u,m);
			}
			if(vb[z.a]+vb[z.b]>0){
				m++;
				va[m]=va[z.b];
				vb[m]=vb[z.a]+vb[z.b];
				vs[m]=vs[z.b];
				c.a=va[m];
				c.b=m;
				f2[u].insert(c); updateb(u,m);
			}
			if(w1.b!=-1) updatea(u,w1.b);
			if(w2.b!=-1) updatea(u,w2.b);
			if(w3.b!=-1) updatea(u,w3.b);
			if(h1.b!=-1) updateb(u,h1.b);
			if(h2.b!=-1) updateb(u,h2.b);
			if(h3.b!=-1) updateb(u,h3.b);
			va[z.a]=-1,va[z.b]=-1;
		}
		else break;
	}
	t[u]+=k;
}
inline int merge(int a,int b){
	if(siz[a]<siz[b]) swap(a,b); siz[a]+=siz[b];
	set<note>::iterator iter = f1[b].begin();
	while(iter!=f1[b].end()){
		note w=(*iter);
		m++,va[m]=w.a+t[b]-t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f1[a].insert(w),iter++,updatea(a,m);
	}
	iter = f2[b].begin();
	while(iter!=f2[b].end()){
		note w=(*iter);
		m++,va[m]=w.a-t[b]+t[a],vb[m]=vb[w.b],va[w.b]=-1,w.a=va[m],w.b=m,vs[m]=m;
		f2[a].insert(w),iter++,updateb(a,m);
	}
	return a;
}
inline void dfs(int u,int fa){
	p[u]=u;
	for(int i=0;i<v[u].size();i++){
		int x=v[u][i];
		if(x==fa) continue;
		dfs(x,u);
		for(int c=0;c<e[x].size();c++){
			node s=e[x][c]; vs[m+1]=vs[m+2]=m+2;
			note v; m++,va[m]=s.t*2-t[p[x]],vb[m]=-s.f,v.a=va[m],v.b=m; f1[p[x]].insert(v),updatea(p[x],m);
			note q; m++,va[m]=s.t*2+t[p[x]]+1,vb[m]=s.f,q.a=va[m],q.b=m;  f2[p[x]].insert(q),updateb(p[x],m);
			siz[p[x]]++;
		}
		update(p[x],w[u][i]*2);
		p[u]=merge(p[u],p[x]);
	}
}
inline bool tmp(note a,note b){
	return a.a<b.a;
}
int main(){
	freopen("in.txt","r",stdin);
	cin>>n; int a,b,c;
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&a,&b,&c);
		v[a].push_back(b),v[b].push_back(a);
		w[a].push_back(c),w[b].push_back(c);
	}
	v[1].push_back(n+1),v[n+1].push_back(1);
	w[1].push_back(1),w[n+1].push_back(1);
	cin>>q;
	while(q--){
		scanf("%d%d%d",&a,&b,&c); node d;
		d.t=a,d.f=b; e[c].push_back(d);
	}
	dfs(n+1,0);
	set<note>::iterator iter = f1[p[n+1]].begin();
	while(iter!=f1[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a+=t[p[n+1]];
		iter++;
	}
	iter = f2[p[n+1]].begin();
	while(iter!=f2[p[n+1]].end()){
		note w=(*iter); gt[++k]=w; gt[k].a-=t[p[n+1]];
		iter++;
	}
	sort(gt+1,gt+k+1,tmp); int sum=0,ans=0;
	for(int i=1;i<=k;i++){
		int j=i; sum+=vb[gt[i].b];
		while(gt[j+1].a==gt[i].a&&j+1<=k) sum+=vb[gt[j+1].b],j++;
		i=j; ans=max(ans,sum);
	}
	cout<<ans<<endl;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*addv[id]<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*(addv[id]+d)<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x-addv[id],-inf,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*(addv[id]+d)<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  if (x!=1) f[x].trans(1);
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x-addv[id],-inf,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*(addv[id]+d)<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>
#define FR first
#define SE second
#define inf 0x3f3f3f3f

using namespace std;

typedef pair<int,int> pr;

inline int sgn(int x) {
  return (x>0)?1:-1;
}

int addv[100005];

struct SETS {

int id;

struct Data {
  int x,v,id;
  Data() {}
  Data(int a,int b,int c):x(a),v(b),id(c) {}
  bool operator < (const Data & b) const {
  	int t1=x-sgn(v)*addv[id],t2=b.x-sgn(b.v)*addv[b.id];
  	return (t1!=t2)?t1<t2:v<b.v;
  }
};

typedef pair<int,Data> pr2;

set <Data> st;
set <pr2> dis;

void update1(set<Data>::iterator it,bool v) {
  if (it!=st.begin()) {
  	set<Data>::iterator it2=it;
  	it2--;
  	if (it->v>0&&it2->v<0) {
  		pr2 t(it->x-it2->x,*it);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void update2(set<Data>::iterator it,bool v) {
  set<Data>::iterator it2=it;
  it2++;
  if (it2!=st.end()) {
  	if (it2->v>0&&it->v<0) {
  		pr2 t(it2->x-it->x,*it2);
  		if (v) dis.insert(t); else dis.erase(t);
	  }
  }
}

void add(int x,int v) {
  set<Data>::iterator it=st.lower_bound(Data(x-addv[id],-inf,id));
  if (it!=st.end()&&it->x-sgn(it->v)*addv[id]==x) {
  	update1(it,0);update2(it,0);
  	v+=it->v;
  	st.erase(it);
  	if (v) {
  	  it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	  update1(it,1);update2(it,1);
    }
    else {
      it=st.lower_bound(Data(x+sgn(v)*addv[id],v,id));
      if (it!=st.end()) update1(it,0);
	}
  }
  else {
  	if (it!=st.end()) update1(it,0);
  	it=st.insert(Data(x+sgn(v)*addv[id],v,id)).FR;
  	update1(it,1);update2(it,1);
  }
}

void trans(int d) {
  while (!dis.empty()&&(dis.begin())->FR-2*(addv[id]+d)<=0) {
  	set<Data>::iterator it=st.lower_bound((dis.begin())->SE),it2=it;
  	it2--;
  	update1(it,0);update2(it,0);update1(it2,0);
  	if (abs(it->v)>abs(it2->v)) {
  		Data t=*it;
  		t.v+=it2->v;
  		st.erase(it);st.erase(it2);
  		it=st.insert(t).FR;
  		update1(it,1);update2(it,1);
	  }
	else if (abs(it2->v)>abs(it->v)) {
		Data t=*it2;
		t.v+=it->v;
		st.erase(it);st.erase(it2);
		it2=st.insert(t).FR;
		update1(it2,1);update2(it2,1);
	  }
	else {
		set<Data>::iterator it3=it;
		it3++;
		st.erase(it);st.erase(it2);
		if (it3!=st.end()) update1(it3,1);
	  }
  }
  addv[id]+=d;
}

void merge(SETS &b) {
  if (st.size()<b.st.size()) swap(*this,b);
  for(set<Data>::iterator it=b.st.begin();it!=b.st.end();it++)
    add(it->x-sgn(it->v)*addv[b.id],it->v);
}

int query() {
  int ans=0,s=0;
  for(set<Data>::iterator it=st.begin();it!=st.end();it++) {
  	s+=it->v;
  	ans=max(ans,s);
  }
  return ans;
}

};

SETS f[100005];

struct Edge {
  int t,v,next;
  Edge() {}
  Edge(int a,int b,int c):t(a),v(b),next(c) {}
};

Edge e[200005];
int head[100005];

vector <pr> vt[100005];

void dfs(int x,int fa) {
  for(int i=head[x];i;i=e[i].next)
    if (e[i].t!=fa) {
    	int u=e[i].t;
    	dfs(u,x);
    	f[u].trans(e[i].v-1);
    	f[x].merge(f[u]);
	}
  f[x].trans(1);
  for(int i=0;i<vt[x].size();i++) {
  	int d=vt[x][i].FR,v=vt[x][i].SE;
  	f[x].add(d,v);
  	f[x].add(d+1,-v);
  }
}

int main() {
  int n;
  scanf("%d",&n);
  for(int i=1;i<n;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	e[2*i-1]=Edge(y,2*z,head[x]);
  	head[x]=2*i-1;
  	e[2*i]=Edge(x,2*z,head[y]);
  	head[y]=2*i;
  }
  int m;
  scanf("%d",&m);
  for(int i=1;i<=m;i++) {
  	int x,y,z;
  	scanf("%d%d%d",&x,&y,&z);
  	vt[z].push_back(pr(2*x,y));
  }
  for(int i=1;i<=n;i++) f[i].id=i;
  dfs(1,0);
  printf("%d\n",f[1].query());
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

namespace flow {
struct edge_t {
  int to, cap, rev;

  edge_t(int t, int c, int r) {
    to = t;
    cap = c;
    rev = r;
  }
};

int n, source, sink, answer;
vector<vector<edge_t>> adj;
vector<int> dist, current;

void init(int v, int s, int t) {
  n = v;
  source = s;
  sink = t;
  answer = 0;
  adj.resize(n);
  dist.resize(n);
  current.resize(n);
}

void add(int x, int y, int c) {
  adj[x].push_back(edge_t(y, c, adj[y].size()));
  adj[y].push_back(edge_t(x, 0, adj[x].size() - 1));
}

bool bfs() {
  queue<int> q;
  for (int i = 0; i < n; ++i) {
    dist[i] = -1;
  }
  dist[source] = 0, q.push(source);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (auto e : adj[x]) {
      if (e.cap && !~dist[e.to]) {
        dist[e.to] = dist[x] + 1;
        if (e.to == sink) {
          return true;
        }
        q.push(e.to);
      }
    }
  }
  return false;
}

int dfs(int x, int f) {
  if (x == sink) {
    return f;
  }
  for (int &i = current[x]; ~i; --i) {
    edge_t &e = adj[x][i];
    if (e.cap && dist[e.to] == dist[x] + 1) {
      int w = dfs(e.to, min(e.cap, f));
      if (w) {
        e.cap -= w;
        adj[e.to][e.rev].cap += w;
        return w;
      }
    }
  }
  return 0;
}

int max_flow() {
  while (bfs()) {
    for (int i = 0; i < n; ++i) {
      current[i] = adj[i].size() - 1;
    }
    while (true) {
      int flow = dfs(source, inf);
      if (!flow) {
        break;
      }
      answer += flow;
    }
  }
  return answer;
}
}

using flow::source;
using flow::sink;
using flow::init;
using flow::add;
using flow::max_flow;

const int N = 100005;

int n, m, total, day[N], fish[N], lake[N], size[N], depth[N];
vector<pair<int, int>> edges, adj[N];
vector<int> all, event[N];
bool visit[N];

void find_root(int x, int p, int s, int &root) {
  bool flag = true;
  size[x] = 1;
  for (auto e : adj[x]) {
    int y = e.first;
    if (y != p && !visit[y]) {
      find_root(y, x, s, root);
      size[x] += size[y];
      flag &= size[y] <= s >> 1;
    }
  }
  flag &= size[x] >= s >> 1;
  if (flag) {
    root = x;
  }
}

void find_size(int x, int p, bool insert) {
  size[x] = 1;
  for (auto e : adj[x]) {
    int y = e.first;
    if (y != p && !visit[y]) {
      depth[y] = depth[x] + e.second;
      find_size(y, x, true);
      size[x] += size[y];
    }
  }
  if (insert) {
    for (auto i : event[x]) {
      all.push_back(i);
    }
  }
}

void divide(int x, int s) {
  int root;
  find_root(x, 0, s, root);
  visit[x = root] = true;
  depth[x] = 0;
  all.clear();
  find_size(x, 0, false);
  vector<pair<int, int>> by_sub;
  for (auto i : all) {
    by_sub.push_back(make_pair(day[i] - depth[lake[i]], i));
  }
  sort(by_sub.begin(), by_sub.end());
  for (int i = 1; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i, total + i + 1);
  }
  for (int i = 0; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i + 1, by_sub[i].second + m);
  }
  for (auto i : all) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  for (auto i : event[x]) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  total += by_sub.size();
  by_sub.clear();
  for (auto i : event[x]) {
    by_sub.push_back(make_pair(day[i] - depth[lake[i]], i));
  }
  sort(by_sub.begin(), by_sub.end());
  for (int i = 1; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i, total + i + 1);
  }
  for (int i = 0; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i + 1, by_sub[i].second + m);
  }
  for (auto i : all) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  total += by_sub.size();
  for (auto e : adj[x]) {
    if (!visit[e.first]) {
      divide(e.first, size[e.first]);
    }
  }
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    adj[x].push_back(make_pair(y, w));
    adj[y].push_back(make_pair(x, w));
  }
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d", &day[i], &fish[i], &lake[i]);
    event[lake[i]].push_back(i);
  }
  total = m << 1 | 1;
  divide(1, n);
  init(total + 1, 0, m << 1 | 1);
  for (auto e : edges) {
    add(e.first, e.second, inf);
  }
  int answer = 0;
  for (int i = 1; i <= m; ++i) {
    add(source, i, fish[i]);
    add(i + m, sink, fish[i]);
    answer += fish[i];
  }
  printf("%d\n", answer - max_flow());
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;

namespace flow {
struct edge_t {
  int to, cap, rev;

  edge_t(int t, int c, int r) {
    to = t;
    cap = c;
    rev = r;
  }
};

int n, source, sink, answer;
vector<vector<edge_t>> adj;
vector<int> dist, current;

void init(int v, int s, int t) {
  n = v;
  source = s;
  sink = t;
  answer = 0;
  adj.resize(n);
  dist.resize(n);
  current.resize(n);
}

void add(int x, int y, int c) {
  adj[x].push_back(edge_t(y, c, adj[y].size()));
  adj[y].push_back(edge_t(x, 0, adj[x].size() - 1));
}

bool bfs() {
  queue<int> q;
  for (int i = 0; i < n; ++i) {
    dist[i] = -1;
  }
  dist[source] = 0, q.push(source);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (auto e : adj[x]) {
      if (e.cap && !~dist[e.to]) {
        dist[e.to] = dist[x] + 1;
        if (e.to == sink) {
          return true;
        }
        q.push(e.to);
      }
    }
  }
  return false;
}

int dfs(int x, int f) {
  if (x == sink) {
    return f;
  }
  for (int &i = current[x]; ~i; --i) {
    edge_t &e = adj[x][i];
    if (e.cap && dist[e.to] == dist[x] + 1) {
      int w = dfs(e.to, min(e.cap, f));
      if (w) {
        e.cap -= w;
        adj[e.to][e.rev].cap += w;
        return w;
      }
    }
  }
  return 0;
}

int max_flow() {
  while (bfs()) {
    for (int i = 0; i < n; ++i) {
      current[i] = adj[i].size() - 1;
    }
    while (true) {
      int flow = dfs(source, inf);
      if (!flow) {
        break;
      }
      answer += flow;
    }
  }
  return answer;
}
}

using flow::source;
using flow::sink;
using flow::init;
using flow::add;
using flow::max_flow;

const int N = 100005;

int n, m, total, day[N], fish[N], lake[N], size[N], depth[N];
vector<pair<int, int>> edges, adj[N];
vector<int> all, event[N];
bool visit[N];

void find_root(int x, int p, int s, int &root) {
  bool flag = true;
  size[x] = 1;
  for (auto e : adj[x]) {
    int y = e.first;
    if (y != p && !visit[y]) {
      find_root(y, x, s, root);
      size[x] += size[y];
      flag &= size[y] <= s >> 1;
    }
  }
  flag &= size[x] >= s >> 1;
  if (flag) {
    root = x;
  }
}

void find_size(int x, int p, bool insert) {
  size[x] = 1;
  for (auto e : adj[x]) {
    int y = e.first;
    if (y != p && !visit[y]) {
      depth[y] = depth[x] + e.second;
      find_size(y, x, true);
      size[x] += size[y];
    }
  }
  if (insert) {
    for (auto i : event[x]) {
      all.push_back(i);
    }
  }
}

void divide(int x, int s) {
  int root;
  find_root(x, 0, s, root);
  visit[x = root] = true;
  depth[x] = 0;
  all.clear();
  find_size(x, 0, false);
  vector<pair<int, int>> by_sub;
  for (auto i : all) {
    by_sub.push_back(make_pair(day[i] - depth[lake[i]], i));
  }
  sort(by_sub.begin(), by_sub.end());
  for (int i = 1; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i, total + i + 1);
  }
  for (int i = 0; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i + 1, by_sub[i].second + m);
  }
  for (auto i : all) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  for (auto i : event[x]) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  total += by_sub.size();
  by_sub.clear();
  for (auto i : event[x]) {
    by_sub.push_back(make_pair(day[i] - depth[lake[i]], i));
  }
  sort(by_sub.begin(), by_sub.end());
  for (int i = 1; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i, total + i + 1);
  }
  for (int i = 0; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i + 1, by_sub[i].second + m);
  }
  for (auto i : all) {
    int limit = day[i] + depth[lake[i]], bound = lower_bound(by_sub.begin(), by_sub.end(), make_pair(limit, 0)) - by_sub.begin();
    if (bound != by_sub.size()) {
      edges.emplace_back(i, total + bound + 1);
    }
  }
  total += by_sub.size();
  by_sub.clear();
  for (auto i : event[x]) {
    by_sub.push_back(make_pair(day[i], i));
  }
  sort(by_sub.begin(), by_sub.end());
  for (int i = 1; i < by_sub.size(); ++i) {
    edges.emplace_back(total + i, total + i + 1);
    edges.emplace_back(by_sub[i].second, total + i + 1);
  }
  total += by_sub.size();
  for (auto e : adj[x]) {
    if (!visit[e.first]) {
      divide(e.first, size[e.first]);
    }
  }
}

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    adj[x].push_back(make_pair(y, w));
    adj[y].push_back(make_pair(x, w));
  }
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d", &day[i], &fish[i], &lake[i]);
    event[lake[i]].push_back(i);
  }
  total = m << 1 | 1;
  divide(1, n);
  init(total + 1, 0, m << 1 | 1);
  for (auto e : edges) {
    add(e.first, e.second, inf);
  }
  int answer = 0;
  for (int i = 1; i <= m; ++i) {
    add(source, i, fish[i]);
    add(i + m, sink, fish[i]);
    answer += fish[i];
  }
  printf("%d\n", answer - max_flow());
  return 0;
}

#include <bits/stdc++.h>
const int64_t INF=2e9+7;
int64_t current_time;
struct End
{
  int64_t x,v;
  int64_t a;
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a)
  {
  }
  bool operator<(struct End other)const
  {
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;
    return false;
  }
  struct End operator-()
  {
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump()
  {
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};
struct Collision
{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2)
  {
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const
  {
    if(time2!=other.time2) return time2<other.time2;
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump()
  {
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};
struct DS
{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2)
  {
    assert(e1<e2);
    if(e1.v>0&&e2.v<0)
    {
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2)
  {
    assert(e1<e2);
    if(e1.v>0&&e2.v<0)
    {
      struct Collision c(e1,e2);
      if(!collide.count(c))
      {
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2)
  {
    if(e1.a>e2.a)
    {
      return End(e1.x,e1.v,e1.a-e2.a);
    }
    else
    {
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e)
  {
    if(e.a==0) return;
    if(ends.count(e))
    {
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;
    auto next=std::next(it);
    if(it!=ends.begin())
    {
      auto prev=std::prev(it);
      if(next!=ends.end())
      {
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end())
    {
      insertc(*it,*next);
    }
  }
  int64_t prep(int64_t T,int64_t A)
  {
    struct End l(T+1,-1,A,current_time);
    struct End r(T-1,1,A,current_time);
    int Al=ends.count(l)?ends.find(l)->a:0;
    int Ar=ends.count(r)?ends.find(r)->a:0;
    return std::max<int64_t>(0,std::min<int64_t>(A-Al,A-Ar));
  }
  void insert_fish(int64_t T,int64_t A)
  {
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l))
    {
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r))
    {
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e)
  {
    if(e.a==0) return;
    if(ends.count(-e))
    {
      auto e2=*ends.find(-e);
      erase(e2);
      insert(cancel(e,e2));
    }
    else
    {
      insert(e);
    }
  }
  void erase(struct End e)
  {
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end())
    {
      erasec(*it,*next);
    }
    if(it!=ends.begin())
    {
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end())
      {
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c)
  {
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  void ffwd(int64_t t)
  {
    while(collide.size()&&collide.begin()->time2<=t*2)
    {
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t)
  {
    while(collide.size()&&collide.begin()->time2<t*2)
    {
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other)
    {
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  void merge(struct DS& other)
  {
    if(ends.size()<other.ends.size())
    {
      swap(other);
    }
    for(auto e:other.ends)
    {
      insert(e);
    }
  }
  int64_t query()
  {
    int64_t ac=0;
    for(auto it:ends)
    {
      if(it.v>0)
      {
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump()
  {
    printf("T=%I64d\n",current_time);
    for(auto e:ends)
    {
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide)
    {
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};
std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];
struct DS dss[100005];
int64_t depth[100005];
void dfs_depth(int64_t node,int64_t parent)
{
  for(auto e:edges[node])
  {
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}
void dfs_solve(int64_t node,int64_t parent)
{
  current_time=-depth[node];
  for(auto e:edges[node])
  {
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
  }
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node])
  {
    f.second=dss[node].prep(f.first,f.second);
  }
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  current_time=-depth[node];
  current_time=-depth[node];
  for(auto f:fish[node])
  {
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert(End(D,1,F,current_time));
    dss[node].insert(End(D,-1,F,current_time));
  }
  current_time=-depth[node];
}
int main()
{
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++)
  {
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++)
  {
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <functional>
#include <cmath>
#include <string>
#include <set>
#include <map>
#define SIZE 200005

using namespace std;
typedef long long int ll;
typedef pair <ll,ll> P;
typedef pair <P,P> PP;

struct edge
{
	int to;
	ll cost;
	edge(int to=0,ll cost=0):to(to),cost(cost){}
};
vector <edge> vec[SIZE];
vector <P> up[SIZE];
vector <P> down[SIZE];
vector <int> vt[SIZE];
ll dep[SIZE];
int nd[SIZE],back[SIZE];
int pos[SIZE],cmb[SIZE];
int par[SIZE],len[SIZE];
PP now[SIZE];
int now_sz;

void dfs(int v=0,int p=-1,int d=0)
{
	dep[v]=d;
	nd[v]=1;
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p)
		{
			dfs(e.to,v,d+e.cost);
			nd[v]+=nd[e.to];
		}
	}
}
void heavy_light(int v=0,int p=-1,int b=-1)
{
	vt[now_sz].push_back(v);
	par[now_sz]=b;
	back[v]=b;
	pos[v]=len[now_sz]++;
	cmb[v]=now_sz;
	bool up=false;
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p&&nd[e.to]*2>=nd[v])
		{
			heavy_light(e.to,v,b);
			up=true;
			break;
		}
	}
	if(!up)
	{
		now_sz++;
	}
	for(int i=0;i<vec[v].size();i++)
	{
		edge e=vec[v][i];
		if(e.to!=p&&nd[e.to]*2<nd[v])
		{
			heavy_light(e.to,v,v);
		}
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		ll c;
		scanf("%d %d %lld",&a,&b,&c);a--,b--,c*=(ll) n,c--;
		vec[a].push_back(edge(b,c));
		vec[b].push_back(edge(a,c));
	}
	dfs();
	heavy_light();
	int m;
	scanf("%d",&m);
	ll all=0;
	for(int i=0;i<m;i++)
	{
		ll t;
		int f,v;
		scanf("%lld %d %d",&t,&f,&v);t*=(ll) n,v--;
		up[v].push_back(P(t+dep[v],f));
		down[v].push_back(P(t-dep[v]-1,f));
		all+=f;
	}
	ll ret=0;
	for(int t=now_sz-1;t>=0;t--)
	{
		int sz=0;
		for(int i=0;i<vt[t].size();i++)
		{
			int v=vt[t][i];
			for(int j=0;j<up[v].size();j++)
			{
				P p=up[v][j];
				now[sz++]=PP(P(p.first,-1),P(p.first-2LL*dep[v],p.second));
			}
			for(int j=0;j<down[v].size();j++)
			{
				P p=down[v][j];
				now[sz++]=PP(P(p.first+2LL*dep[v],1),p);
			}
		}
		multiset <P> st;
		multiset <P>::iterator it;
		sort(now,now+sz);/*
		if(t<=10)
		{
			printf("* %d %lld\n",t,ret);
			for(int i=0;i<sz;i++) printf("[%lld %lld] [%lld %lld]\n",now[i].first.first,now[i].first.second,now[i].second.first,now[i].second.second);
		}*/
		for(int i=sz-1;i>=0;i--)
		{
			if(now[i].first.second==-1)//query
			{
				P q=now[i].second;
				while(q.second>0)
				{
					it=st.lower_bound(P(q.first,-1));
					if(it!=st.end())
					{
						P p=*it;
						ll df=now[i].first.first-p.first;
						if(t==0||df>=2LL*dep[par[t]])
						{
							st.erase(it);
							ll c=min(q.second,p.second);
							ret+=c;
							q.second-=c;
							p.second-=c;
							if(p.second>0) st.insert(p);
						}
						else break;
					}
					else break;
				}
				if(q.second>0&&t>0) up[par[t]].push_back(P(now[i].first.first,q.second));
			}
			else//add
			{
				st.insert(now[i].second);
			}
		}
		if(t>0)
		{
			for(it=st.begin();it!=st.end();it++) down[par[t]].push_back(*it);
			st.clear();
		}
		//printf("* %d %lld\n",t,ret);
	}
	printf("%lld\n",all-ret);
	return 0;
}

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
#define ld long double
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int n;
vector<PI> ask[N],v[N];
struct Set{
	map<int,int> sz,sf;
	priority_queue<PI,vector<PI>,greater<PI> > q;
	int add;
	void bao(int x,int id){
		if(id==1){
			auto it=sf.upper_bound(x-2*add);
			if(it==sf.begin())return; it--;
			q.push(mp(x-it->first,x));
		}else{
			auto it=sz.lower_bound(x+2*add);
			if(it==sz.end())return;
			q.push(mp(it->first-x,it->first));
		}
	}
	void move(int de){
		for(auto i:sz)bao(i.first,1);
		while(q.size()&&q.top().first<=2*(add+de)){
			PI t=q.top(); q.pop();
			int x=t.second,y=t.second-t.first;
			auto xx=sz.find(x),yy=sf.find(y);
			if(xx==sz.end()||yy==sf.end())continue;
			if(xx->second<-yy->second){
				yy->second+=xx->second; sz.erase(xx); bao(yy->first,-1);
			}else{
				xx->second+=yy->second; sf.erase(yy); bao(xx->first,1);
			}
		}
		add+=de;
	}
	void insert(int x,int de){
		if(de>0){
			sz[x+add]+=de;
			bao(x+add,1);
		}else{
			sf[x-add]+=de;
			bao(x-add,-1);
		}
	}
	int get(){
		int ans=0,dq=0;
		for(auto i=sz.begin(),j=sf.begin();i!=sz.end()&&j!=sf.end();){
			if(i==sz.end()||(j!=sf.end()&&i->first-add>=j->first+add)){
				dq+=j->second; j++;
			}else{
				dq+=i->second; i++;
			}
			ans=max(ans,dq);
		}
		return ans;
	}
	int cha(int pos){
		return (sz.count(pos+add)?sz[pos+add]:0)+(sf.count(pos-add)?sf[pos-add]:0);
	}
	int size(){
		return sz.size()+sf.size();
	}
}s[N];//正数比负数大
void Merge(Set &x,Set &y){
	for(auto i:y.sz){
		x.insert(i.first-y.add,i.second);
	}
	for(auto i:y.sf){
		x.insert(i.first+y.add,i.second);
	}
}
void print(Set s){
	cout<<s.add<<endl;
	for(auto i:s.sz)cout<<i.first-s.add<<" "<<i.second<<" wzp\n";
	for(auto i:s.sf)cout<<i.first+s.add<<" "<<i.second<<" cqz\n";
	puts("");
}
void alb(int x){
	for(auto i:ask[x]){
		s[x].insert(i.first,i.second);
		s[x].insert(i.first+1,-i.second);
	}
}
void dfs(int p,int fa){
	for(auto i:v[p])if(i.first!=fa){
		int v=i.first,len=i.second;
		dfs(v,p);
		for(auto &j:ask[v])j.second-=max(0,max(-s[v].cha(j.first),s[v].cha(j.first+1)));
		s[v].move(1);
		alb(v);
		s[v].move(len-1);
		if(s[p].size()<s[v].size())swap(s[p],s[v]);
		Merge(s[p],s[v]);
		//print(s[v]);
		//print(s[p]);
		//if(s[p].cha(4)==-2)while(1);
	}
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int s=read(),t=read(),l=read()*2;
		v[s].push_back(mp(t,l));
		v[t].push_back(mp(s,l));
	}
	int m=read();
	while(m--){
		int d=read()*2,x=read(),p=read();
		ask[p].push_back(mp(d,x));
	}
	v[0].push_back(mp(1,2));
	dfs(0,0);
	//print(s[0]);
	cout<<s[0].get()<<endl;
}
/*
sz里存所有正数
sf里存所有负数
q里存所有最近的正负
add里的lazy

毒瘤处:该子树内时必须只能出现在一个位置
之后展开len-1
*/

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
#define ld long double
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int n;
vector<PI> ask[N],v[N];
struct Set{
	map<int,int> sz,sf;
	priority_queue<PI,vector<PI>,greater<PI> > q;
	int add;
	void bao(int x,int id){
		if(id==1){
			auto it=sf.upper_bound(x-2*add);
			if(it==sf.begin())return; it--;
			q.push(mp(x-it->first,x));
		}else{
			auto it=sz.lower_bound(x+2*add);
			if(it==sz.end())return;
			q.push(mp(it->first-x,it->first));
		}
	}
	void move(int de){
		while(q.size()&&q.top().first<=2*(add+de)){
			PI t=q.top(); q.pop();
			int x=t.second,y=t.second-t.first;
			auto xx=sz.find(x),yy=sf.find(y);
			if(xx==sz.end()||yy==sf.end())continue;
			if(xx->second<-yy->second){
				yy->second+=xx->second; sz.erase(xx); bao(yy->first,-1);
			}else{
				xx->second+=yy->second; sf.erase(yy); bao(xx->first,1);
			}
		}
		add+=de;
	}
	void insert(int x,int de){
		if(de>0){
			sz[x+add]+=de;
			bao(x+add,1);
		}else{
			sf[x-add]+=de;
			bao(x-add,-1);
		}
	}
	int get(){
		int ans=0,dq=0;
		for(auto i=sz.begin(),j=sf.begin();i!=sz.end()&&j!=sf.end();){
			if(i==sz.end()||(j!=sf.end()&&i->first-add>=j->first+add)){
				dq+=j->second; j++;
			}else{
				dq+=i->second; i++;
			}
			ans=max(ans,dq);
		}
		return ans;
	}
	int cha(int pos){
		return (sz.count(pos+add)?sz[pos+add]:0)+(sf.count(pos-add)?sf[pos-add]:0);
	}
	int size(){
		return sz.size()+sf.size()+q.size();
	}
}s[N];//正数比负数大
void Merge(Set &x,Set &y){
	for(auto i:y.sz){
		x.insert(i.first-(y.add-x.add),i.second);
	}
	for(auto i:y.sf){
		x.insert(i.first+(y.add-x.add),i.second);
	}
}
void print(Set s){
	cout<<s.add<<endl;
	for(auto i:s.sz)cout<<i.first<<" "<<i.second<<" wzp\n";
	for(auto i:s.sf)cout<<i.first<<" "<<i.second<<" cqz\n";
	puts("");
}
void alb(int x){
	for(auto i:ask[x]){
		s[x].insert(i.first,i.second);
		s[x].insert(i.first+1,-i.second);
	}
}
void dfs(int p,int fa){
	for(auto i:v[p])if(i.first!=fa){
		int v=i.first,len=i.second;
		dfs(v,p);
		for(auto &j:ask[v])j.second-=max(0,max(-s[v].cha(j.first),s[v].cha(j.first+1)));
		s[v].move(1);
		alb(v);
		s[v].move(len-1);
		//if(s[p].size()<s[v].size())swap(s[p],s[v]);
		Merge(s[p],s[v]);
		//print(s[v]);
		//print(s[p]);
	}
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int s=read(),t=read(),l=read()*2;
		v[s].push_back(mp(t,l));
		v[t].push_back(mp(s,l));
	}
	int m=read();
	while(m--){
		int d=read()*2,x=read(),p=read();
		ask[p].push_back(mp(d,x));
	}
	v[0].push_back(mp(1,2));
	dfs(0,0);
	//print(s[0]);
	cout<<s[0].get()<<endl;
}
/*
sz里存所有正数
sf里存所有负数
q里存所有最近的正负
add里的lazy

毒瘤处:该子树内时必须只能出现在一个位置
之后展开len-1
*/

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
#define ld long double
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int n;
vector<PI> ask[N],v[N];
struct Set{
	map<int,int> sz,sf;
	priority_queue<PI,vector<PI>,greater<PI> > q;
	int add;
	void bao(int x,int id){
		if(id==1){
			auto it=sf.upper_bound(x-2*add);
			if(it==sf.begin())return; it--;
			q.push(mp(x-it->first,x));
		}else{
			auto it=sz.lower_bound(x+2*add);
			if(it==sz.end())return;
			q.push(mp(it->first-x,it->first));
		}
	}
	void move(int de){
		while(q.size()&&q.top().first<=2*(add+de)){
			PI t=q.top(); q.pop();
			int x=t.second,y=t.second-t.first;
			auto xx=sz.find(x),yy=sf.find(y);
			if(xx==sz.end()||yy==sf.end())continue;
			if(xx->second<-yy->second){
				yy->second+=xx->second; sz.erase(xx); bao(yy->first,-1);
			}else{
				xx->second+=yy->second; sf.erase(yy); bao(xx->first,1);
			}
		}
		add+=de;
	}
	void insert(int x,int de){
		if(de>0){
			sz[x+add]+=de;
			bao(x+add,1);
		}else{
			sf[x-add]+=de;
			bao(x-add,-1);
		}
	}
	int get(){
		int ans=0,dq=0;
		for(auto i=sz.begin(),j=sf.begin();i!=sz.end()&&j!=sf.end();){
			if(i==sz.end()||(j!=sf.end()&&i->first-add>=j->first+add)){
				dq+=j->second; j++;
			}else{
				dq+=i->second; i++;
			}
			ans=max(ans,dq);
		}
		return ans;
	}
	int cha(int pos){
		return (sz.count(pos+add)?sz[pos+add]:0)+(sf.count(pos-add)?sf[pos-add]:0);
	}
	int size(){
		return sz.size()+sf.size();
	}
}s[N];//正数比负数大
void Merge(Set &x,Set &y){
	for(auto i:y.sz){
		x.insert(i.first-y.add,i.second);
	}
	for(auto i:y.sf){
		x.insert(i.first+y.add,i.second);
	}
}
void print(Set s){
	cout<<s.add<<endl;
	for(auto i:s.sz)cout<<i.first-s.add<<" "<<i.second<<" wzp\n";
	for(auto i:s.sf)cout<<i.first+s.add<<" "<<i.second<<" cqz\n";
	puts("");
}
void alb(int x){
	for(auto i:ask[x]){
		s[x].insert(i.first,i.second);
		s[x].insert(i.first+1,-i.second);
	}
}
void dfs(int p,int fa){
	for(auto i:v[p])if(i.first!=fa){
		int v=i.first,len=i.second;
		dfs(v,p);
		for(auto &j:ask[v])j.second-=max(0,max(-s[v].cha(j.first),s[v].cha(j.first+1)));
		s[v].move(1);
		alb(v);
		s[v].move(len-1);
		if(s[p].size()<s[v].size())swap(s[p],s[v]);
		Merge(s[p],s[v]);
		//print(s[v]);
		//print(s[p]);
		//if(s[p].cha(4)==-2)while(1);
	}
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int s=read(),t=read(),l=read()*2;
		v[s].push_back(mp(t,l));
		v[t].push_back(mp(s,l));
	}
	int m=read();
	while(m--){
		int d=read()*2,x=read(),p=read();
		ask[p].push_back(mp(d,x));
	}
	v[0].push_back(mp(1,2));
	dfs(0,0);
	//print(s[0]);
	cout<<s[0].get()<<endl;
}
/*
sz里存所有正数
sf里存所有负数
q里存所有最近的正负
add里的lazy

毒瘤处:该子树内时必须只能出现在一个位置
之后展开len-1
*/

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
#define ld long double
#define PI pair<int,int>
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
const int N=100005;
int n;
vector<PI> ask[N],v[N];
struct Set{
	map<int,int> sz,sf;
	priority_queue<PI,vector<PI>,greater<PI> > q;
	int add;
	void bao(int x,int id){
		if(id==1){
			auto it=sf.upper_bound(x-2*add);
			if(it==sf.begin())return; it--;
			q.push(mp(x-it->first,x));
		}else{
			auto it=sz.lower_bound(x+2*add);
			if(it==sz.end())return;
			q.push(mp(it->first-x,it->first));
		}
	}
	void move(int de){
		while(q.size()&&q.top().first<=2*(add+de)){
			PI t=q.top(); q.pop();
			int x=t.second,y=t.second-t.first;
			auto xx=sz.find(x),yy=sf.find(y);
			if(xx==sz.end()||yy==sf.end())continue;
			if(xx->second<-yy->second){
				yy->second+=xx->second; sz.erase(xx); bao(yy->first,-1);
			}else{
				xx->second+=yy->second; sf.erase(yy); bao(xx->first,1);
			}
		}
		add+=de;
	}
	void insert(int x,int de){
		if(de>0){
			sz[x+add]+=de;
			bao(x+add,1);
		}else{
			sf[x-add]+=de;
			bao(x-add,-1);
		}
	}
	int get(){
		int ans=0,dq=0;
		for(auto i=sz.begin(),j=sf.begin();i!=sz.end()&&j!=sf.end();){
			if(i==sz.end()||(j!=sf.end()&&i->first-add>=j->first+add)){
				dq+=j->second; j++;
			}else{
				dq+=i->second; i++;
			}
			ans=max(ans,dq);
		}
		return ans;
	}
	int cha(int pos){
		return (sz.count(pos+add)?sz[pos+add]:0)+(sf.count(pos-add)?sf[pos-add]:0);
	}
	int size(){
		return sz.size()+sf.size();
	}
}s[N];//正数比负数大
void Merge(Set &x,Set &y){
	for(auto i:y.sz){
		x.insert(i.first-(y.add-x.add),i.second);
	}
	for(auto i:y.sf){
		x.insert(i.first+(y.add-x.add),i.second);
	}
}
void print(Set s){
	cout<<s.add<<endl;
	for(auto i:s.sz)cout<<i.first<<" "<<i.second<<" wzp\n";
	for(auto i:s.sf)cout<<i.first<<" "<<i.second<<" cqz\n";
	puts("");
}
void alb(int x){
	for(auto i:ask[x]){
		s[x].insert(i.first,i.second);
		s[x].insert(i.first+1,-i.second);
	}
}
void dfs(int p,int fa){
	for(auto i:v[p])if(i.first!=fa){
		int v=i.first,len=i.second;
		dfs(v,p);
		for(auto &j:ask[v])j.second-=max(0,max(-s[v].cha(j.first),s[v].cha(j.first+1)));
		s[v].move(1);
		alb(v);
		s[v].move(len-1);
		if(s[p].size()<s[v].size())swap(s[p],s[v]);
		Merge(s[p],s[v]);
		//print(s[v]);
		//print(s[p]);
	}
}
int main(){
	n=read();
	for(int i=1;i<n;i++){
		int s=read(),t=read(),l=read()*2;
		v[s].push_back(mp(t,l));
		v[t].push_back(mp(s,l));
	}
	int m=read();
	while(m--){
		int d=read()*2,x=read(),p=read();
		ask[p].push_back(mp(d,x));
	}
	v[0].push_back(mp(1,2));
	dfs(0,0);
	//print(s[0]);
	cout<<s[0].get()<<endl;
}
/*
sz里存所有正数
sf里存所有负数
q里存所有最近的正负
add里的lazy

毒瘤处:该子树内时必须只能出现在一个位置
之后展开len-1
*/

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    //printf("(insertc) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("insertc "),c.dump(),printf("\n");
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    //printf("(erasec) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("erasec "),c.dump(),printf("\n");
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    //printf("INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  void prep(int64_t T,int64_t& L,int64_t& R){
    assert(L==R);
    struct End l(T+1,-1,L,current_time);
    struct End r(T-1,1,R,current_time);
    //printf("CHECKING FOR "),l.dump(),printf(" and "),r.dump(),printf("\n");
    if(ends.count(l)){
      if(R>ends.find(l)->a){
	R-=ends.find(l)->a;
	erase(*ends.find(l));
      }else{
	L=0,R=0;
      }
    }
    if(ends.count(r)){
      if(L>ends.find(r)->a){
	L-=ends.find(r)->a;
	erase(*ends.find(r));
      }else{
	L=0,R=0;
      }
    }
  }
  void insert_fish(int64_t T,int64_t A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    //printf("CANCEL INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      //printf("INSERT CANCEL "),e.dump(),printf(" with "),e2.dump(),printf(" => "),cancel(e,e2).dump(),printf("\n");
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    //printf("ERASE "),e.dump(),printf("\n");
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    //printf("ANNIHILIATE "),c.dump(),printf(" => "),cancel(c.e1,c.e2).dump(),printf("\n");
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
    //dump();
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t){
    while(collide.size()&&collide.begin()->time2<t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
    //printf("MERGE %I64d into %I64d\n",child+1,node+1);
    //dss[node].dump();
  }
  //printf("BEFORE CLEANUP\n");
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node]){
    ls.push_back(f.second);
    rs.push_back(f.second);
    dss[node].prep(f.first,ls.back(),rs.back());
  }
  //dss[node].dump();
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  //printf("BEFORE ADDING FISH\n");
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  current_time=-depth[node];
  for(int64_t i=0;i<(int)fish[node].size();i++){
    current_time=-depth[node];
    //dss[node].insert_fish(D,F);
    //printf("ADDING %I64d,%I64d at %I64d\n",ls[i],rs[i],fish[node][i].first);
    dss[node].insert(End(fish[node][i].first,-1,ls[i],current_time));
    dss[node].insert(End(fish[node][i].first,1,rs[i],current_time));
    //dss[node].cancel_insert(End(D,1,F,current_time));
    //dss[node].cancel_insert(End(D,-1,F,current_time));
  }
  //printf("POST %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    //dss[P].insert(End(D,1,F,current_time));
    //dss[P].insert(End(D,-1,F,current_time));
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  //printf("FINAL\n");
  //dss[0].dump();
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=e2.x) return e1.x<e2.x;
    if(e1.v!=e2.v) return e1.v<e2.v;
    if(e1.a!=e2.a) return e1.a<e2.a;
    return false;
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(const struct End& e1,const struct End& e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      assert(collide.insert(c).second);
    }
  }
  void erasec(const struct End& e1,const struct End& e2){
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void _insert(struct End e){
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  void insert(struct End e){
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      erase(e2);
      insert(cancel(e,e2));
      return;
    }
    _insert(e);
  }
  void erase(const struct End& e){
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(const struct Collision& c){
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    return;
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: %I64d[%I64d+%I64dt]\n",e.a,e.x+e.v*current_time,e.v);
    }
    for(auto c:collide){
      printf("COLLISION AT %I64d/2: %I64d[%I64d+%I64dt] and %I64d[%I64d+%I64dt]\n",c.time2,
	     c.e1.a,c.e1.x+c.e1.v*current_time,c.e1.v,
	     c.e2.a,c.e2.x+c.e2.v*current_time,c.e2.v);
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
//std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]);
    current_time=-depth[node],dss[node].merge(dss[child]);
  }
  //printf("POST %I64d:\n",node+1);
  dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L);
    edges[V].emplace_back(U,L);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    current_time=-depth[P];
    dss[P]._insert(End(D,1,F,current_time));
    dss[P]._insert(End(D,-1,F,current_time));
    //fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  //dss[0].ffwd(INF);
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    //printf("(insertc) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("insertc "),c.dump(),printf("\n");
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    //printf("(erasec) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("erasec "),c.dump(),printf("\n");
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    //printf("INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  void prep(int T,int64_t& L,int64_t& R){
    assert(L==R);
    struct End l(T+1,-1,L,current_time);
    struct End r(T-1,1,R,current_time);
    //printf("CHECKING FOR "),l.dump(),printf(" and "),r.dump(),printf("\n");
    if(ends.count(l)){
      if(R>ends.find(l)->a){
	R-=ends.find(l)->a;
	erase(*ends.find(l));
      }else{
	L=0,R=0;
      }
    }
    if(ends.count(r)){
      if(L>ends.find(r)->a){
	L-=ends.find(r)->a;
	erase(*ends.find(r));
      }else{
	L=0,R=0;
      }
    }
  }
  void insert_fish(int T,int A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    assert(l.a>0),assert(r.a>0);
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    //printf("CANCEL INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      //printf("INSERT CANCEL "),e.dump(),printf(" with "),e2.dump(),printf(" => "),cancel(e,e2).dump(),printf("\n");
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    //printf("ERASE "),e.dump(),printf("\n");
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    //printf("ANNIHILIATE "),c.dump(),printf(" => "),cancel(c.e1,c.e2).dump(),printf("\n");
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
    //dump();
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void ffwd_pre(int64_t t){
    while(collide.size()&&collide.begin()->time2<t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]-1);
    current_time=-depth[node]-1,dss[node].merge(dss[child]);
    //printf("MERGE %I64d into %I64d\n",child+1,node+1);
    //dss[node].dump();
  }
  //printf("BEFORE CLEANUP\n");
  current_time=-depth[node]-1;
  std::vector<int64_t> ls,rs;
  for(auto& f:fish[node]){
    ls.push_back(f.second);
    rs.push_back(f.second);
    dss[node].prep(f.first,ls.back(),rs.back());
  }
  //dss[node].dump();
  dss[node].ffwd(-depth[node]);
  current_time=-depth[node];
  //printf("BEFORE ADDING FISH\n");
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  current_time=-depth[node];
  for(int i=0;i<(int)fish[node].size();i++){
    current_time=-depth[node];
    //dss[node].insert_fish(D,F);
    //printf("ADDING %I64d,%I64d at %I64d\n",ls[i],rs[i],fish[node][i].first);
    dss[node].insert(End(fish[node][i].first,-1,ls[i],current_time));
    dss[node].insert(End(fish[node][i].first,1,rs[i],current_time));
    //dss[node].cancel_insert(End(D,1,F,current_time));
    //dss[node].cancel_insert(End(D,-1,F,current_time));
  }
  //printf("POST %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L*2);
    edges[V].emplace_back(U,L*2);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    D*=2;
    current_time=-depth[P];
    //dss[P].insert(End(D,1,F,current_time));
    //dss[P].insert(End(D,-1,F,current_time));
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  //printf("FINAL\n");
  //dss[0].dump();
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    //printf("(insertc) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("insertc "),c.dump(),printf("\n");
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    //printf("(erasec) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("erasec "),c.dump(),printf("\n");
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    //printf("INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  void insert_fish(int T,int A){
    struct End l(T,-1,A,current_time);
    struct End r(T,1,A,current_time);
    assert(!(ends.count(l)&&ends.count(r)));
    if(ends.count(l)){
      r.a-=ends.find(l)->a;
      erase(*ends.find(l));
    }
    if(ends.count(r)){
      l.a-=ends.find(r)->a;
      erase(*ends.find(r));
    }
    insert(l);
    insert(r);
  }
  void cancel_insert(struct End e){
    //printf("CANCEL INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      //printf("INSERT CANCEL "),e.dump(),printf(" with "),e2.dump(),printf(" => "),cancel(e,e2).dump(),printf("\n");
      erase(e2);
      insert(cancel(e,e2));
    }else{
      insert(e);
    }
  }
  void erase(struct End e){
    //printf("ERASE "),e.dump(),printf("\n");
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    //printf("ANNIHILIATE "),c.dump(),printf(" => "),cancel(c.e1,c.e2).dump(),printf("\n");
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
    //dump();
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      cancel_insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]);
    current_time=-depth[node],dss[node].merge(dss[child]);
    //printf("MERGE %I64d into %I64d\n",child+1,node+1);
    //dss[node].dump();
  }
  //printf("ADDING\n");
  for(auto f:fish[node]){
    int D=f.first,F=f.second;
    current_time=-depth[node];
    dss[node].insert_fish(D,F);
    //dss[node].cancel_insert(End(D,1,F,current_time));
    //dss[node].cancel_insert(End(D,-1,F,current_time));
  }
  //printf("POST %I64d:\n",node+1);
  //dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L);
    edges[V].emplace_back(U,L);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    current_time=-depth[P];
    //dss[P].insert(End(D,1,F,current_time));
    //dss[P].insert(End(D,-1,F,current_time));
    fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  //printf("FINAL\n");
  //dss[0].dump();
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <stdint.h>

const int64_t INF=2e9+7;

//Let time be -depth
int64_t current_time;

struct End{
  int64_t x,v;
  int64_t a;
  //At position x at time t
  End(int64_t x,int64_t v,int64_t a,int64_t t=0):x(x-v*t),v(v),a(a){
  }
  bool operator<(struct End other)const{
    int64_t xt=x+v*current_time;
    int64_t oxt=other.x+other.v*current_time;
    if(xt!=oxt) return xt<oxt;
    if(v!=other.v) return v<other.v;//make sure leftward is before rightward
    return false;//else equal
    //return id<other.id;//break ties arbitrarily
  }
  struct End operator-(){
    return End(x+v*current_time,-v,a,current_time);
  }
  void dump(){
    printf("%I64d[%I64d+%I64dt]",a,x+v*current_time,v);
  }
};

struct Collision{
  int64_t time2;
  struct End e1,e2;
  Collision(struct End e1,struct End e2):e1(e1),e2(e2){
    time2=(e1.x-e2.x)*2/(e2.v-e1.v);
  }
  bool operator<(const struct Collision& other)const{
    if(time2!=other.time2) return time2<other.time2;
    //arbitrarily break ties
    if(e1.x!=other.e1.x) return e1.x<other.e1.x;
    if(e1.v!=other.e1.v) return e1.x<other.e1.v;
    if(e1.a!=other.e1.a) return e1.x<other.e1.a;
    if(e2.x!=other.e2.x) return e2.x<other.e2.x;
    if(e2.v!=other.e2.v) return e2.x<other.e2.v;
    if(e2.a!=other.e2.a) return e2.x<other.e2.a;
    return false;
  }
  void dump(){
    e1.dump(),printf(">%I64d/2<",time2),e2.dump();
  }
};

struct DS{
  std::set<struct End> ends;
  std::set<struct Collision> collide;
  void insertc(struct End e1,struct End e2){
    //printf("(insertc) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("insertc "),c.dump(),printf("\n");
      assert(collide.insert(c).second);
    }
  }
  void erasec(struct End e1,struct End e2){
    //printf("(erasec) "),e1.dump(),printf(" "),e2.dump(),printf("\n");
    assert(e1<e2);
    if(e1.v>0&&e2.v<0){
      struct Collision c(e1,e2);
      //printf("erasec "),c.dump(),printf("\n");
      if(!collide.count(c)){
	printf("ERROR collision "),c.dump(),printf(" not found in\n");
	dump();
      }
      assert(collide.count(c));
      collide.erase(c);
    }
  }
  struct End cancel(struct End e1,struct End e2){
    if(e1.a>e2.a){
      return End(e1.x,e1.v,e1.a-e2.a);
    }else{
      return End(e2.x,e2.v,e2.a-e1.a);
    }
  }
  void insert(struct End e){
    //printf("INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(e)){
      e.a+=ends.find(e)->a;
      erase(*ends.find(e));
    }
    auto it=ends.insert(e).first;

    auto next=std::next(it);
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      if(next!=ends.end()){
	erasec(*prev,*next);
      }
      insertc(*prev,*it);
    }
    if(next!=ends.end()){
      insertc(*it,*next);
    }
  }
  void cancel_insert(struct End e){
    //printf("CANCEL INSERT"),e.dump(),printf("\n");
    if(e.a==0) return;
    if(ends.count(-e)){
      auto e2=*ends.find(-e);
      erase(e2);
      cancel_insert(cancel(e,e2));
      return;
    }
    insert(e);
  }
  void erase(struct End e){
    //printf("ERASE "),e.dump(),printf("\n");
    auto it=ends.find(e);
    assert(it!=ends.end());
    auto next=std::next(it);
    if(next!=ends.end()){
      erasec(*it,*next);
    }
    if(it!=ends.begin()){
      auto prev=std::prev(it);
      erasec(*prev,*it);
      if(next!=ends.end()){
	insertc(*prev,*next);
      }
    }
    ends.erase(e);
  }
  void annihilate(struct Collision c){
    //printf("ANNIHILIATE "),c.dump(),printf("\n");
    erase(c.e1);
    erase(c.e2);
    insert(cancel(c.e1,c.e2));
    //dump();
  }
  //Fast-forward to time t
  void ffwd(int64_t t){
    while(collide.size()&&collide.begin()->time2<=t*2){
      annihilate(*collide.begin());
    }
  }
  void swap(struct DS& other){
    std::swap(ends,other.ends);
    std::swap(collide,other.collide);
  }
  //other becomes invalidated
  void merge(struct DS& other){
    if(ends.size()<other.ends.size()){
      swap(other);
    }
    for(auto e:other.ends){
      cancel_insert(e);
    }
  }
  int64_t query(){
    int64_t ac=0;
    for(auto it:ends){
      if(it.v>0){
	ac+=it.a;
      }
    }
    return ac;
  }
  void dump(){
    printf("T=%I64d\n",current_time);
    for(auto e:ends){
      printf("FISH: "),e.dump(),printf("\n");
    }
    for(auto c:collide){
      printf("COLLISION :"),c.dump(),printf("\n");
    }
  }
};

std::vector<std::pair<int64_t,int64_t> > edges[100005];
//std::vector<std::pair<int64_t,int64_t> > fish[100005];

struct DS dss[100005];
int64_t depth[100005];

void dfs_depth(int64_t node,int64_t parent){
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    depth[child]=depth[node]+e.second;
    dfs_depth(child,node);
  }
}

void dfs_solve(int64_t node,int64_t parent){
  //printf("PRE %I64d:\n",node+1);
  current_time=-depth[node];
  //dss[node].dump();
  //printf("\n");
  for(auto e:edges[node]){
    int64_t child=e.first;
    if(child==parent) continue;
    dfs_solve(child,node);
    current_time=-depth[child],dss[child].ffwd(-depth[node]);
    current_time=-depth[node],dss[node].merge(dss[child]);
  }
  //printf("POST %I64d:\n",node+1);
  //dss[node].dump();
  //printf("\n");
}

int main(){
  int64_t N;
  scanf("%I64d",&N);
  for(int64_t i=0;i<N-1;i++){
    int64_t U,V,L;
    scanf("%I64d %I64d %I64d",&U,&V,&L);
    U--,V--;
    edges[U].emplace_back(V,L);
    edges[V].emplace_back(U,L);
  }
  dfs_depth(0,0);
  int64_t K;
  scanf("%I64d",&K);
  for(int64_t i=0;i<K;i++){
    int64_t D,F,P;
    scanf("%I64d %I64d %I64d",&D,&F,&P);
    P--;
    current_time=-depth[P];
    dss[P].insert(End(D,1,F,current_time));
    dss[P].insert(End(D,-1,F,current_time));
    //fish[P].emplace_back(D,F);
  }
  dfs_solve(0,0);
  current_time=-depth[0];
  dss[0].ffwd(INF);
  //printf("FINAL\n");
  //dss[0].dump();
  printf("%I64d\n",dss[0].query());
  return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

struct State {
	int delta;
	map<int,int> pos;
	map<int,int> neg;
	set<pair<int,pair<int,int>>> matches;

	void init() {
		delta=0; pos.clear(); neg.clear(); matches.clear();
	}

	int findmatchforpos(int x) {
		auto it=neg.lower_bound(x+delta);
		return it==neg.end()?INT_MAX:it->first-delta;
	}
	int findmatchforneg(int y) {
		auto it=pos.upper_bound(y-delta);
		return it==pos.begin()?INT_MIN:prev(it)->first+delta;
	}
	void erasepos(int x) {
		//printf("erasepos(%d)\n",x);
		assert(pos.erase(x-delta));
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx==INT_MIN||xx<=x) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(xx!=INT_MIN&&xx<=x) matches.insert(MP(y-xx+2*delta,MP(xx-delta,y+delta)));
		}
	}
	void eraseneg(int y) {
		//printf("eraseneg(%d)\n",y);
		assert(neg.erase(y+delta));
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy==INT_MAX||yy>=y) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(yy!=INT_MAX&&yy>=y) matches.insert(MP(yy-x+2*delta,MP(x-delta,yy+delta)));
		}
	}
	void insertpos(int x,int val) {
		//printf("insertpos(%d,%d)\n",x,val);
		if(pos.count(x-delta)) { pos[x-delta]+=val; return; }
		//if(neg.count(x+delta)) { int cur=neg[x+delta]; if(val<cur) { neg[x+delta]-=val; return; } eraseneg(x); val-=cur; if(val==0) return; }
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx!=INT_MIN&&xx<x) assert(matches.erase(MP(y-xx+2*delta,MP(xx-delta,y+delta))));
			if(xx==INT_MIN||xx<x) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		pos[x-delta]=val;
	}
	void insertneg(int y,int val) {
		//printf("insertneg(%d,%d)\n",y,val);
		if(neg.count(y+delta)) { neg[y+delta]+=val; return; }
		//if(pos.count(y-delta)) { int cur=pos[y-delta]; if(val<cur) { pos[y-delta]-=val; return; } erasepos(y); val-=cur; if(val==0) return; }
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy!=INT_MAX&&yy>y) assert(matches.erase(MP(yy-x+2*delta,MP(x-delta,yy+delta))));
			if(yy==INT_MAX||yy>y) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		neg[y+delta]=val;
	}
	void grow(int by) {
		//printf("growing(%d)\n",by);
		while(SZ(matches)!=0&&matches.begin()->first-2*delta<2*by) {
			int x=matches.begin()->second.first+delta,y=matches.begin()->second.second-delta;
			assert(pos.count(x-delta)); int xval=pos[x-delta]; assert(neg.count(y+delta)); int yval=neg[y+delta];
			if(xval<yval) { neg[y+delta]-=xval; erasepos(x); } else if(xval>yval) { pos[x-delta]-=yval; eraseneg(y); } else { erasepos(x); eraseneg(y); }
		}
		delta+=by;
	}
	void print() {
		printf("\tneg:"); for(auto it=neg.begin();it!=neg.end();++it) printf(" %d=%d",it->first-delta,it->second); puts("");
		printf("\tpos:"); for(auto it=pos.begin();it!=pos.end();++it) printf(" %d=%d",it->first+delta,it->second); puts("");
		printf("\tmatches:"); for(auto it=matches.begin();it!=matches.end();++it) printf(" %d:%d-%d",it->first-2*delta,it->second.first+delta,it->second.second-delta); puts("");
	}
};

const int MAXN=100000;

int n;
vector<pair<int,int>> e[MAXN];
int nq;
vector<pair<int,int>> obs[MAXN];

State state[MAXN];

int merge(int a,int b) {
	int asz=SZ(state[a].pos)+SZ(state[a].neg),bsz=SZ(state[b].pos)+SZ(state[b].neg);
	if(asz<bsz) swap(a,b),swap(asz,bsz);
	for(auto it=state[b].pos.begin();it!=state[b].pos.end();++it) state[a].insertpos(it->first+state[b].delta,it->second);
	for(auto it=state[b].neg.begin();it!=state[b].neg.end();++it) state[a].insertneg(it->first-state[b].delta,it->second);
	return a;
}

int dfs(int at,int par,int parlen) {
	int ret=at; state[ret].init();
	REPSZ(i,e[at]) {
		int to=e[at][i].first; if(to==par) continue;
		int cur=dfs(to,at,e[at][i].second);
		ret=merge(ret,cur);
	}
	vector<pair<int,int>> extra;
	REPSZ(i,obs[at]) {
		int t=obs[at][i].first,cnt=obs[at][i].second,rem=cnt;
		{ int cur=(state[ret].pos.count(t-state[ret].delta)?state[ret].pos[t-state[ret].delta]:0)+(state[ret].pos.count(t-state[ret].delta-1)?state[ret].pos[t-state[ret].delta-1]:0); rem=max(0,cnt-cur); }
		{ int cur=(state[ret].neg.count(t+state[ret].delta)?state[ret].neg[t+state[ret].delta]:0)+(state[ret].neg.count(t+state[ret].delta+1)?state[ret].neg[t+state[ret].delta+1]:0); rem=max(0,cnt-cur); }
		if(rem>0) extra.PB(MP(t,rem));
	}
	state[ret].grow(1);
	REPSZ(i,extra) { int t=extra[i].first,cnt=extra[i].second; state[ret].insertneg(t-1,cnt); state[ret].insertpos(t+1,cnt); }
	state[ret].grow(parlen-1);
	//printf("dfs(%d,%d,%d):\n",at+1,par==-1?-1:par+1,parlen); state[ret].print();
	return ret;
}

int solve() {
	REP(i,n) sort(obs[i].begin(),obs[i].end());
	int res=dfs(0,-1,1);
	map<int,int> all;
	for(auto it=state[res].pos.begin();it!=state[res].pos.end();++it) all[2*(it->first+state[res].delta)+0]-=it->second;
	for(auto it=state[res].neg.begin();it!=state[res].neg.end();++it) all[2*(it->first-state[res].delta)+1]+=it->second;
	int ret=0,cur=0;
	for(auto it=all.begin();it!=all.end();++it) {
		cur+=it->second;
		ret=max(ret,cur);
	}
	return ret;
}

void run() {
	scanf("%d",&n);
	REP(i,n-1) { int a,b,c; scanf("%d%d%d",&a,&b,&c); --a,--b; e[a].PB(MP(b,c)); e[b].PB(MP(a,c)); }
	scanf("%d",&nq);
	REP(i,nq) { int t,cnt,idx; scanf("%d%d%d",&t,&cnt,&idx); --idx; obs[idx].PB(MP(t,cnt)); }

	printf("%d\n",solve());
}

int main() {
	run();
	return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

struct State {
	int delta;
	map<int,int> pos;
	map<int,int> neg;
	set<pair<int,pair<int,int>>> matches;

	void init() {
		delta=0; pos.clear(); neg.clear(); matches.clear();
	}

	int findmatchforpos(int x) {
		auto it=neg.lower_bound(x+delta+1);
		return it==neg.end()?INT_MAX:it->first-delta;
	}
	int findmatchforneg(int y) {
		auto it=pos.upper_bound(y-delta-1);
		return it==pos.begin()?INT_MIN:prev(it)->first+delta;
	}
	void erasepos(int x) {
		//printf("erasepos(%d)\n",x);
		assert(pos.erase(x-delta));
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx==INT_MIN||xx<=x) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(xx!=INT_MIN&&xx<=x) matches.insert(MP(y-xx+2*delta,MP(xx-delta,y+delta)));
		}
	}
	void eraseneg(int y) {
		//printf("eraseneg(%d)\n",y);
		assert(neg.erase(y+delta));
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy==INT_MAX||yy>=y) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(yy!=INT_MAX&&yy>=y) matches.insert(MP(yy-x+2*delta,MP(x-delta,yy+delta)));
		}
	}
	void insertpos(int x,int val) {
		//printf("insertpos(%d,%d)\n",x,val);
		if(pos.count(x-delta)) { pos[x-delta]+=val; return; }
		//if(neg.count(x+delta)) { int cur=neg[x+delta]; if(val<cur) { neg[x+delta]-=val; return; } eraseneg(x); val-=cur; if(val==0) return; }
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx!=INT_MIN&&xx<x) assert(matches.erase(MP(y-xx+2*delta,MP(xx-delta,y+delta))));
			if(xx==INT_MIN||xx<x) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		pos[x-delta]=val;
	}
	void insertneg(int y,int val) {
		//printf("insertneg(%d,%d)\n",y,val);
		if(neg.count(y+delta)) { neg[y+delta]+=val; return; }
		//if(pos.count(y-delta)) { int cur=pos[y-delta]; if(val<cur) { pos[y-delta]-=val; return; } erasepos(y); val-=cur; if(val==0) return; }
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy!=INT_MAX&&yy>y) assert(matches.erase(MP(yy-x+2*delta,MP(x-delta,yy+delta))));
			if(yy==INT_MAX||yy>y) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		neg[y+delta]=val;
	}
	void grow(int by) {
		//printf("growing(%d)\n",by);
		while(SZ(matches)!=0&&matches.begin()->first-2*delta<2*by) {
			int x=matches.begin()->second.first+delta,y=matches.begin()->second.second-delta;
			assert(pos.count(x-delta)); int xval=pos[x-delta]; assert(neg.count(y+delta)); int yval=neg[y+delta];
			if(xval<yval) { neg[y+delta]-=xval; erasepos(x); } else if(xval>yval) { pos[x-delta]-=yval; eraseneg(y); } else { erasepos(x); eraseneg(y); }
		}
		delta+=by;
	}
	void print() {
		printf("\tneg:"); for(auto it=neg.begin();it!=neg.end();++it) printf(" %d=%d",it->first-delta,it->second); puts("");
		printf("\tpos:"); for(auto it=pos.begin();it!=pos.end();++it) printf(" %d=%d",it->first+delta,it->second); puts("");
		printf("\tmatches:"); for(auto it=matches.begin();it!=matches.end();++it) printf(" %d:%d-%d",it->first-2*delta,it->second.first+delta,it->second.second-delta); puts("");
	}
};

const int MAXN=100000;

int n;
vector<pair<int,int>> e[MAXN];
int nq;
vector<pair<int,int>> obs[MAXN];

State state[MAXN];

int merge(int a,int b) {
	int asz=SZ(state[a].pos)+SZ(state[a].neg),bsz=SZ(state[b].pos)+SZ(state[b].neg);
	if(asz<bsz) swap(a,b),swap(asz,bsz);
	for(auto it=state[b].pos.begin();it!=state[b].pos.end();++it) state[a].insertpos(it->first+state[b].delta,it->second);
	for(auto it=state[b].neg.begin();it!=state[b].neg.end();++it) state[a].insertneg(it->first-state[b].delta,it->second);
	return a;
}

int dfs(int at,int par,int parlen) {
	int ret=at; state[ret].init();
	REPSZ(i,e[at]) {
		int to=e[at][i].first; if(to==par) continue;
		int cur=dfs(to,at,e[at][i].second);
		ret=merge(ret,cur);
	}
	REPSZ(i,obs[at]) {
		int t=obs[at][i].first,cnt=obs[at][i].second,rem=cnt;
		if(state[ret].pos.count(t-state[ret].delta)) rem=max(0,cnt-state[ret].pos[t-state[ret].delta]);
		if(state[ret].neg.count(t+state[ret].delta)) rem=max(0,cnt-state[ret].neg[t+state[ret].delta]);
		if(rem>0) state[ret].insertpos(t,rem),state[ret].insertneg(t,rem);
	}
	state[ret].grow(parlen);
	//printf("dfs(%d,%d,%d):\n",at+1,par==-1?-1:par+1,parlen);
	//state[ret].print();
	return ret;
}

int solve() {
	REP(i,n) sort(obs[i].begin(),obs[i].end());
	int res=dfs(0,-1,0);
	map<int,int> all;
	for(auto it=state[res].pos.begin();it!=state[res].pos.end();++it) all[2*(it->first+state[res].delta)+0]-=it->second;
	for(auto it=state[res].neg.begin();it!=state[res].neg.end();++it) all[2*(it->first-state[res].delta)+1]+=it->second;
	int ret=0,cur=0;
	for(auto it=all.begin();it!=all.end();++it) {
		cur+=it->second;
		ret=max(ret,cur);
	}
	return ret;
}

void run() {
	scanf("%d",&n);
	REP(i,n-1) { int a,b,c; scanf("%d%d%d",&a,&b,&c); --a,--b; e[a].PB(MP(b,c)); e[b].PB(MP(a,c)); }
	scanf("%d",&nq);
	REP(i,nq) { int t,cnt,idx; scanf("%d%d%d",&t,&cnt,&idx); --idx; obs[idx].PB(MP(t,cnt)); }

	printf("%d\n",solve());
}

int main() {
	run();
	return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

struct State {
	int delta;
	map<int,int> pos;
	map<int,int> neg;
	set<pair<int,pair<int,int>>> matches;

	void init() {
		delta=0; pos.clear(); neg.clear(); matches.clear();
	}

	int findmatchforpos(int x) {
		auto it=neg.lower_bound(x+delta);
		return it==neg.end()?INT_MAX:it->first-delta;
	}
	int findmatchforneg(int y) {
		auto it=pos.upper_bound(y-delta);
		return it==pos.begin()?INT_MIN:prev(it)->first+delta;
	}
	void erasepos(int x) {
		//printf("erasepos(%d)\n",x);
		assert(pos.erase(x-delta));
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx==INT_MIN||xx<=x) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(xx!=INT_MIN&&xx<=x&&findmatchforpos(xx)==y) matches.insert(MP(y-xx+2*delta,MP(xx-delta,y+delta)));
		}
		//print();
	}
	void eraseneg(int y) {
		//printf("eraseneg(%d)\n",y);
		assert(neg.erase(y+delta));
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy==INT_MAX||yy>=y) assert(matches.erase(MP(y-x+2*delta,MP(x-delta,y+delta))));
			if(yy!=INT_MAX&&yy>=y&&findmatchforneg(yy)==x) matches.insert(MP(yy-x+2*delta,MP(x-delta,yy+delta)));
		}
		//print();
	}
	void insertpos(int x,int val) {
		//printf("insertpos(%d,%d)\n",x,val);
		if(pos.count(x-delta)) { pos[x-delta]+=val; return; }
		//if(neg.count(x+delta)) { int cur=neg[x+delta]; if(val<cur) { neg[x+delta]-=val; return; } eraseneg(x); val-=cur; if(val==0) return; }
		int y=findmatchforpos(x);
		if(y!=INT_MAX) {
			int xx=findmatchforneg(y);
			if(xx!=INT_MIN&&xx<x&&findmatchforpos(xx)==y) assert(matches.erase(MP(y-xx+2*delta,MP(xx-delta,y+delta))));
			if(xx==INT_MIN||xx<x) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		pos[x-delta]=val;
		//print();
	}
	void insertneg(int y,int val) {
		//printf("insertneg(%d,%d)\n",y,val);
		if(neg.count(y+delta)) { neg[y+delta]+=val; return; }
		//if(pos.count(y-delta)) { int cur=pos[y-delta]; if(val<cur) { pos[y-delta]-=val; return; } erasepos(y); val-=cur; if(val==0) return; }
		int x=findmatchforneg(y);
		if(x!=INT_MIN) {
			int yy=findmatchforpos(x);
			if(yy!=INT_MAX&&yy>y&&findmatchforneg(yy)==x) assert(matches.erase(MP(yy-x+2*delta,MP(x-delta,yy+delta))));
			if(yy==INT_MAX||yy>y) matches.insert(MP(y-x+2*delta,MP(x-delta,y+delta)));
		}
		neg[y+delta]=val;
		//print();
	}
	void grow(int by) {
		//printf("growing(%d)\n",by); print();
		while(SZ(matches)!=0&&matches.begin()->first-2*delta<2*by) {
			int x=matches.begin()->second.first+delta,y=matches.begin()->second.second-delta;
			//printf("x=%d y=%d\n",x,y); print();
			assert(pos.count(x-delta)); int xval=pos[x-delta]; assert(neg.count(y+delta)); int yval=neg[y+delta];
			if(xval<yval) { neg[y+delta]-=xval; erasepos(x); } else if(xval>yval) { pos[x-delta]-=yval; eraseneg(y); } else { erasepos(x); eraseneg(y); }
		}
		delta+=by;
	}
	void print() {
		printf("\tneg:"); for(auto it=neg.begin();it!=neg.end();++it) printf(" %d=%d",it->first-delta,it->second); puts("");
		printf("\tpos:"); for(auto it=pos.begin();it!=pos.end();++it) printf(" %d=%d",it->first+delta,it->second); puts("");
		printf("\tmatches:"); for(auto it=matches.begin();it!=matches.end();++it) printf(" %d:%d-%d",it->first-2*delta,it->second.first+delta,it->second.second-delta); puts("");
	}
};

const int MAXN=100000;

int n;
vector<pair<int,int>> e[MAXN];
int nq;
vector<pair<int,int>> obs[MAXN];

State state[MAXN];

int merge(int a,int b) {
	int asz=SZ(state[a].pos)+SZ(state[a].neg),bsz=SZ(state[b].pos)+SZ(state[b].neg);
	if(asz<bsz) swap(a,b),swap(asz,bsz);
	for(auto it=state[b].pos.begin();it!=state[b].pos.end();++it) state[a].insertpos(it->first+state[b].delta,it->second);
	for(auto it=state[b].neg.begin();it!=state[b].neg.end();++it) state[a].insertneg(it->first-state[b].delta,it->second);
	return a;
}

int dfs(int at,int par,int parlen) {
	int ret=at; state[ret].init();
	REPSZ(i,e[at]) {
		int to=e[at][i].first; if(to==par) continue;
		int cur=dfs(to,at,e[at][i].second);
		ret=merge(ret,cur);
	}
	vector<pair<int,int>> extra;
	REPSZ(i,obs[at]) {
		int t=obs[at][i].first,cnt=obs[at][i].second,rem=cnt;
		{ int cur=(state[ret].pos.count(t-state[ret].delta)?state[ret].pos[t-state[ret].delta]:0)+(state[ret].pos.count(t-state[ret].delta-1)?state[ret].pos[t-state[ret].delta-1]:0); rem=max(0,cnt-cur); }
		{ int cur=(state[ret].neg.count(t+state[ret].delta)?state[ret].neg[t+state[ret].delta]:0)+(state[ret].neg.count(t+state[ret].delta+1)?state[ret].neg[t+state[ret].delta+1]:0); rem=max(0,cnt-cur); }
		if(rem>0) extra.PB(MP(t,rem));
	}
	state[ret].grow(1);
	REPSZ(i,extra) { int t=extra[i].first,cnt=extra[i].second; state[ret].insertneg(t-1,cnt); state[ret].insertpos(t+1,cnt); }
	state[ret].grow(parlen-1);
	//printf("dfs(%d,%d,%d):\n",at+1,par==-1?-1:par+1,parlen); state[ret].print();
	return ret;
}

int solve() {
	REP(i,n) sort(obs[i].begin(),obs[i].end());
	int res=dfs(0,-1,1);
	map<int,int> all;
	for(auto it=state[res].pos.begin();it!=state[res].pos.end();++it) all[2*(it->first+state[res].delta)+0]-=it->second;
	for(auto it=state[res].neg.begin();it!=state[res].neg.end();++it) all[2*(it->first-state[res].delta)+1]+=it->second;
	int ret=0,cur=0;
	for(auto it=all.begin();it!=all.end();++it) {
		cur+=it->second;
		ret=max(ret,cur);
	}
	return ret;
}

void run() {
	scanf("%d",&n);
	REP(i,n-1) { int a,b,c; scanf("%d%d%d",&a,&b,&c); --a,--b,c*=2; e[a].PB(MP(b,c)); e[b].PB(MP(a,c)); }
	scanf("%d",&nq);
	REP(i,nq) { int t,cnt,idx; scanf("%d%d%d",&t,&cnt,&idx); t*=2; --idx; obs[idx].PB(MP(t,cnt)); }

	printf("%d\n",solve());
}

int main() {
	run();
	return 0;
}

//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define bged(v) (v).begin(),(v).end()
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#ifndef LOCAL
#define cerr if(0)cout
#endif
typedef long long ll;
const int Imx=2147483647;
const ll Lbig=2e18;
const int mod=1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it,len;
	fastio(){it=len=0;}
	inline char get()
	{
		if(it<len)return s[it++];it=0;
		len=fread(s,1,100000,stdin);
		if(len==0)return EOF;else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while(c==' '||c=='\n')c=get();
		if(it>0)it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0;bool ng=0;char c;c=_buff.get();
	while(c!='-'&&(c<'0'||c>'9'))c=_buff.get();
	if(c=='-')ng=1,c=_buff.get();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=_buff.get();
	return ng?-r:r;
}
template<class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline char getreal(){char c=_buff.get();while(c<=32)c=_buff.get();return c;}
ll qpow(ll x,ll k){return k==0?1:1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;}
const int maxn=100111;
int CURT;
struct Function
{
	#define Qv(M,x) ((M).find(x)==(M).end()?0:M[x])
	int T;
	struct element
	{
		int x,v;
		element(int X=0,int V=0){x=X;v=V;}
		inline int getT()const{return v>0?x-CURT:x+CURT;}
		bool operator<(const element &t)const
		{
			if(getT()!=t.getT())return getT()<t.getT();
			return v<t.v;
		}
	};
	void UPDT(){CURT=T;}
	unordered_map<int,int> M[2];//0-negative 1-positive
	set<element> all;
	set<pair<int,pair<int,int> > > st;
	void debug(int id)
	{
		UPDT();
		cerr<<"Debug "<<id<<" T="<<T<<endl;
		for(set<element>::iterator it=all.begin();it!=all.end();it++)cerr<<it->getT()<<","<<it->v<<" ";cerr<<endl;
		for(auto it:M[0])cerr<<it.FF<<","<<it.SS<<" ";cerr<<endl;
		for(auto it:M[1])cerr<<it.FF<<","<<it.SS<<" ";cerr<<endl;
	}
	void add_relation(int x,int y)
	{
		int t=(y-x+1)/2;
		assert(t>0);
		st.insert(MP(t,MP(x,y)));
	}
	void all_insert(element x)
	{
		if(x.v==0)return;
		UPDT();
		all.insert(x);
		set<element>::iterator it=all.find(x);
		if(x.v>0&&it!=all.begin())
		{
			it--;
			if(it->v<0)add_relation(it->x,x.x);
		}
		else if(x.v<0)
		{
			it++;
			if(it!=all.end()&&it->v>0)add_relation(x.x,it->x);
		}
	}
	void all_del(element x)
	{
		if(x.v==0)return;
		UPDT();
		set<element>::iterator it=all.find(x),it0=it,it1=it0;
		assert(it!=all.end());
		it1++;
		if(it0!=all.begin()&&it1!=all.end())
		{
			it0--;
			if(it0->v<0&&it1->v>0)add_relation(it0->x,it1->x);
		}
		all.erase(x);
	}
	void add(int t,int p,int v)
	{
		if(v==0)return;
		int cur=0;
		if(M[t].find(p)!=M[t].end())all_del(element(p,M[t][p])),cur=M[t][p];
		M[t][p]=cur+v;
		all_insert(element(p,M[t][p]));
	}
	void Add(int x,int v)
	{
		if(v==0)return;
		int t=v>0,p,q;
		if(t)p=x+T,q=x-T;else p=x-T,q=x+T;
		int qval=Qv(M[t^1],q);
		if(qval)
		{
			if(abs(qval)>=abs(v))add(t^1,q,v),v=0;
			else add(t^1,q,-qval),v+=qval;
		}
		add(t,p,v);
		assert((Qv(M[t],p)!=0)+(Qv(M[t^1],q)!=0)<=1);
	}

	void merge(int x,int y)
	{
		if(M[0].find(x)!=M[0].end()&&M[1].find(y)!=M[1].end())
		{
			int dlt=min(-M[0][x],M[1][y]);
			assert(dlt>=0);
			add(0,x,dlt);
			add(1,y,-dlt);
		}
	}
	void go(int dt)
	{
		int nT=T+dt;
		while(st.size()>0&&st.begin()->FF<=nT)
		{
			merge(st.begin()->SS.FF,st.begin()->SS.SS);
			st.erase(st.begin());
		}
		T=nT;
	}
	int getmx()
	{
		UPDT();
		int v=0,mx=0;
		for(set<element>::iterator it=all.begin();it!=all.end();it++)
		{
			v+=it->v;
			mx=max(mx,v);
		}
		return mx;
	}
	int getdlt(int x)
	{
		return Qv(M[0],x-T)+Qv(M[1],x+T);
	}
	int getndlt(int x,int f)
	{
		int d0=getdlt(x);
		int d1=getdlt(x+1);
		return max(0,f-max(0,max(0-d0,d1)));
	}
}yxg[maxn*2];
int tot;
int Merge(int x,int y)
{
	if(yxg[x].all.size()>yxg[y].all.size())return Merge(y,x);
//	cerr<<"======Merge:"<<endl;
//	yxg[x].debug(x);
//	yxg[y].debug(y);
//	cerr<<"------------"<<endl;
	for(set<Function::element>::iterator it=yxg[x].all.begin();it!=yxg[x].all.end();it++)
	{
		yxg[y].Add(it->getT(),it->v);
	}
//	yxg[y].debug(y);
//	cerr<<"==========="<<endl;
	return y;
}
int n,m;
vector<pair<int,int> > con[maxn];
vector<pair<int,int> > v[maxn];
int id[maxn];
void dfs(int x,int pre=-1)
{
//	cerr<<"dfs:"<<x<<endl;
	id[x]=0;
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i].FF;
		if(u==pre)continue;
		dfs(u,x);
		yxg[id[u]].go(con[x][i].SS*2-1);
		if(id[x]==0)id[x]=id[u];
		else id[x]=Merge(id[x],id[u]);
	}
	if(id[x]==0)id[x]=++tot;
	if(x!=1)
	{
		vector<int> V;
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			V.PB(yxg[id[x]].getndlt(d*2,f));
//			cerr<<"ndlt="<<yxg[id[x]].getndlt(d*2,f)<<endl;
		}
		yxg[id[x]].go(1);
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			yxg[id[x]].Add(d*2,V[i]);
			yxg[id[x]].Add(d*2+1,-V[i]);
		}
	}
	else
	{
		for(int i=0;i<v[x].size();i++)
		{
			int d=v[x][i].FF;
			int f=v[x][i].SS;
			yxg[id[x]].Add(d*2,f);
			yxg[id[x]].Add(d*2+1,-f);
		}
	}
//	cerr<<"_____________"<<x<<" "<<yxg[id[x]].getmx()<<endl;
//	yxg[id[x]].debug(x);
}
int main()
{
	geti(n);
	for(int i=1;i<n;i++)
	{
		int x,y,d;
		getiii(x,y,d);
		con[x].PB(MP(y,d));
		con[y].PB(MP(x,d));
	}
	geti(m);
	for(int i=1;i<=m;i++)
	{
		int d,f,p;
		getiii(d,f,p);
		v[p].PB(MP(d,f));
	}
	dfs(1);
	int ans=yxg[id[1]].getmx();
	cout<<ans<<endl;
	return 0;
}