#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 <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<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 <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 <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;
}

#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>
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>
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;
}

//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;
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;
#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;
}

 #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
*/

/*
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;
}