#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define inf 2e9
using namespace std;
inline int read()
{
int x=0,w=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') w=-1;
c=getchar();
}
while(c<='9'&&c>='0')
{
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return w==1?x:-x;
}
ll n,t1,t2,t3,f[maxn],s1[maxn],s2[maxn],ans;
struct node
{
ll a,b,c,id,w1,w2;
} p[maxn];
vector <int> mp[maxn];
inline void dfs(int u,int fa)
{
f[u]=fa;
s1[u]=p[u].w1;//子树中点的权值
s2[u]=p[u].w2;
for(int i=0; i<mp[u].size(); i++)
{
int v=mp[u][i];
if(v==fa)
continue;
dfs(v,u);
s1[u]+=s1[v];
s2[u]+=s2[v];
}
}
// 父节点 父节点代价
inline void dfs2(int u,int fa,ll mn)
{
for(int i=0; i<mp[u].size(); i++)
{
int v=mp[u][i];
if(v==fa)
continue;
if(p[u].a<mn) //当前点代价小于父节点
{
ll tmp=min(s1[u],s2[u]);
ans+=tmp*p[u].a*2;
ans-=tmp*mn*2;
mn=p[u].a;
}
dfs2(v,u,mn);
}
}
int main()
{
n=read();
for(int i=1; i<=n; i++)
{
p[i].a=read(),p[i].b=read(),p[i].c=read();
t1+=p[i].b;
t2+=p[i].c;
p[i].id=i;
if(p[i].b!=p[i].c)//如果需要变换
{
if(p[i].b==0) //初始值是0,则需要变成1,就是w1
p[i].w1=1;
else
p[i].w2=1; //初始值是1,需要变成0, 就是w2
}
}
if(t1!=t2)
return puts("-1"),0;//有的总和 与 要的总和不等 直接结束
for(int i=1; i<=n-1; i++)
{
int u=read(),v=read();
mp[u].push_back(v);
mp[v].push_back(u);
}
dfs(1,0);
ans=p[1].a*min(s1[1],s2[1])*2;//直接拿根节点去搞答案
for(int i=0; i<mp[1].size(); i++)
{
int v=mp[1][i];
dfs2(v,1,p[1].a);
}
cout<<ans<<endl;
return 0;
}