#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 3e5 + 11;
const LL inf = 1e16;
int n, m, tot;
int head[N], to[N<<1], nex[N<<1], size;
int id[N], L[N], R[N];
LL c[N], f[N];
vector<int> st[N], ed[N];
struct seg{
#define ls (p << 1)
#define rs (p << 1 | 1)
	LL t[N<<2], tag[N<<2];
	void add_tag(int p, LL c){
		tag[p] += c;
		t[p] += c;
	}
	void push_down(int p){
		if(!tag[p])return ;
		add_tag(ls, tag[p]);
		add_tag(rs, tag[p]);
		tag[p] = 0;
 	}
	void build(int p, int l, int r){
		if(l == r){
			t[p] = 1e16;
			return ;
		}
		int mid = l + r >> 1;
		build(ls, l, mid); build(rs, mid + 1, r);
		t[p] = min(t[ls], t[rs]);
	}
	void modify(int p, int l, int r, int x, LL c){
		if(l > x || r < x)return ;
		if(l == r && l == x){
			t[p] = c;
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		modify(ls, l, mid, x, c);
		modify(rs, mid + 1, r, x, c);
		t[p] = min(t[ls], t[rs]);
	}
	void add(int p, int l, int r, int x, int y, LL c){
		if(l > y || r < x)return ;
		if(l >= x && r <= y){
			add_tag(p, c);
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		add(ls, l, mid, x, y, c);
		add(rs, mid + 1, r, x, y, c);
		t[p] = min(t[ls], t[rs]);
	}
	LL query(int p, int l, int r, int x, int y){
		if(l > y || r < x)return inf;
		if(l >= x && r <= y){
			return t[p];
		}
		push_down(p);
		int mid = l + r >> 1;
		return min(query(ls, l, mid, x, y), query(rs, mid + 1, r, x, y));
	}
#undef ls
#undef rs
}T;
void dfs(int u, int fa){
	L[u] = m + 1;
	for(int i = 0;i < st[u].size(); i++){
		id[st[u][i]] = ++tot;
		L[u] = min(L[u], tot);
		R[u] = max(R[u], tot);
	}
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dfs(v, u);
		L[u] = min(L[u], L[v]);
		R[u] = max(R[u], R[v]);
	}
//	printf("u=%d L=%d R=%d\n", u, L[u], R[u]);
	if(L[u] == m + 1 || !R[u]){
		puts("-1");
		exit(0);
	}
}
void dp(int u, int fa){
	LL sum = 0;
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dp(v, u);
		sum += f[v];
	}
	for(int i = 0;i < st[u].size(); i++){
		T.modify(1, 1, n, id[st[u][i]], c[st[u][i]]);
	}
	T.add(1, 1, n, L[u], R[u], sum);
	for(int i = 0;i < ed[u].size(); i++){
		int now = ed[u][i];
		T.modify(1, 1, n, id[now], 1e16);
	}
	if(u != 1)f[u] = T.query(1, 1, n, L[u], R[u]);
	else f[u] = sum;
	T.add(1, 1, n, L[u], R[u], -f[u]);
}
void add(int u, int v){
	to[++size] = v;
	nex[size] = head[u];
	head[u] = size;
}
int main(){
	cin>>n>>m;
	int u, v;
	for(int i = 1;i < n; i++){
		scanf("%d%d", &u, &v);
		add(u, v); add(v, u);
	}
	for(int i = 1;i <= m; i++){
		scanf("%d%d%lld", &u, &v, &c[i]);
		st[u].push_back(i);
		ed[v].push_back(i);
	}
	dfs(1, 1);
	T.build(1, 1, m);
	dp(1, 1);
	if(f[1] < inf)printf("%lld\n", f[1]);
	else puts("-1");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 3e5 + 11;
const LL inf = 1e16;
int n, m, tot;
int head[N], to[N<<1], nex[N<<1], size;
int id[N], f[N], L[N], R[N];
LL c[N];
vector<int> st[N], ed[N];
struct seg{
#define ls (p << 1)
#define rs (p << 1 | 1)
	LL t[N<<2], tag[N<<2];
	void add_tag(int p, LL c){
		tag[p] += c;
		t[p] += c;
	}
	void push_down(int p){
		if(!tag[p])return ;
		add_tag(ls, tag[p]);
		add_tag(rs, tag[p]);
		tag[p] = 0;
 	}
	void build(int p, int l, int r){
		if(l == r){
			t[p] = 1e16;
			return ;
		}
		int mid = l + r >> 1;
		build(ls, l, mid); build(rs, mid + 1, r);
		t[p] = min(t[ls], t[rs]);
	}
	void modify(int p, int l, int r, int x, LL c){
		if(l > x || r < x)return ;
		if(l == r && l == x){
			t[p] = c;
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		modify(ls, l, mid, x, c);
		modify(rs, mid + 1, r, x, c);
		t[p] = min(t[ls], t[rs]);
	}
	void add(int p, int l, int r, int x, int y, LL c){
		if(l > y || r < x)return ;
		if(l >= x && r <= y){
			add_tag(p, c);
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		add(ls, l, mid, x, y, c);
		add(rs, mid + 1, r, x, y, c);
		t[p] = min(t[ls], t[rs]);
	}
	LL query(int p, int l, int r, int x, int y){
		if(l > y || r < x)return inf;
		if(l >= x && r <= y){
			return t[p];
		}
		push_down(p);
		int mid = l + r >> 1;
		return min(query(ls, l, mid, x, y), query(rs, mid + 1, r, x, y));
	}
#undef ls
#undef rs
}T;
void dfs(int u, int fa){
	L[u] = m + 1;
	for(int i = 0;i < st[u].size(); i++){
		id[st[u][i]] = ++tot;
		L[u] = min(L[u], tot);
		R[u] = max(R[u], tot);
	}
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dfs(v, u);
		L[u] = min(L[u], L[v]);
		R[u] = max(R[u], R[v]);
	}
//	printf("u=%d L=%d R=%d\n", u, L[u], R[u]);
	if(L[u] == m + 1 || !R[u]){
		puts("-1");
		exit(0);
	}
}
void dp(int u, int fa){
	LL sum = 0;
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dp(v, u);
		sum += f[v];
	}
	for(int i = 0;i < st[u].size(); i++){
		T.modify(1, 1, n, id[st[u][i]], c[st[u][i]]);
	}
	T.add(1, 1, n, L[u], R[u], sum);
	for(int i = 0;i < ed[u].size(); i++){
		int now = ed[u][i];
		T.modify(1, 1, n, id[now], 1e16);
	}
	if(u != 1)f[u] = T.query(1, 1, n, L[u], R[u]);
	else f[u] = sum;
	T.add(1, 1, n, L[u], R[u], -f[u]);
}
void add(int u, int v){
	to[++size] = v;
	nex[size] = head[u];
	head[u] = size;
}
int main(){
	cin>>n>>m;
	int u, v;
	for(int i = 1;i < n; i++){
		scanf("%d%d", &u, &v);
		add(u, v); add(v, u);
	}
	for(int i = 1;i <= m; i++){
		scanf("%d%d%lld", &u, &v, &c[i]);
		st[u].push_back(i);
		ed[v].push_back(i);
	}
	dfs(1, 1);
	T.build(1, 1, m);
	dp(1, 1);
	if(f[1] < inf)printf("%lld\n", f[1]);
	else puts("-1");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 3e5 + 11;
const LL inf = 1e16;
int n, m, tot;
int head[N], to[N<<1], nex[N<<1], size;
int id[N], L[N], R[N];
LL c[N], f[N];
vector<int> st[N], ed[N];
struct seg{
#define ls (p << 1)
#define rs (p << 1 | 1)
	LL t[N<<2], tag[N<<2];
	void add_tag(int p, LL c){
		tag[p] += c;
		t[p] += c;
	}
	void push_down(int p){
		if(!tag[p])return ;
		add_tag(ls, tag[p]);
		add_tag(rs, tag[p]);
		tag[p] = 0;
 	}
	void build(int p, int l, int r){
		if(l == r){
			t[p] = 1e16;
			return ;
		}
		int mid = l + r >> 1;
		build(ls, l, mid); build(rs, mid + 1, r);
		t[p] = min(t[ls], t[rs]);
	}
	void modify(int p, int l, int r, int x, LL c){
		if(l > x || r < x)return ;
		if(l == r && l == x){
			t[p] = c;
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		modify(ls, l, mid, x, c);
		modify(rs, mid + 1, r, x, c);
		t[p] = min(t[ls], t[rs]);
	}
	void add(int p, int l, int r, int x, int y, LL c){
		if(l > y || r < x)return ;
		if(l >= x && r <= y){
			add_tag(p, c);
			return ;
		}
		push_down(p);
		int mid = l + r >> 1;
		add(ls, l, mid, x, y, c);
		add(rs, mid + 1, r, x, y, c);
		t[p] = min(t[ls], t[rs]);
	}
	LL query(int p, int l, int r, int x, int y){
		if(l > y || r < x)return inf;
		if(l >= x && r <= y){
			return t[p];
		}
		push_down(p);
		int mid = l + r >> 1;
		return min(query(ls, l, mid, x, y), query(rs, mid + 1, r, x, y));
	}
#undef ls
#undef rs
}T;
void dfs(int u, int fa){
	L[u] = m + 1;
	for(int i = 0;i < st[u].size(); i++){
		id[st[u][i]] = ++tot;
		L[u] = min(L[u], tot);
		R[u] = max(R[u], tot);
	}
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dfs(v, u);
		L[u] = min(L[u], L[v]);
		R[u] = max(R[u], R[v]);
	}
	if(L[u] == m + 1 || !R[u]){
		puts("-1");
		exit(0);
	}
}
void dp(int u, int fa){
	LL sum = 0;
	for(int i = head[u];i;i = nex[i]){
		int v = to[i];
		if(v == fa)continue;
		dp(v, u);
		sum += f[v];
	}
	for(int i = 0;i < st[u].size(); i++){
		int now = st[u][i];
		T.modify(1, 1, m, id[st[u][i]], c[st[u][i]]);
	}
	T.add(1, 1, m, L[u], R[u], sum);
	for(int i = 0;i < ed[u].size(); i++){
		int now = ed[u][i];
		T.modify(1, 1, m, id[now], 1e16);
	}
	if(u != 1)f[u] = T.query(1, 1, m, L[u], R[u]);
	else f[u] = sum;
	T.add(1, 1, m, L[u], R[u], -f[u]);
}
void add(int u, int v){
	to[++size] = v;
	nex[size] = head[u];
	head[u] = size;
}
int main(){
	cin>>n>>m;
	if(n == 1){
		puts("0");
		return 0;
	}
	int u, v;
	for(int i = 1;i < n; i++){
		scanf("%d%d", &u, &v);
		add(u, v); add(v, u);
	}
	for(int i = 1;i <= m; i++){
		scanf("%d%d%lld", &u, &v, &c[i]);
		if(u == v){
			i--, m--;
			continue;
		}
		st[u].push_back(i);
		ed[v].push_back(i);
	}
	dfs(1, 1);
	T.build(1, 1, m);
	dp(1, 1);
	if(f[1] < inf)printf("%lld\n", f[1]);
	else puts("-1");
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;
#define MN 300010
#define ll long long
struct SJd
{
	ll z;int s;
	SJd(){}
	SJd(ll Z,int S)
	{
		z=Z;s=S;
	}
};
bool operator>(const SJd &a,const SJd &b)
{
	return a.z>b.z;
}
void operator+=(SJd &a,ll x)
{
	a.z+=x;
}
int cl[MN],cr[MN],jl[MN],sl=0;SJd sz[MN];ll ld[MN];
void pur(int x,ll y)
{
	sz[x]+=y;
	ld[x]+=y;
}
void pushd(int x)
{
	if(ld[x]==0)
		return;
	if(cl[x])
		pur(cl[x],ld[x]);
	if(cr[x])
		pur(cr[x],ld[x]);
	ld[x]=0;
}
void swap(int &a,int &b)
{
	int t=a;a=b;b=t;
}
int merge(int x,int y)
{
	pushd(x);pushd(y);
	if(x==0||y==0)
		return x+y;
	if(sz[x]>sz[y])
		swap(x,y);
	cr[x]=merge(cr[x],y);
	if(jl[cl[x]]<jl[cr[x]])
		swap(cl[x],cr[x]);
	jl[x]=jl[cr[x]]+1;
	return x;
}
int delmin(int x)
{
	return merge(cl[x],cr[x]);
}
int fr[300010],ne[600010],v[600010],sd[300010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int mer(int x,int y)
{
	if(x==0||y==0)
		return x+y;
	ll t=sz[x].z;
	pur(x,sz[y].z);
	pur(y,t);
	return merge(x,y);
}
int insert(int x,SJd t)
{
	sz[++sl]=t;
	return merge(x,sl);
}
int X[300010],Y[300010],Z[300010];
vector<int> ve[300010];
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	int ro=0;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		int rt=dfs(v[i],u);
		if(rt==0)return 0;
		while(rt&&sz[rt].s>sd[u])
			rt=delmin(rt);
		ro=mer(ro,rt);
	}
	int yz=sz[ro].z;
	for(int i=0;i<ve[u].size();i++)
	{
		int t=ve[u][i];
		ro=insert(ro,SJd(yz+Z[t],sd[Y[t]]));
	}
	return ro;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);addb(b,a);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		if(X[i]!=Y[i])
			ve[X[i]].push_back(i);
	}
	int rt=dfs(1,0);
	if(rt==0)
		printf("-1");
	else
		printf("%lld",sz[rt].z);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;
#define MN 300010
#define ll long long
struct SJd
{
	ll z;int s;
	SJd(){}
	SJd(ll Z,int S)
	{
		z=Z;s=S;
	}
};
bool operator>(const SJd &a,const SJd &b)
{
	return a.z>b.z;
}
void operator+=(SJd &a,ll x)
{
	a.z+=x;
}
int cl[MN],cr[MN],jl[MN],sl=0;SJd sz[MN];ll ld[MN];
void pur(int x,ll y)
{
	sz[x]+=y;
	ld[x]+=y;
}
void pushd(int x)
{
	if(ld[x]==0)
		return;
	if(cl[x])
		pur(cl[x],ld[x]);
	if(cr[x])
		pur(cr[x],ld[x]);
	ld[x]=0;
}
void swap(int &a,int &b)
{
	int t=a;a=b;b=t;
}
int merge(int x,int y)
{
	pushd(x);pushd(y);
	if(x==0||y==0)
		return x+y;
	if(sz[x]>sz[y])
		swap(x,y);
	cr[x]=merge(cr[x],y);
	if(jl[cl[x]]<jl[cr[x]])
		swap(cl[x],cr[x]);
	jl[x]=jl[cr[x]]+1;
	return x;
}
int delmin(int x)
{
	return merge(cl[x],cr[x]);
}
int fr[300010],ne[600010],v[600010],sd[300010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int mer(int x,int y)
{
	if(x==0||y==0)
		return x+y;
	ll t=sz[x].z;
	pur(x,sz[y].z);
	pur(y,t);
	return merge(x,y);
}
int insert(int x,SJd t)
{
	sz[++sl]=t;
	return merge(x,sl);
}
int X[300010],Y[300010],Z[300010];
vector<int> ve[300010];
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	int ro=0;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		int rt=dfs(v[i],u);
		if(rt==0)return 0;
		while(rt&&sz[rt].s>sd[u])
			rt=delmin(rt);
		ro=mer(ro,rt);
	}
	ll yz=sz[ro].z;
	for(int i=0;i<ve[u].size();i++)
	{
		int t=ve[u][i];
		ro=insert(ro,SJd(yz+Z[t],sd[Y[t]]));
	}
	return ro;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	if(n==1)
	{
		printf("0");
		return 0;
	}
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);addb(b,a);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		if(X[i]!=Y[i])
			ve[X[i]].push_back(i);
	}
	int rt=dfs(1,0);
	if(rt==0)
		printf("-1");
	else
		printf("%lld",sz[rt].z);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;
#define MN 300010
#define ll long long
struct SJd
{
	ll z;int s;
	SJd(){}
	SJd(ll Z,int S)
	{
		z=Z;s=S;
	}
};
bool operator>(const SJd &a,const SJd &b)
{
	return a.z>b.z;
}
void operator+=(SJd &a,ll x)
{
	a.z+=x;
}
int cl[MN],cr[MN],jl[MN],sl=0;SJd sz[MN];ll ld[MN];
void pur(int x,ll y)
{
	sz[x]+=y;
	ld[x]+=y;
}
void pushd(int x)
{
	if(ld[x]==0)
		return;
	if(cl[x])
		pur(cl[x],ld[x]);
	if(cr[x])
		pur(cr[x],ld[x]);
	ld[x]=0;
}
void swap(int &a,int &b)
{
	int t=a;a=b;b=t;
}
int merge(int x,int y)
{
	pushd(x);pushd(y);
	if(x==0||y==0)
		return x+y;
	if(sz[x]>sz[y])
		swap(x,y);
	cr[x]=merge(cr[x],y);
	if(jl[cl[x]]<jl[cr[x]])
		swap(cl[x],cr[x]);
	jl[x]=jl[cr[x]]+1;
	return x;
}
int delmin(int x)
{
	return merge(cl[x],cr[x]);
}
int fr[300010],ne[600010],v[600010],sd[300010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int mer(int x,int y)
{
	if(x==0||y==0)
		return x+y;
	ll t=sz[x].z;
	pur(x,sz[y].z);
	pur(y,t);
	return merge(x,y);
}
int insert(int x,SJd t)
{
	sz[++sl]=t;
	return merge(x,sl);
}
int X[300010],Y[300010],Z[300010];
vector<int> ve[300010];
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	int ro=0;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		int rt=dfs(v[i],u);
		while(rt&&sz[rt].s>sd[u])
			rt=delmin(rt);
		ro=mer(ro,rt);
	}
	for(int i=0;i<ve[u].size();i++)
	{
		int t=ve[u][i];
		ro=insert(ro,SJd(sz[ro].z+Z[t],sd[Y[t]]));
	}
	return ro;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);addb(b,a);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		ve[X[i]].push_back(i);
	}
	int rt=dfs(1,0);
	printf("%lld",sz[rt].z);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;
#define MN 300010
#define ll long long
struct SJd
{
	ll z;int s;
	SJd(){}
	SJd(ll Z,int S)
	{
		z=Z;s=S;
	}
};
bool operator>(const SJd &a,const SJd &b)
{
	return a.z>b.z;
}
void operator+=(SJd &a,ll x)
{
	a.z+=x;
}
int cl[MN],cr[MN],jl[MN],sl=0;SJd sz[MN];ll ld[MN];
void pur(int x,ll y)
{
	sz[x]+=y;
	ld[x]+=y;
}
void pushd(int x)
{
	if(ld[x]==0)
		return;
	if(cl[x])
		pur(cl[x],ld[x]);
	if(cr[x])
		pur(cr[x],ld[x]);
	ld[x]=0;
}
void swap(int &a,int &b)
{
	int t=a;a=b;b=t;
}
int merge(int x,int y)
{
	pushd(x);pushd(y);
	if(x==0||y==0)
		return x+y;
	if(sz[x]>sz[y])
		swap(x,y);
	cr[x]=merge(cr[x],y);
	if(jl[cl[x]]<jl[cr[x]])
		swap(cl[x],cr[x]);
	jl[x]=jl[cr[x]]+1;
	return x;
}
int delmin(int x)
{
	return merge(cl[x],cr[x]);
}
int fr[300010],ne[600010],v[600010],sd[300010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int mer(int x,int y)
{
	if(x==0||y==0)
		return x+y;
	ll t=sz[x].z;
	pur(x,sz[y].z);
	pur(y,t);
	return merge(x,y);
}
int insert(int x,SJd t)
{
	sz[++sl]=t;
	return merge(x,sl);
}
int X[300010],Y[300010],Z[300010];
vector<int> ve[300010];
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	int ro=0;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		int rt=dfs(v[i],u);
		if(rt==0)return 0;
		while(rt&&sz[rt].s>sd[u])
			rt=delmin(rt);
		ro=mer(ro,rt);
	}
	ll yz=sz[ro].z;
	for(int i=0;i<ve[u].size();i++)
	{
		int t=ve[u][i];
		ro=insert(ro,SJd(yz+Z[t],sd[Y[t]]));
	}
	return ro;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);addb(b,a);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		if(X[i]!=Y[i])
			ve[X[i]].push_back(i);
	}
	int rt=dfs(1,0);
	if(rt==0)
		printf("-1");
	else
		printf("%lld",sz[rt].z);
	return 0;
}


#include <stdio.h>
#include <vector>
using namespace std;
#define MN 300010
#define ll long long
struct SJd
{
	ll z;int s;
	SJd(){}
	SJd(ll Z,int S)
	{
		z=Z;s=S;
	}
};
bool operator>(const SJd &a,const SJd &b)
{
	return a.z>b.z;
}
void operator+=(SJd &a,ll x)
{
	a.z+=x;
}
int cl[MN],cr[MN],jl[MN],sl=0;SJd sz[MN];ll ld[MN];
void pur(int x,ll y)
{
	sz[x]+=y;
	ld[x]+=y;
}
void pushd(int x)
{
	if(ld[x]==0)
		return;
	if(cl[x])
		pur(cl[x],ld[x]);
	if(cr[x])
		pur(cr[x],ld[x]);
	ld[x]=0;
}
void swap(int &a,int &b)
{
	int t=a;a=b;b=t;
}
int merge(int x,int y)
{
	pushd(x);pushd(y);
	if(x==0||y==0)
		return x+y;
	if(sz[x]>sz[y])
		swap(x,y);
	cr[x]=merge(cr[x],y);
	if(jl[cl[x]]<jl[cr[x]])
		swap(cl[x],cr[x]);
	jl[x]=jl[cr[x]]+1;
	return x;
}
int delmin(int x)
{
	return merge(cl[x],cr[x]);
}
int fr[300010],ne[600010],v[600010],sd[300010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int mer(int x,int y)
{
	if(x==0||y==0)
		return x+y;
	ll t=sz[x].z;
	pur(x,sz[y].z);
	pur(y,t);
	return merge(x,y);
}
int insert(int x,SJd t)
{
	sz[++sl]=t;
	return merge(x,sl);
}
int X[300010],Y[300010],Z[300010];
vector<int> ve[300010];
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	int ro=0;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		int rt=dfs(v[i],u);
		while(rt&&sz[rt].s>sd[u])
			rt=delmin(rt);
		ro=mer(ro,rt);
	}
	for(int i=0;i<ve[u].size();i++)
	{
		int t=ve[u][i];
		ro=insert(ro,SJd(sz[ro].z+Z[t],sd[Y[t]]));
	}
	return ro;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n-1;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);addb(b,a);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&X[i],&Y[i],&Z[i]);
		if(X[i]!=Y[i])
			ve[X[i]].push_back(i);
	}
	int rt=dfs(1,0);
	printf("%lld",sz[rt].z);
	return 0;
}


#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#define ll long long
#define N 300010
using namespace std;
int n,m;
int root = 1;
class point
{
public:
	ll A;
	int B;
};
point make(ll a, int b)
{
	point C;
	C.A = a;
	C.B = b;
	return C;
}
bool operator <(point a, point b)
{
	if (a.A == b.A)return a.B > b.B;
	return a.A > b.A;
}
priority_queue<point> Q[N];
bool vis[N];
vector<int> G[N];
int deep[N] = { 0 };
ll del[N] = { 0 };
bool flag = 1;
void DFS1(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			deep[v] = deep[u] + 1;
			DFS1(v);
		}
	}
}
ll ans = 0;
void merge(int i, int j)
{
	if (Q[i].size() < Q[j].size())
	{
		swap(Q[i], Q[j]);
		swap(del[i], del[j]);
	}
	while (Q[j].size())
	{
		Q[i].push(make(Q[j].top().A + del[j] - del[i], Q[j].top().B));
		Q[j].pop();
	}
}
void DFS2(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			DFS2(v);
			merge(u, v);
		}
	}
	while (Q[u].size() && Q[u].top().B >= deep[u])Q[u].pop();
	if (u != root)
	{
		if (Q[u].empty())
		{
			flag = 0;
			return;
		}
		ll cost;
		cost = Q[u].top().A + del[u];
		ans += cost;
		del[u] -= cost;
	}
}
void read()
{
	int i, u, v, w;
	cin >> n>>m;
	for (i = 1; i < n; i++)
	{
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	//deep[1] = 1;
	memset(vis, 0, sizeof(vis));
	DFS1(root);
	for (i = 1; i <= m; i++)
	{
		cin >> u >> v >> w;
		Q[u].push(make(w, deep[v]));
	}
	memset(vis, 0, sizeof(vis));
	//if (n >= 300000)cout << sizeof(Q) << endl;
	DFS2(root);
}
void work()
{
	if (flag)cout << ans << endl;
	else cout << -1 << endl;
}
int main()
{
	read();
	work();
	//while (true);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#define ll long long
#define N 300010
using namespace std;
int n,m;
int root = 1;
class point
{
public:
	ll A;
	int B;
};
point make(ll a, int b)
{
	point C;
	C.A = a;
	C.B = b;
	return C;
}
bool operator <(point a, point b)
{
	if (a.A == b.A)return a.B > b.B;
	return a.A > b.A;
}
priority_queue<point> Q[N];
bool vis[N];
vector<int> G[N];
int deep[N] = { 0 };
ll del[N] = { 0 };
bool flag = 1;
void DFS1(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			deep[v] = deep[u] + 1;
			DFS1(v);
		}
	}
}
ll ans = 0;
void merge(int i, int j)
{
	if (Q[i].size() < Q[j].size())
	{
		swap(Q[i], Q[j]);
		swap(del[i], del[j]);
	}
	while (Q[j].size())
	{
		Q[i].push(make(Q[j].top().A + del[j] - del[i], Q[j].top().B));
		Q[j].pop();
	}
}
void DFS2(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			DFS2(v);
			merge(u, v);
		}
	}
	while (Q[u].size() && Q[u].top().B >= deep[u])Q[u].pop();
	if (u != root)
	{
		if (Q[u].empty())
		{
			flag = 0;
			return;
		}
		ll cost;
		cost = Q[u].top().A + del[u];
		ans += cost;
		del[u] -= cost;
	}
}
void read()
{
	int i, u, v, w;
	cin >> n>>m;
	for (i = 1; i < n; i++)
	{
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	deep[1] = 1;
	memset(vis, 0, sizeof(vis));
	DFS1(root);
	for (i = 1; i <= m; i++)
	{
		cin >> u >> v >> w;
		Q[u].push(make(w, deep[v]));
	}
	memset(vis, 0, sizeof(vis));
	DFS2(root);
}
void work()
{
	if (flag)cout << ans << endl;
	else cout << -1 << endl;
}
int main()
{
	read();
	work();
	//while (true);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <queue>
#define A first
#define B second
using namespace std;
typedef long long ll;
typedef pair<ll, int> pii;

const int MAXN = 1e6;

int N, M;
ll add[MAXN];
priority_queue<pii, vector<pii>, greater<pii>> q[MAXN];
vector<int> g[MAXN];
int d[MAXN];
ll ans;

void dfs1(int i, int p) {
	d[i] = d[p] + 1;
	for(int j: g[i]) {
		if(j == p)
			continue;
		dfs1(j, i);
	}
}

void merge(int i, int j) {
	if(q[i].size() < q[j].size()) {
		swap(q[i], q[j]);
		swap(add[i], add[j]);
	}
	while(q[j].size()) {
		q[i].push({q[j].top().A + add[j] - add[i], q[j].top().B});
		q[j].pop();
	}
}

void dfs2(int i, int p) {
	for(int j: g[i]) {
		if(j == p)
			continue;
		dfs2(j, i);
		merge(i, j);
	}
	while(q[i].size() && q[i].top().B >= d[i])
		q[i].pop();
	if(i != 1) {
		if(q[i].empty()) {
			puts("-1");
			exit(0);
		}
		ll cost = add[i] + q[i].top().A;
		ans += cost;
		add[i] -= cost;
	}
}

int main() {
	//freopen("A.in", "r", stdin);
	scanf("%d%d", &N, &M);
	for(int i = 0, x, y; i < N-1; i++) {
		scanf("%d%d", &x, &y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs1(1, 0);
	for(int i = 0, x, y, c; i < M; i++) {
		scanf("%d%d%d", &x, &y, &c);
		q[x].push({c, d[y]});
	}
	dfs2(1, 0);
	printf("%I64d\n", ans);
}


#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#define ll long long
#define N 300010
#define A first
#define B second
#define pi pair<ll,int>
using namespace std;
int n,m;
int root = 1;
class point
{
public:
	ll A;
	int B;
};
point make(ll a, int b)
{
	point C;
	C.A = a;
	C.B = b;
	return C;
}
bool operator <(point a, point b)
{
	if (a.A == b.A)return a.B > b.B;
	return a.A > b.A;
}
//priority_queue<point> Q[N];
priority_queue<pi, vector<pi>, greater<pi>> Q[N];
bool vis[N];
vector<int> G[N];
int deep[N] = { 0 };
ll del[N] = { 0 };
bool flag = 1;
void DFS1(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			deep[v] = deep[u] + 1;
			DFS1(v);
		}
	}
}
ll ans = 0;
void merge(int i, int j)
{
	if (Q[i].size() < Q[j].size())
	{
		swap(Q[i], Q[j]);
		swap(del[i], del[j]);
	}
	//if(n<300000)
	while (!Q[j].empty())
	{
		Q[i].push(make(Q[j].top().A + del[j] - del[i], Q[j].top().B));
		Q[j].pop();
	}
}
void DFS2(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			DFS2(v);
			merge(u, v);
		}
	}
	while (Q[u].size() && Q[u].top().B >= deep[u])Q[u].pop();
	if (u != root)
	{
		if (Q[u].empty())
		{
			flag = 0;
			return;
		}
		ll cost=Q[u].top().A + del[u];
		ans += cost;
		del[u] -= cost;
	}
}
void read()
{
	int i, u, v, w;
	cin >> n>>m;
	for (i = 1; i < n; i++)
	{
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	//deep[1] = 1;
	memset(vis, 0, sizeof(vis));
	DFS1(root);
	for (i = 1; i <= m; i++)
	{
		cin >> u >> v >> w;
		Q[u].push(make(w, deep[v]));
	}
	memset(vis, 0, sizeof(vis));
	//if (n >= 300000)cout << sizeof(Q) << endl;
	DFS2(root);
}
void work()
{
	if (flag)cout << ans << endl;
	else cout << -1 << endl;
}
int main()
{
	read();
	work();
	//while (true);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#define ll long long
#define N 500010
using namespace std;
int n,m;
int root = 1;
class point
{
public:
	ll A,B;
};
point make(ll a, ll b)
{
	point C;
	C.A = a;
	C.B = b;
	return C;
}
bool operator <(point a, point b)
{
	if (a.A == b.A)return a.B > b.B;
	return a.A > b.A;
}
priority_queue<point> Q[N];
bool vis[N];
vector<int> G[N];
int deep[N] = { 0 };
ll del[N] = { 0 };
bool flag = 1;
void DFS1(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			deep[v] = deep[u] + 1;
			DFS1(v);
		}
	}
}
ll ans = 0;
void merge(int i, int j)
{
	if (Q[i].size() < Q[j].size())
	{
		swap(Q[i], Q[j]);
		swap(del[i], del[j]);
	}
	while (Q[j].size())
	{
		Q[i].push(make(Q[j].top().A + del[j] - del[i], Q[j].top().B));
		Q[j].pop();
	}
}
void DFS2(int u)
{
	int i, v;
	vis[u] = 1;
	for (i = 0; i < G[u].size(); i++)
	{
		v = G[u][i];
		if (!vis[v])
		{
			DFS2(v);
			merge(u, v);
		}
	}
	while (Q[u].size() && Q[u].top().B >= deep[u])Q[u].pop();
	if (u != root)
	{
		if (Q[u].empty())
		{
			flag = 0;
			return;
		}
		ll cost;
		cost = Q[u].top().A + del[u];
		ans += cost;
		del[u] -= cost;
	}
}
void read()
{
	int i, u, v, w;
	cin >> n>>m;
	for (i = 1; i < n; i++)
	{
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	deep[1] = 1;
	memset(vis, 0, sizeof(vis));
	DFS1(root);
	for (i = 1; i <= m; i++)
	{
		cin >> u >> v >> w;
		Q[u].push(make(w, deep[v]));
	}
	memset(vis, 0, sizeof(vis));
	DFS2(root);
}
void work()
{
	if (flag)cout << ans << endl;
	else cout << -1 << endl;
}
int main()
{
	read();
	work();
	//while (true);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N];

priority_queue<PII, vector<PII>, greater<PII> > Q[N];
int d[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
    }
}

inline void upd(int &x, int y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if (Q[v].size() < Q[u].size()) swap(Q[v], Q[u]), swap(d[v], d[u]);
        while (!Q[u].empty()) {
            auto it = Q[u].top();Q[u].pop();
            Q[v].push(make_pair(it.first-d[u]+d[v], it.second));
        }
    }
    if (v == 1) return;
    while (!Q[v].empty() && Q[v].top().second >= dep[v]) Q[v].pop();
    if (Q[v].empty()) {
        flag = true;
        return;
    }
    auto it = Q[v].top();
    ans += it.first - d[v];
    d[v] = it.first;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        Q[u].push(make_pair(c, dep[v]));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N], size[N];

vector<pair<int, LL> > worker[N];
map<int, LL> *M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    size[v] = 1;
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
        size[v] += size[u];
    }
}

inline void upd(LL &x, LL y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    int mx = -1, son = -1;
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if ((int)(*M[u]).size() > mx) mx = (int)(*M[u]).size(), son = u;
        f[v] = min(f[v], f[u]);
    }
    if (son != -1) {
        M[v] = M[son];
        d[v] = d[son];
    }
    else {
        M[v] = new map<int, LL>();
        d[v] = 0;
    }
    for (auto &it : worker[v]) {
        if ((*M[v]).count(it.first))
            upd((*M[v])[it.first], it.second + d[v]);
        else
            (*M[v])[it.first] = it.second + d[v];
    }
    for (auto u : e[v]) {
        if (u == p || u == son) continue;
        for (auto &it : (*M[u])) {
            if ((*M[v]).count(it.first))
                upd((*M[v])[it.first], it.second - d[u] + d[v]);
            else
                (*M[v])[it.first] = it.second - d[u] + d[v];
        }
    }
    if (v == 1) return;
    if (f[v] == dep[v]) {
        if (!(*M[v]).empty() && (*M[v]).rbegin()->first == dep[v]) {
            (*M[v]).erase(dep[v]);
        }
        if ((*M[v]).empty()) {
            flag = true;
            return;
        }
        auto it = (*M[v]).rbegin();
        f[v] = it->first;
        ans += it->second - d[v];
        d[v] += it->second;
        (*M[v]).erase(it->first);
        if ((*M[v]).empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        worker[u].push_back(make_pair(dep[v], c));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N], size[N];

vector<pair<int, LL> > worker[N];
map<int, LL> *M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    size[v] = 1;
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
        size[v] += size[u];
    }
}

inline void upd(LL &x, LL y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    int mx = -1, son = -1;
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if ((int)(*M[u]).size() > mx) mx = (int)(*M[u]).size(), son = u;
        f[v] = min(f[v], f[u]);
    }
    if (son != -1) {
        M[v] = M[son];
        d[v] = d[son];
    }
    else {
        M[v] = new map<int, LL>();
        d[v] = 0;
    }
    for (auto &it : worker[v]) {
        if ((*M[v]).count(it.first))
            upd((*M[v])[it.first], it.second + d[v]);
        else
            (*M[v])[it.first] = it.second + d[v];
    }
    for (auto u : e[v]) {
        if (u == p || u == son) continue;
        for (auto &it : (*M[u])) {
            if ((*M[v]).count(it.first))
                upd((*M[v])[it.first], it.second - d[u] + d[v]);
            else
                (*M[v])[it.first] = it.second - d[u] + d[v];
        }
    }
    /*
    puts("--------------");
    printf("%d %d %d %d\n", v, p, d[v], f[v]);
    for (auto it : (*M[v])) {
        cout << it.first << ' ' << it.second << endl;
    }
    */
    if (v == 1) return;
    if (f[v] == dep[v]) {
        if (!(*M[v]).empty() && (*M[v]).rbegin()->first == dep[v]) {
            (*M[v]).erase(dep[v]);
        }
        if ((*M[v]).empty()) {
            flag = true;
            return;
        }
        auto it = (*M[v]).rbegin();
        f[v] = it->first;
        ans += it->second - d[v];
        d[v] = it->second;
        (*M[v]).erase(it->first);
        if ((*M[v]).empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        worker[u].push_back(make_pair(dep[v], c));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N];

map<int, int> M[N];
int d[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
    }
}

inline void upd(int &x, int y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if (M[v].size() < M[u].size()) swap(M[v], M[u]), swap(d[v], d[u]);
        for (auto &it : M[u]) {
            if (M[v].count(it.first-d[u]+d[v]))
                upd(M[v][it.first-d[u]+d[v]], it.second);
            else
                M[v][it.first-d[u]+d[v]] = it.second;
        }
    }
    if (v == 1) return;
    while (!M[v].empty() && M[v].begin()->second >= dep[v]) M[v].erase(M[v].begin());
    if (M[v].empty()) {
        flag = true;
        return;
    }
    auto it = M[v].begin();
    ans += it->first - d[v];
    d[v] = it->first;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        if (M[u].count(c))
            upd(M[u][c], dep[v]);
        else
            M[u][c] = dep[v];
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N];

set<pair<int, int> > S[N];
int d[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
    }
}

inline void upd(int &x, int y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if (S[v].size() < S[u].size()) swap(S[v], S[u]), swap(d[v], d[u]);
        for (auto &it : S[u]) S[v].insert(make_pair(it.first-d[u]+d[v], it.second));
    }
    if (v == 1) return;
    while (!S[v].empty() && S[v].begin()->second >= dep[v]) S[v].erase(S[v].begin());
    if (S[v].empty()) {
        flag = true;
        return;
    }
    auto it = S[v].begin();
    ans += it->first - d[v];
    d[v] = it->first;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        S[u].insert(make_pair(c, dep[v]));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N], size[N];

vector<pair<int, int> > worker[N];
map<int, int> *M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    size[v] = 1;
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
        size[v] += size[u];
    }
}

inline void upd(int &x, int y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    int mx = -1, son = -1;
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if ((int)(*M[u]).size() > mx) mx = (int)(*M[u]).size(), son = u;
        f[v] = min(f[v], f[u]);
    }
    if (son != -1) {
        M[v] = M[son];
        d[v] = d[son];
    }
    else {
        M[v] = new map<int, int>();
        d[v] = 0;
    }
    for (auto &it : worker[v]) {
        if ((*M[v]).count(it.first+d[v]))
            upd((*M[v])[it.first+d[v]], it.second);
        else
            (*M[v])[it.first+d[v]] = it.second;
    }
    for (auto u : e[v]) {
        if (u == p || u == son) continue;
        for (auto &it : (*M[u])) {
            if ((*M[v]).count(it.first-d[u]+d[v]))
                upd((*M[v])[it.first-d[u]+d[v]], it.second);
            else
                (*M[v])[it.first-d[u]+d[v]] = it.second;
        }
    }
    /*
    puts("--------------");
    printf("%d %d %d %d\n", v, p, d[v], f[v]);
    for (auto it : (*M[v])) {
        cout << it.first << ' ' << it.second << endl;
    }
    */
    if (v == 1) return;
    if (f[v] == dep[v]) {
        while (!(*M[v]).empty() && (*M[v]).begin()->second >= dep[v]) {
            (*M[v]).erase((*M[v]).begin());
        }
        if ((*M[v]).empty()) {
            flag = true;
            return;
        }
        auto it = (*M[v]).begin();
        f[v] = it->second;
        ans += it->first - d[v];
        d[v] = it->first;
        (*M[v]).erase(it);
        if ((*M[v]).empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        worker[u].push_back(make_pair(c, dep[v]));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N];

map<int, int> M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
    }
}

inline void upd(int &x, int y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        f[v] = min(f[v], f[u]);
        if (M[v].size() < M[u].size()) swap(M[v], M[u]), swap(d[v], d[u]);
        for (auto &it : M[u]) {
            if (M[v].count(it.first-d[u]+d[v]))
                upd(M[v][it.first-d[u]+d[v]], it.second);
            else
                M[v][it.first-d[u]+d[v]] = it.second;
        }
    }
    if (v == 1) return;
    if (f[v] == dep[v]) {
        while (!M[v].empty() && M[v].begin()->second >= dep[v]) {
            M[v].erase(M[v].begin());
        }
        if (M[v].empty()) {
            flag = true;
            return;
        }
        auto it = M[v].begin();
        f[v] = it->second;
        ans += it->first - d[v];
        d[v] = it->first;
        M[v].erase(it);
        if (M[v].empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        if (M[u].count(c))
            upd(M[u][c], dep[v]);
        else
            M[u][c] = dep[v];
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N], size[N];

vector<pair<int, LL> > worker[N];
map<int, LL> *M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    size[v] = 1;
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
        size[v] += size[u];
    }
}

inline void upd(LL &x, LL y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    int mx = -1, son = -1;
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if ((int)(*M[u]).size() > mx) mx = (int)(*M[u]).size(), son = u;
        f[v] = min(f[v], f[u]);
    }
    if (son != -1) {
        M[v] = M[son];
        d[v] = d[son];
    }
    else {
        M[v] = new map<int, LL>();
        d[v] = 0;
    }
    for (auto &it : worker[v]) {
        if ((*M[v]).count(it.first))
            upd((*M[v])[it.first], it.second + d[v]);
        else
            (*M[v])[it.first] = it.second + d[v];
    }
    for (auto u : e[v]) {
        if (u == p || u == son) continue;
        for (auto &it : (*M[u])) {
            if ((*M[v]).count(it.first))
                upd((*M[v])[it.first], it.second - d[u] + d[v]);
            else
                (*M[v])[it.first] = it.second - d[u] + d[v];
        }
    }
    /*
    puts("--------------");
    printf("%d %d %d %d\n", v, p, d[v], f[v]);
    for (auto it : (*M[v])) {
        cout << it.first << ' ' << it.second << endl;
    }
    */
    if (f[v] == dep[v]) {
        if (!(*M[v]).empty() && (*M[v]).rbegin()->first == dep[v]) {
            auto it = (*M[v]).rbegin();
            if (it->second - d[v] < 0) {
                ans += it->second - d[v];
                d[v] = it->second;
                (*M[v]).erase(it->first);
            }
        }
        if (v == 1) return;
        if ((*M[v]).empty()) {
            flag = true;
            return;
        }
        auto it = (*M[v]).rbegin();
        f[v] = it->first;
        ans += it->second - d[v];
        d[v] = it->second;
        (*M[v]).erase(it->first);
        if ((*M[v]).empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        worker[u].push_back(make_pair(dep[v], c));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

vector<int> e[N];
int dep[N], size[N];

vector<pair<int, LL> > worker[N];
map<int, LL> *M[N];
int d[N], f[N];
bool flag;
LL ans;

void dfs1(int v, int p) {
    size[v] = 1;
    for (auto u : e[v]) {
        if (u == p) continue;
        dep[u] = dep[v] + 1;
        dfs1(u, v);
        size[v] += size[u];
    }
}

inline void upd(LL &x, LL y) {
    if (y < x) x = y;
}

void dfs(int v, int p) {
    int mx = -1, son = -1;
    f[v] = dep[v];
    for (auto u : e[v]) {
        if (u == p) continue;
        dfs(u, v);
        if (flag) return;
        if ((int)(*M[u]).size() > mx) mx = (int)(*M[u]).size(), son = u;
        f[v] = min(f[v], f[u]);
    }
    if (son != -1) {
        M[v] = M[son];
        d[v] = d[son];
    }
    else {
        M[v] = new map<int, LL>();
        d[v] = 0;
    }
    for (auto &it : worker[v]) {
        if ((*M[v]).count(it.first))
            upd((*M[v])[it.first], it.second + d[v]);
        else
            (*M[v])[it.first] = it.second + d[v];
    }
    for (auto u : e[v]) {
        if (u == p || u == son) continue;
        for (auto &it : (*M[u])) {
            if ((*M[v]).count(it.first))
                upd((*M[v])[it.first], it.second - d[u] + d[v]);
            else
                (*M[v])[it.first] = it.second - d[u] + d[v];
        }
    }
    /*
    puts("--------------");
    printf("%d %d %d %d\n", v, p, d[v], f[v]);
    for (auto it : (*M[v])) {
        cout << it.first << ' ' << it.second << endl;
    }
    */
    if (f[v] == dep[v]) {
        if (!(*M[v]).empty() && (*M[v]).rbegin()->first == dep[v]) {
            auto it = (*M[v]).rbegin();
            if (it->second - d[v] < 0) {
                ans += it->second - d[v];
                d[v] = it->second;
            }
            (*M[v]).erase(it->first);
        }
        if (v == 1) return;
        if ((*M[v]).empty()) {
            flag = true;
            return;
        }
        auto it = (*M[v]).rbegin();
        f[v] = it->first;
        ans += it->second - d[v];
        d[v] = it->second;
        (*M[v]).erase(it->first);
        if ((*M[v]).empty()) d[v] = 0;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs1(1, 0);
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        worker[u].push_back(make_pair(dep[v], c));
    }
    dfs(1, 0);
    if (flag) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
typedef long long i64;
const int N=3e5+77;
struct path{
	int tp,v;
	bool operator<(const path&w)const{return tp!=w.tp?tp<w.tp:v<w.v;}
};
int n,m;
std::vector<int>e[N];
int dep[N];
typedef std::multiset<path> MSET;
typedef MSET::iterator IT;
MSET f[N];
int mf[N],fa[N],dec[N];
i64 ans=0;
int gf(int x){
	while(x!=mf[x])x=mf[x]=x[mf][mf];
	return x;
}
void ins(int w,path p,int d){
	p.v+=d;
	IT i1=f[w].insert(p),i2=i1;
	if(i2!=f[w].begin()&&(--i2)->v<=p.v){
		f[w].erase(i1);
		return;
	}
	for(++i1;i1!=f[w].end()&&i1->v>=p.v;i2=i1,++i1,f[w].erase(i2));
}
void f1(int w,int pa){
	dep[w]=dep[fa[w]=pa]+1;
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=pa)f1(u,w);
	}
}
void f2(int w){
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=fa[w]){
			f2(u);
			if(f[u].size()>f[w].size())f[w].swap(f[u]),std::swap(dec[w],dec[u]);
			for(IT it=f[u].begin();it!=f[u].end();++it)ins(w,*it,dec[w]-dec[u]);
			f[u].clear();
		}
	}
	while(f[w].size()){
		IT it=f[w].begin();
		if(it->tp==dep[w])f[w].erase(it);
		else break;
	}
	if(w!=1&&w==mf[w]){
		if(f[w].empty())puts("-1"),exit(0);
		IT it=--f[w].end();
		ans+=it->v-dec[w];
		dec[w]=it->v;
		for(int a=w;dep[a]>it->tp;a=mf[a]=gf(fa[a]));
		f[w].erase(it);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)mf[i]=i;
	for(int i=1,a,b;i<n;++i){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	f1(1,0);
	for(int i=0,a,b,c;i<m;++i){
		scanf("%d%d%d",&a,&b,&c);
		ins(a,(path){dep[b],c},0);
	}
	f2(1);
	printf("%I64d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
typedef long long i64;
const int N=3e5+77;
struct path{
	int tp,v;
	bool operator<(const path&w)const{return tp!=w.tp?tp<w.tp:v<w.v;}
};
int n,m;
std::vector<int>e[N];
int dep[N];
typedef std::multiset<path> MSET;
typedef MSET::iterator IT;
MSET f[N];
int mf[N],fa[N],dec[N];
i64 ans=0;
int gf(int x){
	while(x!=mf[x])x=mf[x]=x[mf][mf];
	return x;
}
void ins(int w,path p,int d){
	p.v-=d;
	IT i1=f[w].insert(p),i2=i1;
	if(i2!=f[w].begin()&&(--i2)->v<=p.v){
		f[w].erase(i1);
		return;
	}
	for(++i1;i1!=f[w].end()&&i1->v>=p.v;i2=i1,++i1,f[w].erase(i2));
}
void f1(int w,int pa){
	dep[w]=dep[fa[w]=pa]+1;
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=pa)f1(u,w);
	}
}
void f2(int w){
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=fa[w]){
			f2(u);
			if(f[u].size()>f[w].size())f[w].swap(f[u]),std::swap(dec[w],dec[u]);
			for(IT it=f[u].begin();it!=f[u].end();++it)ins(w,*it,dec[w]-dec[u]);
			f[u].clear();
		}
	}
	while(f[w].size()){
		IT it=f[w].begin();
		if(it->tp==dep[w])f[w].erase(it);
		else break;
	}
	if(w!=1&&w==mf[w]){
		if(f[w].empty())puts("-1"),exit(0);
		IT it=--f[w].end();
		ans+=it->v-dec[w];
		dec[w]=it->v;
		for(int a=w;dep[a]>it->tp;a=mf[a]=gf(fa[a]));
		f[w].erase(it);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)mf[i]=i;
	for(int i=1,a,b;i<n;++i){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	f1(1,0);
	for(int i=0,a,b,c;i<m;++i){
		scanf("%d%d%d",&a,&b,&c);
		ins(a,(path){dep[b],c},0);
	}
	f2(1);
	printf("%I64d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
typedef long long i64;
const int N=1e5+7;
struct path{
	int tp,v;
	bool operator<(const path&w)const{return tp!=w.tp?tp<w.tp:v<w.v;}
};
int n,m;
std::vector<int>e[N];
int dep[N];
typedef std::multiset<path> MSET;
typedef MSET::iterator IT;
MSET f[N];
int mf[N],fa[N],dec[N];
i64 ans=0;
int gf(int x){
	while(x!=mf[x])x=mf[x]=x[mf][mf];
	return x;
}
void ins(int w,path p,int d){
	p.v-=d;
	IT i1=f[w].insert(p),i2=i1;
	if(i2!=f[w].begin()&&(--i2)->v<=p.v){
		f[w].erase(i1);
		return;
	}
	for(++i1;i1!=f[w].end()&&i1->v>=p.v;i2=i1,++i1,f[w].erase(i2));
}
void f1(int w,int pa){
	dep[w]=dep[fa[w]=pa]+1;
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=pa)f1(u,w);
	}
}
void f2(int w){
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=fa[w]){
			f2(u);
			if(f[u].size()>f[w].size())f[w].swap(f[u]),std::swap(dec[w],dec[u]);
			for(IT it=f[u].begin();it!=f[u].end();++it)ins(w,*it,dec[w]-dec[u]);
			f[u].clear();
		}
	}
	while(f[w].size()){
		IT it=f[w].begin();
		if(it->tp==dep[w])f[w].erase(it);
		else break;
	}
	if(w!=1&&w==mf[w]){
		if(f[w].empty())puts("-1"),exit(0);
		IT it=--f[w].end();
		ans+=it->v-dec[w];
		dec[w]=it->v;
		for(int a=w;dep[a]>it->tp;a=mf[a]=gf(fa[a]));
		f[w].erase(it);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)mf[i]=i;
	for(int i=1,a,b;i<n;++i){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	f1(1,0);
	for(int i=0,a,b,c;i<m;++i){
		scanf("%d%d%d",&a,&b,&c);
		ins(a,(path){dep[b],c},0);
	}
	f2(1);
	printf("%I64d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
typedef long long i64;
const int N=1e5+7;
struct path{
	int tp,v;
	bool operator<(const path&w)const{return tp!=w.tp?tp<w.tp:v<w.v;}
};
int n,m;
std::vector<int>e[N];
int dep[N];
typedef std::multiset<path> MSET;
typedef MSET::iterator IT;
MSET f[N];
int mf[N],fa[N],dec[N];
i64 ans=0;
int gf(int x){
	while(x!=mf[x])x=mf[x]=x[mf][mf];
	return x;
}
void ins(int w,path p,int d){
	p.v-=d;
	IT i1=f[w].insert(p),i2=i1;
	if(i2!=f[w].begin()&&(--i2)->v<=p.v){
		f[w].erase(i1);
		return;
	}
	for(++i1;i1!=f[w].end()&&i1->v>=p.v;i2=i1,++i1,f[w].erase(i2));
}
void f1(int w,int pa){
	dep[w]=dep[fa[w]=pa]+1;
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=pa)f1(u,w);
	}
}
void f2(int w){
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=fa[w]){
			f2(u);
			if(f[u].size()>f[w].size())f[w].swap(f[u]),std::swap(dec[w],dec[u]);
			for(IT it=f[u].begin();it!=f[u].end();++it)ins(w,*it,dec[w]-dec[u]);
			f[u].clear();
		}
	}
	while(f[w].size()){
		IT it=f[w].begin();
		if(it->tp==dep[w])f[w].erase(it);
		else break;
	}
	if(w!=1&&w==mf[w]){
		if(f[w].empty())puts("-1"),exit(0);
		IT it=f[w].begin();
		ans+=it->v-dec[w];
		dec[w]=it->v;
		for(int a=w;dep[a]>it->tp;a=mf[a]=gf(fa[a]));
		f[w].erase(it);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)mf[i]=i;
	for(int i=1,a,b;i<n;++i){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	f1(1,0);
	for(int i=0,a,b,c;i<m;++i){
		scanf("%d%d%d",&a,&b,&c);
		ins(a,(path){dep[b],c},0);
	}
	f2(1);
	printf("%I64d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
typedef long long i64;
const int N=3e5+77;
struct path{
	int tp,v;
	bool operator<(const path&w)const{return tp!=w.tp?tp<w.tp:v<w.v;}
};
int n,m;
std::vector<int>e[N];
int dep[N];
typedef std::multiset<path> MSET;
typedef MSET::iterator IT;
MSET f[N];
int mf[N],fa[N],dec[N];
i64 ans=0;
int gf(int x){
	while(x!=mf[x])x=mf[x]=x[mf][mf];
	return x;
}
void ins(int w,path p,int d){
	p.v+=d;
	IT i1=f[w].insert(p),i2=i1;
	if(i2!=f[w].begin()&&(--i2)->v<=p.v){
		f[w].erase(i1);
		return;
	}
	for(++i1;i1!=f[w].end()&&i1->v>=p.v;i2=i1,++i1,f[w].erase(i2));
}
void f1(int w,int pa){
	dep[w]=dep[fa[w]=pa]+1;
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=pa)f1(u,w);
	}
}
void f2(int w){
	for(int i=0;i<e[w].size();++i){
		int u=e[w][i];
		if(u!=fa[w]){
			f2(u);
			if(f[u].size()>f[w].size())f[w].swap(f[u]),std::swap(dec[w],dec[u]);
			for(IT it=f[u].begin();it!=f[u].end();++it)ins(w,*it,dec[w]-dec[u]);
			f[u].clear();
		}
	}
	while(f[w].size()){
		IT it=--f[w].end();
		if(it->tp==dep[w])f[w].erase(it);
		else break;
	}
	if(w!=1&&w==mf[w]){
		if(f[w].empty())puts("-1"),exit(0);
		IT it=--f[w].end();
		ans+=it->v-dec[w];
		dec[w]=it->v;
		for(int a=w;dep[a]>it->tp;a=mf[a]=gf(fa[a]));
		f[w].erase(it);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)mf[i]=i;
	for(int i=1,a,b;i<n;++i){
		scanf("%d%d",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	f1(1,0);
	for(int i=0,a,b,c;i<m;++i){
		scanf("%d%d%d",&a,&b,&c);
		ins(a,(path){dep[b],c},0);
	}
	f2(1);
	printf("%I64d\n",ans);
	return 0;
}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;
const long long linf = 1e15+5;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
bool isanswer=true;
int n,m;
ll ST[N << 2], L[N << 2];

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || b>index || e<index){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=min(val,LIMIT);
		return ;
	}
	else{
		updatev(2*node,b,(b+e)/2,index,val);
		updatev(2*node+1,(b+e)/2+1,e,index,val);
		tree[node].val=min(min(tree[2*node].val,tree[2*node+1].val),LIMIT);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(min(tree[2*node].val,tree[2*node+1].val),LIMIT);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(min(l.val,r.val),LIMIT);
		return ;
	}
}

// ll update(int k, int bas, int son, int x, ll D) {
//     if(bas > x || son < x) return ST[k];
//     if(bas == son) return ST[k] = D;
//     ST[k] = min(update(sol, bas, orta, x, D), update(sag, orta + 1, son, x, D)) + L[k];
//     if(ST[k] > linf) ST[k] = linf;
//     return ST[k];
// }

// ll update(int k, int bas, int son, int x, int y, ll D) {
//     if(bas > y || son < x) return ST[k];
//     if(x <= bas && son <= y) {
//         L[k] = min(linf, D + L[k]);
//         ST[k] = min(linf, D + ST[k]);
//         return ST[k];
//     }
//     ST[k] = min(update(sol, bas, orta, x, y, D), update(sag, orta + 1, son, x, y, D)) + L[k];
//     if(ST[k] > linf) ST[k] = linf;
//     return ST[k];
// }

// ll query(int k, int bas, int son, int x, int y) {
//     if(bas > y || son < x) return linf;
//     if(x <= bas && son <= y) return ST[k];
//     return min(linf, min(query(sol, bas, orta, x, y), query(sag, orta + 1, son, x, y)) + L[k]);
// }

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			if(prev!=2*linf){
				prev=min(prev,2*linf);
			}
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],linf);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	initialise(1,1,m);

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(answer1>=linf || !isanswer){
		printf("-1\n");
	}
	else{
		printf("%lld\n",answer1);
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
#define orta (bas + son >> 1)
#define sag (k + k + 1)
#define sol (k + k)
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;
const long long linf = 1e15+5;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
bool isanswer=true;
int n,m;
ll ST[N << 2], L[N << 2];

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=min(val,LIMIT);
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(min(tree[2*node].val,tree[2*node+1].val),LIMIT);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(min(tree[2*node].val,tree[2*node+1].val),LIMIT);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		tree[node].val=min(tree[node].val,LIMIT);
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].lazyp=min(tree[2*node].lazyp,LIMIT);
			tree[2*node+1].lazyp=min(tree[2*node+1].lazyp,LIMIT);
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(min(l.val,r.val),LIMIT);
		return ;
	}
}

// ll update(int k, int bas, int son, int x, ll D) {
//     if(bas > x || son < x) return ST[k];
//     if(bas == son) return ST[k] = D;
//     ST[k] = min(update(sol, bas, orta, x, D), update(sag, orta + 1, son, x, D)) + L[k];
//     if(ST[k] > linf) ST[k] = linf;
//     return ST[k];
// }

// ll update(int k, int bas, int son, int x, int y, ll D) {
//     if(bas > y || son < x) return ST[k];
//     if(x <= bas && son <= y) {
//         L[k] = min(linf, D + L[k]);
//         ST[k] = min(linf, D + ST[k]);
//         return ST[k];
//     }
//     ST[k] = min(update(sol, bas, orta, x, y, D), update(sag, orta + 1, son, x, y, D)) + L[k];
//     if(ST[k] > linf) ST[k] = linf;
//     return ST[k];
// }

// ll query(int k, int bas, int son, int x, int y) {
//     if(bas > y || son < x) return linf;
//     if(x <= bas && son <= y) return ST[k];
//     return min(linf, min(query(sol, bas, orta, x, y), query(sag, orta + 1, son, x, y)) + L[k]);
// }

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			if(prev!=2*linf){
				prev=min(prev,2*linf);
			}
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],linf);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	initialise(1,1,m);

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(answer1>=linf || !isanswer){
		printf("-1\n");
	}
	else{
		printf("%lld\n",answer1);
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
int n,m;
bool ispossible=true;
int active=0;

void poss(int u,int p){
	rep(t1,Adj[u]){
		if(t1!=p){
			poss(t1,u);
		}
	}

	rep(t1,add[u]){
		active++;
	}

	rep(t1,del[u]){
		active--;
	}

	if(active<=0 && u!=1){
		ispossible=false;
	}

	return ;
}

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=val;
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	// printf("before (%d,%d)->(%d)\n",b,e,tree[node].val);
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		// error(tree[node].val);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		// printf("(%d,%d)->(%d)\n",b,e,tree[node].val);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(l.val,r.val);
		return ;
	}
}

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			prev=min(prev,2*LIMIT);
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		assert(t1.y+prev>=t1.y && t1.y+prev>=prev);
		// error(t1.y+prev);
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],LIMIT);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			// Error(t1,prev-dp[t1]);
			// printf("updating here\n");
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	poss(1,0);

	if(!ispossible){
		printf("-1\n");
		return 0;
	}

	initialise(1,1,N);
	debug;

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(!(answer1>=LIMIT)){
		printf("%lld\n",answer1);
	}
	else{
		printf("-1\n");
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
int n,m;

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=val;
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	// printf("before (%d,%d)->(%d)\n",b,e,tree[node].val);
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		// error(tree[node].val);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		// printf("(%d,%d)->(%d)\n",b,e,tree[node].val);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(l.val,r.val);
		return ;
	}
}

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		assert(t1.y+prev>=t1.y && t1.y+prev>=prev);
		// error(t1.y+prev);
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],LIMIT);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	initialise(1,1,m);
	debug;

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(!(answer1>=LIMIT)){
		printf("%lld\n",answer1);
	}
	else{
		printf("-1\n");
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
int n,m;
bool ispossible=true;
int active=0;

void poss(int u,int p){
	rep(t1,Adj[u]){
		if(t1!=p){
			poss(t1,u);
		}
	}

	if(active==0){
		ispossible=false;
	}

	rep(t1,add[u]){
		active++;
	}

	rep(t1,del[u]){
		active--;
	}

	if(active<=0 && u!=1){
		ispossible=false;
	}

	return ;
}

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=val;
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	// printf("before (%d,%d)->(%d)\n",b,e,tree[node].val);
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		// error(tree[node].val);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		// printf("(%d,%d)->(%d)\n",b,e,tree[node].val);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(l.val,r.val);
		return ;
	}
}

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			prev=min(prev,2*LIMIT);
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		assert(t1.y+prev>=t1.y && t1.y+prev>=prev);
		// error(t1.y+prev);
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],LIMIT);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			// Error(t1,prev-dp[t1]);
			// printf("updating here\n");
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	poss(1,0);

	if(!ispossible){
		printf("-1\n");
		return 0;
	}

	initialise(1,1,N);
	debug;

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(!(answer1>=LIMIT)){
		printf("%lld\n",answer1);
	}
	else{
		printf("-1\n");
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
int n,m;
bool ispossible=true;
int active=0;

void poss(int u,int p){
	rep(t1,Adj[u]){
		if(t1!=p){
			poss(t1,u);
		}
	}

	rep(t1,add[u]){
		active++;
	}

	rep(t1,del[u]){
		active--;
	}

	if(active<=0){
		ispossible=false;
	}

	return ;
}

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=val;
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	// printf("before (%d,%d)->(%d)\n",b,e,tree[node].val);
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		// error(tree[node].val);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		// printf("(%d,%d)->(%d)\n",b,e,tree[node].val);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(l.val,r.val);
		return ;
	}
}

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			prev=min(prev,2*LIMIT);
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		assert(t1.y+prev>=t1.y && t1.y+prev>=prev);
		// error(t1.y+prev);
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],LIMIT);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			// Error(t1,prev-dp[t1]);
			// printf("updating here\n");
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	poss(1,0);

	if(!ispossible){
		printf("-1\n");
		return 0;
	}

	initialise(1,1,N);
	debug;

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(!(answer1>=LIMIT)){
		printf("%lld\n",answer1);
	}
	else{
		printf("-1\n");
	}
return 0;}


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

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/STACK:16777216")

#define Foreach(i, c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))
#define rof(i,a,b) for(int (i)=(a);(i) > (b); --(i))
#define rep(i, c) for(auto &(i) : (c))
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define PB pop_back()
#define iOS ios_base::sync_with_stdio(false)
#define sqr(a) (((a) * (a)))
#define pow2(a) (((a) * (a)))
#define all(a) a.begin() , a.end()
#define error(x) cerr << #x << " = " << (x) <<endl
#define Error(a,b) cerr<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define errop(a) cerr<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define L(x) (((x)<<1)+1)
#define R(x) (((x)<<1)+2)
#define umap unordered_map
#define double long double
#define mod 1000000007
#define mod1 10000019
#define LIMIT 40000000000000000LL
#define MAX1 1000000000
//#define si(n) scanf("%d",&n)
//#define sii(n,m) scanf("%d%d",&n,&m)
//#define pi(n) printf("%d\n",n)
const int inf=0x3f3f3f3f;
// const long double pi=acos(-1.0);
#define INF 1000000000000000000LL
#define inf 2000000000
#define MAX 1000005
#define N 600010
const string debug_line="yolo";
#define debug error(debug_line)
// const double PI=4*atan(1);
#define read() freopen("mergedoutput.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
//template <typename T> using os =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef pair<int,int>pii;
typedef vector<int> vi;
typedef complex<double> point;

typedef struct node2{
	ll val;
	ll lazyp;
	bool islazyp;
}node1;

node1 tree[2400100];
vi Adj[600100];
bool visited[600100];
vector<pii> add[600100];
vector<pii> del[600100];
int dfs_timer=0;
int begin1[600100];
int end1[600100];
int timerWork[600100];
ll dp[600100];
int n,m;
bool ispossible=true;
int active=0;

void poss(int u,int p){
	rep(t1,Adj[u]){
		if(t1!=p){
			poss(t1,u);
		}
	}

	if(u==1 && active==0){
		ispossible=false;
	}

	rep(t1,add[u]){
		active++;
	}

	rep(t1,del[u]){
		active--;
	}

	if(active<=0 && u!=1){
		ispossible=false;
	}

	return ;
}

void initialise(int node,int b,int e){
	if(b>e){
		return ;
	}
	else if(b==e){
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
	else{
		initialise(2*node,b,(b+e)/2);
		initialise(2*node+1,(b+e)/2+1,e);
		tree[node].val=LIMIT;
		tree[node].lazyp=0;
		tree[node].islazyp=0;
		return ;
	}
}

void updatev(int node,int b,int e,int index,ll val){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e){
		return ;
	}
	else if(b==e && e==index){
		tree[node].val=val;
		return ;
	}
	else{
		if(index<=(b+e)/2){
			updatev(2*node,b,(b+e)/2,index,val);
		}
		else{
			updatev(2*node+1,(b+e)/2+1,e,index,val);
		}
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		return ;
	}
}

void updated(int node,int b,int e,int i,int j,ll val){
	// printf("before (%d,%d)->(%d)\n",b,e,tree[node].val);
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		tree[node].val+=val;
		// error(tree[node].val);
		if(b!=e){
			tree[2*node].lazyp+=val;
			tree[2*node+1].lazyp+=val;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		return ;
	}
	else{
		updated(2*node,b,(b+e)/2,i,j,val);
		updated(2*node+1,(b+e)/2+1,e,i,j,val);
		tree[node].val=min(tree[2*node].val,tree[2*node+1].val);
		// printf("(%d,%d)->(%d)\n",b,e,tree[node].val);
		return ;
	}
}

void query(node1 &res,int node,int b,int e,int i,int j){
	if(tree[node].islazyp){
		tree[node].val+=tree[node].lazyp;
		if(b!=e){
			tree[2*node].lazyp+=tree[node].lazyp;
			tree[2*node+1].lazyp+=tree[node].lazyp;
			tree[2*node].islazyp=tree[2*node+1].islazyp=true;
		}
		tree[node].islazyp=false;
		tree[node].lazyp=0;
	}
	if(b>e || i>e || j<b){
		return ;
	}
	else if(i<=b && e<=j){
		res=tree[node];
		return ;
	}
	else{
		node1 l,r;
		l.val=r.val=LIMIT;
		query(l,2*node,b,(b+e)/2,i,j);
		query(r,2*node+1,(b+e)/2+1,e,i,j);
		res.val=min(l.val,r.val);
		return ;
	}
}

ll solve(int u,int p){
	visited[u]=true;
	ll prev=0;

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			prev+=solve(t1,u);
			prev=min(prev,2*LIMIT);
		}
	}

	if(u==1){
		dp[u]=prev;
		return dp[u];
	}

	rep(t1,add[u]){
		assert(t1.y+prev>=t1.y && t1.y+prev>=prev);
		// error(t1.y+prev);
		updatev(1,1,m,timerWork[t1.x],t1.y+prev);
	}

	rep(t1,del[u]){
		updatev(1,1,m,timerWork[t1.x],LIMIT);
	}

	rep(t1,Adj[u]){
		if(t1!=p){
			// Error(t1,prev-dp[t1]);
			// printf("updating here\n");
			updated(1,1,m,begin1[t1],end1[t1],prev-dp[t1]);
		}
	}

	node1 res;
	res.val=LIMIT;
	query(res,1,1,m,begin1[u],end1[u]);
	dp[u]=res.val;
	// Error(u,dp[u]);
	// Error(u,p);
	return dp[u];
}

void DFS(int u,int p){
	visited[u]=true;
	begin1[u]=dfs_timer+1;

	rep(t1,add[u]){
		timerWork[t1.x]=++dfs_timer;
	}

	rep(t1,Adj[u]){
		if(!visited[t1] && t1!=p){
			DFS(t1,u);
		}
	}
	end1[u]=dfs_timer;
	return ;
}

int main(){
	scanf("%d%d",&n,&m);

	For(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Adj[a].pb(b);
		Adj[b].pb(a);
	}

	For(i,0,m){
		int u,v,c;
		scanf("%d%d%d",&u,&v,&c);
		add[u].pb(mp(i,c));
		del[v].pb(mp(i,c));
	}

	poss(1,0);

	if(!ispossible){
		printf("-1\n");
		return 0;
	}

	initialise(1,1,N);
	debug;

	DFS(1,0);
	debug;

	For(i,0,n+1){
		visited[i]=false;
	}

	ll answer1=solve(1,0);

	if(!(answer1>=LIMIT)){
		printf("%lld\n",answer1);
	}
	else{
		printf("-1\n");
	}
return 0;}