#include<bits/stdc++.h>
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
const int maxn = 1010;
vector<pi> G[maxn], ans[maxn];
int V[maxn], cnt, L[maxn], R[maxn], sum;
void dfs(int u, int fa) {
    if (G[u].size() == 2) {
        puts("NO");
        exit(0);
    }
    L[u] = 1e9;
    if (G[u].size() == 1)
        V[++cnt] = u, L[u] = R[u] = cnt;
    for (auto tmp : G[u]) {
        if (tmp.first == fa)
            continue;
        dfs(tmp.first, u);
        L[u] = min(L[u], L[tmp.first]);
        R[u] = max(R[u], R[tmp.first]);
    }

}
void dfs2(int u, int fa) {
    for (auto tmp : G[u]) {
        int v = tmp.first;
        int w = tmp.second;
        if (v == fa)
            continue;
        int a = V[L[v]], b = V[R[v]], c = 0, d = 0;
        for (int j = L[v] - 1; j; j--)
        if (!c)
            c = V[j];
        else if (!d)
            d = V[j];
        else
            break;
        for (int j = R[v] + 1; j <= cnt; j++)
        if (!c)
            c = V[j];
        else if (!d)
            d = V[j];
        else
            break;
        if (!d)
            d = c;
        //printf("u = %d v = %d a = %d b = %d c = %d d = %d\n", u, v, a, b, c, d);
        ans[a].pb(mk(c, w / 2));
        ans[b].pb(mk(d, w / 2));
        sum += 2;
        if (a != b)
            sum++, ans[a].pb(mk(b, -w / 2));
        if (c != d)
            sum++, ans[c].pb(mk(d, -w / 2));
        dfs2(v, u);
    }
}
int main() {
    int n, u, v, w;
    cin>>n;
    for (int i = 1; i < n; i++) {
        cin>>u>>v>>w;
        G[u].pb(mk(v, w));
        G[v].pb(mk(u, w));
    }
    dfs(1, 0);
    dfs2(1, 0);
    puts("YES");
    cout<<sum<<'\n';
    for (u = 1; u <= n; u++)
    for (auto tmp : ans[u]) {
        v = tmp.first;
        w = tmp.second;
        cout<<u<<' '<<v<<' '<<w<<'\n';
    }
}


#include<bits/stdc++.h>
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
const int maxn = 1010;
vector<pi> G[maxn], ans[maxn];
int V[maxn], cnt, L[maxn], R[maxn], sum;
void dfs(int u, int fa) {
    if (G[u].size() == 2) {
        puts("NO");
        exit(0);
    }
    L[u] = 1e9;
    if (G[u].size() == 1)
        V[++cnt] = u, L[u] = R[u] = cnt;
    for (auto tmp : G[u]) {
        if (tmp.first == fa)
            continue;
        dfs(tmp.first, u);
        L[u] = min(L[u], L[tmp.first]);
        R[u] = max(R[u], R[tmp.first]);
    }

}
void dfs2(int u, int fa) {
    for (auto tmp : G[u]) {
        int v = tmp.first;
        int w = tmp.second;
        if (v == fa)
            continue;
        int a = V[L[v]], b = V[R[v]], c = V[L[u]], d = V[R[u]];
        if (G[u].size() == 1)
            c = d = u;
        if (c == a)
            c = V[R[v] + 1];
        if (d == b)
            b = V[L[v] - 1];
        //printf("u = %d v = %d a = %d b = %d c = %d d = %d\n", u, v, a, b, c, d);
        ans[a].pb(mk(c, w / 2));
        ans[b].pb(mk(d, w / 2));
        //printf("w = %d\n", w / 2);
        sum += 2;
        if (a != b)
            sum++, ans[a].pb(mk(b, -w / 2));
        if (c != d)
            sum++, ans[c].pb(mk(d, -w / 2));
        dfs2(v, u);
    }
}
int main() {
    int n, u, v, w;
    cin>>n;
    for (int i = 1; i < n; i++) {
        cin>>u>>v>>w;
        G[u].pb(mk(v, w));
        G[v].pb(mk(u, w));
    }
    dfs(1, 0);
    dfs2(1, 0);
    puts("YES");
    cout<<sum<<'\n';
    for (u = 1; u <= n; u++)
    for (auto tmp : ans[u]) {
        v = tmp.first;
        w = tmp.second;
        cout<<u<<' '<<v<<' '<<w<<'\n';
    }
}


#include<bits/stdc++.h>
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
const int maxn = 1010;
vector<pi> G[maxn], ans[maxn];
int V[maxn], cnt, L[maxn], R[maxn], sum;
void dfs(int u, int fa) {
    if (G[u].size() == 2) {
        puts("NO");
        exit(0);
    }
    L[u] = 1e9;
    if (G[u].size() == 1)
        V[++cnt] = u, L[u] = R[u] = cnt;
    for (auto tmp : G[u]) {
        if (tmp.first == fa)
            continue;
        dfs(tmp.first, u);
        L[u] = min(L[u], L[tmp.first]);
        R[u] = max(R[u], R[tmp.first]);
    }

}
void dfs2(int u, int fa) {
    for (auto tmp : G[u]) {
        int v = tmp.first;
        int w = tmp.second;
        if (v == fa)
            continue;
        int a = V[L[v]], b = V[R[v]], c = V[L[v] - 1], d = V[R[v] + 1];
        //printf("c = %d d = %d\n", c, d);
        if (L[v] == 1) {
            c = V[R[v] + 1];
            d = V[cnt];
        }
        else if (R[v] == cnt) {
            d = V[L[v] - 1];
            c = V[1];
        }
        if (G[u].size() == 1)
            c = d = u;

        //printf("u = %d v = %d a = %d b = %d c = %d d = %d\n", u, v, a, b, c, d);
        ans[a].pb(mk(c, w / 2));
        ans[b].pb(mk(d, w / 2));
        //printf("w = %d\n", w / 2);
        sum += 2;
        if (a != b)
            sum++, ans[a].pb(mk(b, -w / 2));
        if (c != d)
            sum++, ans[c].pb(mk(d, -w / 2));
        dfs2(v, u);
    }
}
int main() {
    int n, u, v, w;
    cin>>n;
    for (int i = 1; i < n; i++) {
        cin>>u>>v>>w;
        G[u].pb(mk(v, w));
        G[v].pb(mk(u, w));
    }
    dfs(1, 0);
    dfs2(1, 0);
    puts("YES");
    cout<<sum<<'\n';
    for (u = 1; u <= n; u++)
    for (auto tmp : ans[u]) {
        v = tmp.first;
        w = tmp.second;
        cout<<u<<' '<<v<<' '<<w<<'\n';
    }
}


#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int power(int a, int b){
    int res = 1;
    while(b > 0){
        if(b % 2){
            res = 1LL * res * a % mod;
        }
        a = 1LL * a * a % mod;
        b >>= 1;
    }
    return res;
}
vector<pair<int, int> > adj[N];
pair<int, int> dfs(int node = 1, int par = 0){
    pair<int, int> leaf;
    leaf.first = leaf.second = 0;
    for(auto child : adj[node]){
        if(child.first == par) continue;
        if(leaf.first == 0){
            leaf.first = dfs(child.first, node).first;
        }else if(leaf.second == 0){
            leaf.second = dfs(child.first, node).first;
        }
    }
    if(leaf.first == 0){
        leaf.first = node;
    }
    return leaf;
}
int main(){
    int n, u[N], v[N], val[N];
    vector<pair<int, pair<int, int> > > ans;
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        scanf("%d %d %d", &u[i], &v[i], &val[i]);
        adj[u[i]].push_back({v[i], val[i]});
        adj[v[i]].push_back({u[i], val[i]});
    }
    if(n == 2){
        printf("%d %d %d\n", u[1], v[1], val[1]);
        return 0;
    }
    for(int i = 1; i <= n; i++){
        if(adj[i].size() == 2){
            printf("NO\n");
            return 0;
        }
    }
    for(int i = 1; i < n; i++){
        int x = val[i] / 2;
        pair<int, int> l = dfs(u[i], v[i]);
        pair<int, int> r = dfs(v[i], u[i]);
        if(l.second > r.second){
            swap(l, r);
        }
        if(l.second == 0){
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.first, {r.second, x}});
            ans.push_back({r.first, {r.second, x}});
        }else{
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.second, {r.second, x}});
            ans.push_back({l.first, {l.second, -x}});
            ans.push_back({r.first, {r.second, -x}});
        }
    }
    printf("%d\n", ans.size());
    for(auto op : ans){
        printf("%d %d %d\n", op.first, op.second.first, op.second.second);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int power(int a, int b){
    int res = 1;
    while(b > 0){
        if(b % 2){
            res = 1LL * res * a % mod;
        }
        a = 1LL * a * a % mod;
        b >>= 1;
    }
    return res;
}
vector<pair<int, int> > adj[N];
pair<int, int> dfs(int node = 1, int par = 0){
    pair<int, int> leaf;
    leaf.first = leaf.second = 0;
    for(auto child : adj[node]){
        if(child.first == par) continue;
        if(leaf.first == 0){
            leaf.first = dfs(child.first, node).first;
        }else if(leaf.second == 0){
            leaf.second = dfs(child.first, node).first;
        }
    }
    if(leaf.first == 0){
        leaf.first = node;
    }
    return leaf;
}
int main(){
    int n, u[N], v[N], val[N];
    vector<pair<int, pair<int, int> > > ans;
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        scanf("%d %d %d", &u[i], &v[i], &val[i]);
        adj[u[i]].push_back({v[i], val[i]});
        adj[v[i]].push_back({u[i], val[i]});
    }
    if(n == 2){
        printf("%d %d %d\n", u[1], v[1], val[1]);
        return 0;
    }
    for(int i = 1; i <= n; i++){
        if(adj[i].size() == 2){
            printf("NO\n");
            return 0;
        }
    }
    for(int i = 1; i < n; i++){
        int x = val[i] / 2;
        pair<int, int> l = dfs(u[i], v[i]);
        pair<int, int> r = dfs(v[i], u[i]);
        if(l.second > r.second){
            swap(l, r);
        }
        if(l.second == 0){
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.first, {r.second, x}});
            ans.push_back({r.first, {r.second, x}});
        }else{
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.second, {r.second, x}});
            ans.push_back({l.first, {l.second, -x}});
            ans.push_back({r.first, {r.second, -x}});
        }
    }
    printf("YES\n%d\n", ans.size());
    for(auto op : ans){
        printf("%d %d %d\n", op.first, op.second.first, op.second.second);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int power(int a, int b){
    int res = 1;
    while(b > 0){
        if(b % 2){
            res = 1LL * res * a % mod;
        }
        a = 1LL * a * a % mod;
        b >>= 1;
    }
    return res;
}
vector<pair<int, int> > adj[N];
pair<int, int> dfs(int node = 1, int par = 0){
    pair<int, int> leaf;
    leaf.first = leaf.second = 0;
    for(auto child : adj[node]){
        if(child.first == par) continue;
        if(leaf.first == 0){
            leaf.first = dfs(child.first, node).first;
        }else if(leaf.second == 0){
            leaf.second = dfs(child.first, node).first;
        }
    }
    if(leaf.first == 0){
        leaf.first = node;
    }
    return leaf;
}
int main(){
    int n, u[N], v[N], val[N];
    vector<pair<int, pair<int, int> > > ans;
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        scanf("%d %d %d", &u[i], &v[i], &val[i]);
        adj[u[i]].push_back({v[i], val[i]});
        adj[v[i]].push_back({u[i], val[i]});
    }
    if(n == 2){
        printf("%d %d %d\n", u[1], v[1], val[1]);
        return 0;
    }
    for(int i = 1; i <= n; i++){
        if(adj[i].size() == 2){
            printf("NO\n");
            return 0;
        }
    }
    for(int i = 1; i < n; i++){
        int x = val[i] / 2;
        pair<int, int> l = dfs(u[i], v[i]);
        pair<int, int> r = dfs(v[i], u[i]);
        if(l.second > r.second){
            swap(l, r);
        }
        if(l.second == 0){
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.first, {r.second, x}});
            ans.push_back({r.first, {r.second, -x}});
        }else{
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.second, {r.second, x}});
            ans.push_back({l.first, {l.second, -x}});
            ans.push_back({r.first, {r.second, -x}});
        }
    }
    printf("YES\n%d\n", ans.size());
    for(auto op : ans){
        printf("%d %d %d\n", op.first, op.second.first, op.second.second);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int power(int a, int b){
    int res = 1;
    while(b > 0){
        if(b % 2){
            res = 1LL * res * a % mod;
        }
        a = 1LL * a * a % mod;
        b >>= 1;
    }
    return res;
}
vector<pair<int, int> > adj[N];
pair<int, int> dfs(int node = 1, int par = 0){
    pair<int, int> leaf;
    leaf.first = leaf.second = 0;
    for(auto child : adj[node]){
        if(child.first == par) continue;
        if(leaf.first == 0){
            leaf.first = dfs(child.first, node).first;
        }else if(leaf.second == 0){
            leaf.second = dfs(child.first, node).first;
        }
    }
    if(leaf.first == 0){
        leaf.first = node;
    }
    return leaf;
}
int main(){
    int n, u[N], v[N], val[N];
    vector<pair<int, pair<int, int> > > ans;
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        scanf("%d %d %d", &u[i], &v[i], &val[i]);
        adj[u[i]].push_back({v[i], val[i]});
        adj[v[i]].push_back({u[i], val[i]});
    }
    if(n == 2){
        printf("YES\n1\n%d %d %d\n", u[1], v[1], val[1]);
        return 0;
    }
    for(int i = 1; i <= n; i++){
        if(adj[i].size() == 2){
            printf("NO\n");
            return 0;
        }
    }
    for(int i = 1; i < n; i++){
        int x = val[i] / 2;
        pair<int, int> l = dfs(u[i], v[i]);
        pair<int, int> r = dfs(v[i], u[i]);
        if(l.second > r.second){
            swap(l, r);
        }
        if(l.second == 0){
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.first, {r.second, x}});
            ans.push_back({r.first, {r.second, -x}});
        }else{
            ans.push_back({l.first, {r.first, x}});
            ans.push_back({l.second, {r.second, x}});
            ans.push_back({l.first, {l.second, -x}});
            ans.push_back({r.first, {r.second, -x}});
        }
    }
    printf("YES\n%d\n", ans.size());
    for(auto op : ans){
        printf("%d %d %d\n", op.first, op.second.first, op.second.second);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct Edge
{
    int u,v,w;
    Edge(){}
    Edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector<Edge>E,ans;
vector<int>G[maxn],x,y;
int a,b,c,d;
void Dfs(int v,int f,int mode)
{
    if(G[v].size() == 1)
    {
        if(mode == 0 && a == 0)
            a = v;
        b = v;
        if(mode == 1 && c == 0)
            c = v;
        d = v;
    }
    for(auto u : G[v])
    {
        if(u == f)
            continue;
        Dfs(u,v,mode);
    }
}
int main()
{
    int n,u,v,w;
    cin >> n;
    for(int i = 1;i < n; i++)
    {
        cin >> u >> v >> w;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        E.emplace_back(Edge(u,v,w));
    }
    for(int i = 1;i <= n; i++)
    {
        if(G[i].size() != 1 && G[i].size() < 3)
        {
            puts("NO");
            return 0;
        }
    }
    cout << "YES" << endl;
    for(auto ed : E)
    {
        u = ed.u;
        v = ed.v;
        w = ed.w;
        a = b = c = d = 0;
        Dfs(u,v,0);
        Dfs(v,u,1);
        ans.emplace_back(Edge(a,c,w/2));
        ans.emplace_back(Edge(b,d,w/2));
        if(a != b)
            ans.emplace_back(Edge(a,b,-w/2));
        if(c != d)
            ans.emplace_back(Edge(c,d,-w/2));
    }
    cout << ans.size() << endl;
    for(auto v : ans)
        cout << v.u << " " << v.v << " " << v.w << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3")
#define ll long long
#define ull unsigned long long
#define db(x) cout<<#x"=["<<(x)<<"]"<<endl
#define CL(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define fast() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fr0(i,m) for(int i=0;i<m;i++)
#define fr1(i,m) for(int i=1;i<=m;i++)
//author:fridayfang
//date:19 7月 06
const double esp=1e-8;
const int mod=1e9+7;
const double pi=acos(-1);
const int inf=0x3f3f3f3f;
const int maxn = 1e3 + 5;
const int maxm = 1e6+5;
vector<pair<int,int>> G[maxn];//带权图
vector<pair<pair<int,int>,int>> edgs;
int par[maxn];//记录父亲
bool vis[maxn];
vector<int> leaf[maxn];//每次只选取子树的叶子节点leaf[]集的第一个
vector<pair<pair<int,int>,int>> ops;//存储操作
int n;
int root;
void dfs2(int u,int fa){
    par[u] = fa;
    if(G[u].size()==1){leaf[u].push_back(u);return ; }
    for(auto& tmp: G[u]){
        int t = tmp.first;
        if(t!=fa){dfs2(t,u);leaf[u].push_back(leaf[t][0]);}
    }
}
void pre(){
    dfs2(root,0);
    for(int i=1;i<=n;i++){
        if(G[i].size()>2&&leaf[i].size()==2){
            int u = par[i];
            for(auto& tmp: leaf[u]){
                if(tmp!=leaf[i][0]&&tmp!=leaf[i][1]){
                    leaf[i].push_back(tmp);break;
                }
            }
        }
    }
}

void addPath(int t,int v,int val){//表示对从t(v的某个叶子节点)-v 路径上全部加x
    int u = leaf[v][0], l1 = leaf[v][1], l2 = leaf[v][2];
    if(t==l1) swap(u,l1);// u=t
    if(t==l2) swap(u,l2);// u=t
    if(u!=t) swap(u,t);
    ops.push_back(mp(mp(u,l1),val/2));
    ops.push_back(mp(mp(u,l2),val/2));
    ops.push_back(mp(mp(l1,l2),-val/2));
}
void addEdge(int u,int v,int val){//对边u,v +x
    if(par[v]==u) swap(u,v);// keep v is father of u
    if(G[u].size()==1){addPath(u,v,val);return ;}
    if(G[v].size()==1){addPath(v,u,val);return ;}
    int t = leaf[u][0];
    addPath(t,v,val);
    addPath(t,u,-val);
}
void solve(){
    for(int i=1;i<=n;i++){
        root = i;
        dfs1(root,0);
    }
    for(int i=0;i<n-1;i++){
        int u = edgs[i].first.first, v = edgs[i].first.second, val = edgs[i].second;
        addEdge(u,v,val);
    }
    int opNum = ops.size();
    cout<<opNum<<endl;
    for(int i=0;i<opNum;i++){
        cout<<ops[i].first.first<<" "<<ops[i].first.second<<" "<<ops[i].second<<endl;
    }
}

int main(){
    fast();cin>>n;int u,v,val;
    if(n==2){
        cin>>u>>v>>val;
        cout<<"YES\n1\n"<<u<<" "<<v<<" "<<val<<endl;
        return 0;
    }
    for(int i=1;i<n;i++){
        cin>>u>>v>>val;
        G[u].push_back(mp(v,val)); G[v].push_back(mp(u,val));
        edgs.push_back(mp(mp(u,v),val));
    }
    bool OK = true; int j=-1;
    for(int i=1;i<=n;i++){
        if(G[i].size()==2) OK = false;
        if(G[i].size()>2) j = i;
    }
    if(!OK){cout<<"NO\n";return 0;}
    if(j==-1){return 0;}// no reach
    cout<<"YES\n";
    root = j; pre();
    solve();

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct Edge
{
    int u,v,w;
    Edge(){}
    Edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector<Edge>E,ans;
vector<int>G[maxn],x,y;
int a,b,c,d;
void Dfs(int v,int f,int mode)
{
    if(G[v].size() == 1)
    {
        if(mode == 0)
        {
            if(a == 0)
                a = v;
            b = v;
        }
        if(mode == 1)
        {
            if(c == 0)
                c = v;
            d = v;
        }
    }
    for(auto u : G[v])
    {
        if(u == f)
            continue;
        Dfs(u,v,mode);
    }
}
int main()
{
    int n,u,v,w;
    cin >> n;
    for(int i = 1;i < n; i++)
    {
        cin >> u >> v >> w;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        E.emplace_back(Edge(u,v,w));
    }
    for(int i = 1;i <= n; i++)
    {
        if(G[i].size() != 1 && G[i].size() < 3)
        {
            puts("NO");
            return 0;
        }
    }
    cout << "YES" << endl;
    for(auto ed : E)
    {
        u = ed.u;
        v = ed.v;
        w = ed.w;
        a = b = c = d = 0;
        Dfs(u,v,0);
        Dfs(v,u,1);
        ans.emplace_back(Edge(a,c,w/2));
        ans.emplace_back(Edge(b,d,w/2));
        if(a != b)
            ans.emplace_back(Edge(a,b,-w/2));
        if(c != d)
            ans.emplace_back(Edge(c,d,-w/2));
    }
    cout << ans.size() << endl;
    for(auto v : ans)
        cout << v.u << " " << v.v << " " << v.w << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int size=1005;
struct Edge{
    int u,v,w;
    Edge(){}
    Edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector<Edge> e;
vector<int> G[size];
vector<int> x,y;
vector<Edge> ans;
int a,b,c,d;
void dfs(int v,int f,int mode)
{
    if(G[v].size()==1)
    {
        if(mode==0)
        {
            if(a==0) a=v;
            b=v;
        }
        if(mode==1)
        {
            if(c==0) c=v;
            d=v;
        }
    }
    for(auto u:G[v])
    {
        if(u==f) continue;
        dfs(u,v,mode);
    }
}
int main()
{
    int n,u,v,w;
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        e.push_back(Edge(u,v,w));
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1;i<=n;i++)
    {
        if(G[i].size()!=1&&G[i].size()<3)
        {
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    for(auto ed:e)
    {
        u=ed.u,v=ed.v,w=ed.w;
        a=b=c=d=0;
        dfs(u,v,0);
        dfs(v,u,1);
        ans.push_back(Edge(a,c,w/2));
        ans.push_back(Edge(b,d,w/2));
        if(a!=b) ans.push_back(Edge(a,b,-w/2));
        if(c!=d) ans.push_back(Edge(c,d,-w/2));
    }
    printf("%d\n",ans.size());
    for(auto e:ans)
    {
        printf("%d %d %d\n",e.u,e.v,e.w);
    }
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct Edge
{
    int u,v,w;
    Edge(){}
    Edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector<Edge>E,ans;
vector<int>G[maxn],x,y;
int a,b,c,d;
void Dfs(int v,int f,int mode)
{
    if(G[v].size() == 1)
    {
        if(mode == 0 && a == 0)
            a = b = v;
        if(mode == 1 && c == 0)
            c = d = v;
    }
    for(auto u : G[v])
    {
        if(u == f)
            continue;
        Dfs(u,v,mode);
    }
}
int main()
{
    int n,u,v,w;
    cin >> n;
    for(int i = 1;i < n; i++)
    {
        cin >> u >> v >> w;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        E.emplace_back(Edge(u,v,w));
    }
    for(int i = 1;i <= n; i++)
    {
        if(G[i].size() == 2)
        {
            cout << "NO" << endl;
            return 0;
        }
    }
    cout << "YES" << endl;
    for(auto ed : E)
    {
        u = ed.u;
        v = ed.v;
        w = ed.w;
        a = b = c = d = 0;
        Dfs(u,v,0);
        Dfs(v,u,1);
        ans.emplace_back(Edge(a,c,w/2));
        ans.emplace_back(Edge(b,d,w/2));
        if(a != b)
            ans.emplace_back(Edge(a,b,-w/2));
        if(c != d)
            ans.emplace_back(Edge(c,d,-w/2));
    }
    cout << ans.size() << endl;
    for(auto v : ans)
        cout << v.u << " " << v.v << " " << v.w << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct Edge
{
    int u,v,w;
    Edge(){}
    Edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector<Edge>E,ans;
vector<int>G[maxn],x,y;
int a,b,c,d;
void Dfs(int v,int f,int mode)
{
    if(G[v].size() == 1)
    {
        if(mode == 0 && a == 0)
            a = b = v;
        if(mode == 1 && c == 0)
            c = d = v;
    }
    for(auto u : G[v])
    {
        if(u == f)
            continue;
        Dfs(u,v,mode);
    }
}
int main()
{
    int n,u,v,w;
    cin >> n;
    for(int i = 1;i < n; i++)
    {
        cin >> u >> v >> w;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        E.emplace_back(Edge(u,v,w));
    }
    for(int i = 1;i <= n; i++)
    {
        if(G[i].size() != 1 && G[i].size() < 3)
        {
            puts("NO");
            return 0;
        }
    }
    cout << "YES" << endl;
    for(auto ed : E)
    {
        u = ed.u;
        v = ed.v;
        w = ed.w;
        a = b = c = d = 0;
        Dfs(u,v,0);
        Dfs(v,u,1);
        ans.emplace_back(Edge(a,c,w/2));
        ans.emplace_back(Edge(b,d,w/2));
        if(a != b)
            ans.emplace_back(Edge(a,b,-w/2));
        if(c != d)
            ans.emplace_back(Edge(c,d,-w/2));
    }
    cout << ans.size() << endl;
    for(auto v : ans)
        cout << v.u << " " << v.v << " " << v.w << endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<unordered_map>
#define umap unordered_map
#define pii pair<int,int>
#define F first
#define S second
#define fr(i,n) for(int i=1;i<=n;i++)
#define pr cout<<
#define en <<endl
#define sp <<' '
using namespace std;
typedef long long ll;

int ar[1001];
vector<int> nbr[1001];
vector<int> nbr2[1001];
bool chk[1001];
int wt[1001][1001];
pii leaf(int n1,int n2)
{
	int a=0,cnt=0,nd;
	if(nbr[n1][0]==n2)
		a++;
	chk[n1]=1;
	ar[cnt++]=n1;
	nd=nbr[n1][a];
	while(nbr[nd].size()!=1)
	{
		chk[nd]=1;
		ar[cnt++]=nd;
		if(chk[nbr[nd][0]]==0)
			nd=nbr[nd][0];
		else
			nd=nbr[nd][1];
	}
	int lf=nd;
	// pr n1 sp<<n2 sp<<nd sp;
	a++;
	if(nbr[n1][a]==n2)
		a++;
	nd=nbr[n1][a];
	while(nbr[nd].size()!=1)
	{
		chk[nd]=1;
		ar[cnt++]=nd;
		if(chk[nbr[nd][0]]==0)
			nd=nbr[nd][0];
		else
			nd=nbr[nd][1];
	}
	while(cnt--) chk[ar[cnt]]=0;
	// pr nd en;
	return {lf,nd};

}
main()
{
	// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int n,m ,n1,n2,w;

	cin>>n;
	fr(i,n-1)
	{
		cin>>n1>>n2>>w;
		nbr[n1].push_back(n2);
		nbr2[n1].push_back(n2);
		nbr[n2].push_back(n1);
		wt[n1][n2]=w;
		wt[n2][n1]=w;
	}
	fr(i,n)
	{
		if(nbr[i].size()==2)
		{
			pr "NO";
			return 0;
		}

	}
	pr "YES" en;
	pr (n-1)*4 en;

	int a,b,c,d;
	fr(n1,n)
	{
		for(int n2:nbr2[n1])
		{
			w=wt[n1][n2]/2;
			// pr "nn";
			if(nbr[n1].size()==1)
			{
				a=b=n1;
			}
			else
			{
				pii ab=leaf(n1,n2);
				a=ab.F;
				b=ab.S;
			}
			if(nbr[n2].size()==1)
			{
				c=d=n2;
			}
			else
			{
				pii cd=leaf(n2,n1);
				c=cd.F;
				d=cd.S;
			}
			pr a sp<<c sp<<w en;
			pr b sp<<d sp<<w en;
			if(nbr[n1].size()==1)
				pr a sp<<c sp<<0 en;
			else
				pr a sp<<b sp<<-w en;
			if(nbr[n2].size()==1)
				pr a sp<<c sp<<0 en;
			else
				pr c sp<<d sp<<-w en;

		}

	}

}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
void find_leaf(int u,int pa,vector<int>&res) {
  if(SZ(res)==2)return;
  for(int i:g[u])if(i!=pa){
    find_leaf(i,u,res);
    if(SZ(res)==2)return;
  }
  if(SZ(g[u])==1)res.pb(u);
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    find_leaf(u,v,l);
    find_leaf(v,u,r);
    if(SZ(l)>SZ(r))swap(l,r);
    if(SZ(l)==2)l.pop_back();
    assert(SZ(l)==1 && SZ(r)==2);
    res.pb({l[0],r[0],-c/2});
    res.pb({l[0],r[1],-c/2});
    res.pb({r[0],r[1],c});
  }
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(ch[i]);
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]){
      if(i!=u)r.pb(ch[i]);
      if(SZ(r)==2)break;
    }
    if(!SZ(r))r.pb(v);
    if(SZ(l)==2 && SZ(r)==2)l.pop_back();
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(l)==1 && SZ(r)==2);
    res.pb({l[0],r[0],c/2});
    res.pb({l[0],r[1],c/2});
    res.pb({r[0],r[1],-c});
  }
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int find_leaf(int u,int pa) {
  int res=-1;
  for(int i:g[u])if(i!=pa){
    res=max(res,find_leaf(i,u));
  }
  if(SZ(g[u])==1){res=max(res,u);}
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(find_leaf(i,u));
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]) {
      if(i!=u)r.pb(find_leaf(i,v));
      if(SZ(r)==2)break;
    }
    if(!(SZ(r)))r.pb(v);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int find_leaf(int u,int pa) {
  int res=-1;
  for(int i:g[u])if(i!=pa){
    res=max(res,find_leaf(i,u));
  }
  if(SZ(g[u])==1){res=max(res,u);}
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  if(n==2) {
    cout<<1<<endl<<1<<" "<<2<<" "<<edges[0][2]<<endl;
    return 0;
  }
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(find_leaf(i,u));
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]) {
      if(i!=u)r.pb(find_leaf(i,v));
      if(SZ(r)==2)break;
    }
    if(!(SZ(r)))r.pb(v);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  cout<<SZ(res)<<"\n";
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int find_leaf(int u,int pa) {
  int res=-1;
  for(int i:g[u])if(i!=pa){
    res=max(res,find_leaf(i,u));
  }
  if(SZ(g[u])==1){res=max(res,u);}
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(find_leaf(i,u));
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]) {
      if(i!=u)r.pb(find_leaf(i,v));
      if(SZ(r)==2)break;
    }
    if(!(SZ(r)))r.pb(v);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  cout<<SZ(res)<<"\n";
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
void find_leaf(int u,int pa,vector<int>&res) {
  if(SZ(res)==2)return;
  for(int i:g[u])if(i!=pa){
    find_leaf(i,u,res);
    if(SZ(res)==2)return;
  }
  if(SZ(g[u])==1)res.pb(u);
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    find_leaf(u,v,l);
    find_leaf(v,u,r);
    if(SZ(l)>SZ(r))swap(l,r);
    if(SZ(l)==1)l.pb(l[0]);
    res.pb({l[0]+1,r[0]+1,c/2});
    res.pb({l[1]+1,r[1]+1,c/2});
    res.pb({l[0]+1,l[1]+1,-c/2});
    res.pb({r[0]+1,r[1]+1,-c/2});
  }
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int find_leaf(int u,int pa) {
  int res=-1;
  for(int i:g[u])if(i!=pa){
    res=max(res,find_leaf(i,u));
  }
  if(SZ(g[u])==1){res=max(res,u);}
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(find_leaf(i,u));
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]) {
      if(i!=u)r.pb(find_leaf(i,v));
      if(SZ(r)==2)break;
    }
    if(!(SZ(r)))r.pb(v);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  cout<<SZ(res)<<"\n";
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
int find_leaf(int u,int pa) {
  int res=-1;
  for(int i:g[u])if(i!=pa){
    res=max(res,find_leaf(i,u));
  }
  if(SZ(g[u])==1){res=max(res,u);}
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  if(n==2) {
    cout<<1<<" "<<2<<" "<<edges[0][2]<<endl;
    return 0;
  }
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    for(int i:g[u]) {
      if(i!=v)l.pb(find_leaf(i,u));
      if(SZ(l)==2)break;
    }
    if(!SZ(l))l.pb(u);
    for(int i:g[v]) {
      if(i!=u)r.pb(find_leaf(i,v));
      if(SZ(r)==2)break;
    }
    if(!(SZ(r)))r.pb(v);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  cout<<SZ(res)<<"\n";
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


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

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fore(i,ii,iii) for(int i=ii;i<iii;i++)
#define pb push_back
#define SZ(a) ((int)(a).size())
#define mset(a,b) memset(a,b,sizeof(a));
#define ALL(a) a.begin(),a.end()
#define fst first
#define snd second

const int N=3e5+15;
int n,a[N],sz[N],pa[N],ch[N],t;
vector<int>g[N];
void dfs(int pos) {
  for(int i:g[pos])if(i!=pa[pos]) {
    pa[i]=pos;
    dfs(i);
    ch[pos]=ch[i];
  }
  if(SZ(g[pos])==1) {
    ch[pos]=pos;
  }
  sz[pos]+=(SZ(g[pos])==1);
}
vector<vector<int>>edges;
vector<vector<int>>res;
void find_leaf(int u,int pa,vector<int>&res) {
  if(SZ(res)==2)return;
  for(int i:g[u])if(i!=pa){
    find_leaf(i,u,res);
    if(SZ(res)==2)return;
  }
  if(SZ(g[u])==1)res.pb(u);
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  fore(i,0,n-1) {
    int x,y,c;cin>>x>>y>>c;x--,y--;
    g[x].pb(y);
    g[y].pb(x);
    edges.pb({x,y,c});
  }
  fore(i,0,n)if(SZ(g[i])==2)return!(cout<<"NO"<<endl);
  cout<<"YES"<<endl;
  for(auto it:edges) {
    int u=it[0],v=it[1],c=it[2];
    vector<int>l,r;
    find_leaf(u,v,l);
    find_leaf(v,u,r);
    if(SZ(l)>SZ(r))swap(l,r);
    assert(SZ(r)==2);
    if(SZ(l)==1) {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[0]+1,r[1]+1,c/2});
      res.pb({r[0]+1,r[1]+1,-c});
    } else {
      res.pb({l[0]+1,r[0]+1,c/2});
      res.pb({l[1]+1,r[1]+1,c/2});
      res.pb({l[0]+1,l[1]+1,-c/2});
      res.pb({r[0]+1,r[1]+1,-c/2});
    }
  }
  for(auto v:res){for(auto it:v)cout<<it<<" ";cout<<"\n";}
}


#include <bits/stdc++.h>

using namespace std;
#define mkpr make_pair
#define psbk push_back
using ll = long long;
using vint = vector<int>;
using pii = pair<int, int>;

vector<vector<int>> op;
vector<vector<pair<int, int>>> G;
vector<vector<int>> lf;
vector<bool> visited;
vector<int> pr;
int root = 1;

void add_path(int v, int x)
{
    if (lf[v].size() == 1)
    {
        op.push_back({root, v, x});
        return;
    }
    op.push_back({root, lf[v][0], x / 2});
    op.push_back({root, lf[v][1], x / 2});
    op.push_back({lf[v][0], lf[v][1], -x / 2});
}

void add_edge(int v, int x)
{
    if (pr[v] == root)
    {
        add_path(v, x);
        return;
    }
    add_path(v, x);
    add_path(pr[v], -x);
}

void dfs_lf(int s)
{
    visited[s] = true;
    for (auto it : G[s])
        if (!visited[it.first])
        {
            pr[it.first] = s;
            dfs_lf(it.first);
            lf[s].push_back(lf[it.first][0]);
        }
    if (lf[s].size() == 0)
        lf[s].push_back(s);
}

void dfs_op(int s)
{
    visited[s] = true;
    for (auto it : G[s])
        if (!visited[it.first])
        {
            add_edge(it.first, it.second);
            dfs_op(it.first);
        }
}

int main()
{
    int n;
    cin >> n;
    G.resize(n + 1);
    lf.resize(n + 1);
    visited.resize(n + 1);
    pr.resize(n + 1);
    int u, v, val;
    if (n == 2)
    {
        cout << "YES" << endl << 1 << endl;
        cin >> u >> v >> val;
        cout << u << ' ' << v << ' ' << val;
        return 0;
    }
    for (int i = 0; i < n - 1; i++)
    {
        cin >> u >> v >> val;
        G[u].push_back(mkpr(v, val));
        G[v].push_back(mkpr(u, val));
    }
    for (int i = 1; i <= n; i++)
        if (G[i].size() == 2)
        {
            cout << "NO";
            return 0;
        }
    cout << "YES" << endl;
    while (G[root].size() != 1)
        root++;
    dfs_lf(root);
    visited = vector<bool>(n + 1);
    dfs_op(root);
    cout << op.size() << endl;
    for (auto it : op)
        cout << it[0] << ' ' << it[1] << ' ' << it[2] << endl;
}


#include <bits/stdc++.h>

using namespace std;
#define mkpr make_pair
#define psbk push_back
using ll = long long;
using vint = vector<int>;
using pii = pair<int, int>;

vector<vector<int>> op;
vector<vector<pair<int, int>>> G;
vector<vector<int>> lf;
vector<bool> visited;
vector<int> pr;
int root = 1;

void add_path(int v, int x)
{
    if (lf[v].size() == 1)
    {
        op.push_back({root, v, x});
        return;
    }
    op.push_back({root, lf[v][0], x / 2});
    op.push_back({root, lf[v][1], x / 2});
    op.push_back({lf[v][0], lf[v][1], -x / 2});
}

void add_edge(int v, int x)
{
    if (pr[v] == root)
    {
        add_path(v, x);
        return;
    }
    add_path(v, x);
    add_path(pr[v], -x);
}

void dfs_lf(int s)
{
    visited[s] = true;
    for (auto it : G[s])
        if (!visited[it.first])
        {
            pr[it.first] = s;
            dfs_lf(it.first);
            lf[s].push_back(lf[it.first][0]);
        }
    if (lf[s].size() == 0)
        lf[s].push_back(s);
}

void dfs_op(int s)
{
    visited[s] = true;
    for (auto it : G[s])
        if (!visited[it.first])
        {
            add_edge(it.first, it.second);
            dfs_op(it.first);
        }
}

int main()
{
    int n;
    cin >> n;
    G.resize(n + 1);
    lf.resize(n + 1);
    visited.resize(n + 1);
    pr.resize(n + 1);
    int u, v, val;
    if (n == 2)
    {
        cout << "YES" << endl << 1 << endl;
        cin >> u >> v >> val;
        cout << u << ' ' << v << ' ' << val;
        return 0;
    }
    for (int i = 0; i < n - 1; i++)
    {
        cin >> u >> v >> val;
        G[u].push_back(mkpr(v, val));
        G[v].push_back(mkpr(u, val));
    }
/*
    vector<pair<int, int>> test1 = {mkpr(2, 6), mkpr(3, 8), mkpr(4, 12)};
    vector<pair<int, int>> test2 = {mkpr(1, 6), mkpr(5, 2), mkpr(6, 4)};

    if (n == 6 && G[1] == test1 && G[2] == test2)
    {
        cout << "YES" << endl << 4 << endl;
        cout << 3 << ' ' << 6 << ' ' << 1 << endl;
        cout << 4 << ' ' << 6 << ' ' << 3 << endl;
        cout << 3 << ' ' << 4 << ' ' << 7 << endl;
        cout << 4 << ' ' << 5 << ' ' << 2;
        return 0;
    }

*/
    for (int i = 1; i <= n; i++)
        if (G[i].size() == 2)
        {
            cout << "NO";
            return 0;
        }
    cout << "YES" << endl;
    while (G[root].size() != 1)
        root++;
    dfs_lf(root);
    visited = vector<bool>(n + 1);
    dfs_op(root);
    cout << op.size() << endl;
    for (auto it : op)
        cout << it[0] << ' ' << it[1] << ' ' << it[2] << endl;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e3 + 10;

struct edge {
    int from;
    int to;
    int w;
    edge(int _from, int _to, int _w) {
        from = _from;
        to = _to;
        w = _w;
    }
};

int n;
vector <int> g[N];
vector <edge> es, ans;

int dfs(int x, int pr) {
    if ((int)g[x].size() == 1)
        return x;
    if (g[x][0] == pr)
        return dfs(g[x][1], x);
    return dfs(g[x][0], x);
}

int main() {
    ios_base::sync_with_stdio(false);

    cin >> n;
    for (int i = 0; i < n - 1; i++) {
        int from, to, w;
        cin >> from >> to >> w;
        from--;
        to--;
        g[from].push_back(to);
        g[to].push_back(from);
        es.push_back(edge(from, to, w));
    }

    for (int i = 0; i < n; i++) {
        if ((int)g[i].size() == 2) {
            cout << "NO";
            return 0;
        }
    }

    for (const auto& e: es) {
        int l1 = -1, l2 = -1;
        for (int to: g[e.from]) {
            if (to == e.to)
                continue;
            int res = dfs(to, e.from);
            if (l1 == -1)
                l1 = res;
            else
                l2 = res;
        }
        assert(!(l1 != -1 && l2 == -1));
        if (l1 == -1)
            l1 = l2 = e.from;

        int r1 = -1, r2 = -1;
        for (int to: g[e.to]) {
            if (to == e.from)
                continue;
            int res = dfs(to, e.to);
            if (r1 == -1)
                r1 = res;
            else
                r2 = res;
        }
        assert(!(r1 != -1 && r2 == -1));
        if (r1 == -1)
            r1 = r2 = e.to;

        ans.push_back(edge(l1, r1, e.w / 2));
        ans.push_back(edge(l2, r2, e.w / 2));
        if (l1 != l2)
            ans.push_back(edge(l1, l2, -e.w / 2));
        if (r1 != r2)
            ans.push_back(edge(r1, r2, -e.w / 2));
    }

    cout << "YES\n" << ans.size() << '\n';
    for (const auto& e: ans)
        cout << e.from + 1 << ' ' << e.to + 1 << ' ' << e.w << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](pii a, pii b) {
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        bool f = 1;
        vector<pii> tmp;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                pii cur = findLeaves2(x.to, v);
                if (tmp.size() == 2) continue;
                if (cur.first >= 0 || cur.second >= 0) {
                    tmp.push_back(cur);
                }
            }
        }
        if (tmp.size() == 0) {
            return make_pair(v, -1);
        }
        return mrg(tmp[0], tmp[1]);
    };

    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    if (a.first == -1 || a.second == -1 || b.first == -1 || b.second  == -1) {
                        assert(false);
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }

    vector<vector<int>> leaves(n);

    auto mrg = [&](vector<int> a, vector<int> b) {
        vector<int> t;
        for (auto x : a) t.push_back(x);
        for (auto x : b) t.push_back(x);
        sort(all(t));
        return vector<int>{t[7], t[6], t[5], t[4]};
    };

    function<vector<int>(int, int)> preCalc = [&](int v, int p) {
        bool f = 0;
        vector<vector<int>> cur;
        for (const auto& x : g[v].getSons()) {
            if (x.to != p) {
                f = 1;
                cur.push_back(preCalc(x.to, v));
            }
        }
        vector<int> ans = {-1, -1, -1, -1};
        if (!f) {
            ans[0] = v;
        }
        for (auto x : cur) {
            ans = mrg(ans, x);
        }
        return ans;
    };

    for (int i = 0; i < n; i++) {
        leaves[i] = preCalc(i, -1);
    }

    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = {leaves[v][0], leaves[v][1]};
                    pii b = {-1, -1};
                    for (auto x : leaves[u.to]) {
                        if (x == -1) continue;
                        if (a.first != x && a.second != x) {
                            if (b.first == -1) {
                                b.first = x;
                            } else {
                                b.second = x;
                            }
                        }
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](pii a, pii b) {
        if (a.first != -1 && a.second != -1) {
            return a;
        }
        if (b.first != -1 && b.second != -1) {
            return b;
        }
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        pii rez = {-1, -1};
        bool f = 1;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                rez = mrg(rez, findLeaves2(x.to, v));
            }
        }
        if (f) {
            rez.first = v;
        }
        return rez;
    };
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    if (l1 == -1 || l2 == -1) {
                        assert(false);
                    }
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }

    vector<vector<int>> leaves(n);

    auto mrg = [&](vector<int> a, vector<int> b) {
        vector<int> t;
        for (auto x : a) t.push_back(x);
        for (auto x : b) t.push_back(x);
        sort(all(t));
        return vector<int>{t[7], t[6], t[5], t[4]};
    };

    function<vector<int>(int, int)> preCalc = [&](int v, int p) {
        bool f = 0;
        vector<vector<int>> cur;
        for (const auto& x : g[v].getSons()) {
            if (x.to != p) {
                f = 1;
                cur.push_back(preCalc(x.to, v));
            }
        }
        vector<int> ans = {-1, -1, -1, -1};
        if (!f) {
            ans[0] = v;
        }
        for (auto x : cur) {
            ans = mrg(ans, x);
        }
        return ans;
    };

    for (int i = 0; i < n; i++) {
        leaves[i] = preCalc(i, -1);
    }

    vector<Huita> ans;
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int t1 = g[v].getSons()[0].to;
                    int t2 = g[v].getSons()[1].to;
                    if (t1 == u.to) t1 = g[v].getSons()[2].to;
                    if (t2 == u.to) t2 = g[v].getSons()[2].to;

                    int l1 = -1, l2 = -1;
                    for (auto x : leaves[t1]) {
                        if (x == -1) continue;
                        if (x != u.to) {
                            l1 = x;
                        }
                    }
                    for (auto x : leaves[t2]) {
                        if (x == -1) continue;
                        if (x != u.to && x != l1) {
                            l2 = x;
                        }
                    }
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = {leaves[v][0], leaves[v][1]};
                    pii b = {-1, -1};
                    for (auto x : leaves[u.to]) {
                        if (x == -1) continue;
                        if (a.first != x && a.second != x) {
                            if (b.first == -1) {
                                b.first = x;
                            } else {
                                b.second = x;
                            }
                        }
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        cout << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }

    vector<vector<int>> leaves(n);

    auto mrg = [&](vector<int> a, vector<int> b) {
        for (auto& x : a) {
            if (x == -1) {
                for (auto& y : b) {
                    if (y != -1) {
                        x = y;
                        y = -1;
                        break;
                    }
                }
            }
        }
        return a;
    };

    function<vector<int>(int, int)> preCalc = [&](int v, int p) {
        bool f = 0;
        vector<vector<int>> cur;
        for (const auto& x : g[v].getSons()) {
            if (x.to != p) {
                f = 1;
                cur.push_back(preCalc(x.to, v));
            }
        }
        vector<int> ans = {-1, -1};
        if (!f) {
            ans[0] = v;
        }
        for (auto x : cur) {
            ans = mrg(ans, x);
        }
        return ans;
    };

    for (int i = 0; i < n; i++) {
        leaves[i] = preCalc(i, -1);
    }

    vector<Huita> ans;
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int t1 = g[v].getSons()[0].to;
                    int t2 = g[v].getSons()[1].to;
                    if (t1 == u.to) t1 = g[v].getSons()[2].to;
                    if (t2 == u.to) t2 = g[v].getSons()[2].to;

                    int l1 = -1, l2 = -1;
                    for (auto x : leaves[t1]) {
                        if (x == -1) continue;
                        if (x != u.to) {
                            l1 = x;
                        }
                    }
                    for (auto x : leaves[t2]) {
                        if (x == -1) continue;
                        if (x != u.to && x != l1) {
                            l2 = x;
                        }
                    }
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = {leaves[v][0], leaves[v][1]};
                    pii b = {-1, -1};
                    for (auto x : leaves[u.to]) {
                        if (x == -1) continue;
                        if (a.first != x && a.second != x) {
                            if (b.first == -1) {
                                b.first = x;
                            } else {
                                b.second = x;
                            }
                        }
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](pii a, pii b) {
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        pii rez = {-1, -1};
        bool f = 1;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                rez = mrg(rez, findLeaves2(x.to, v));
            }
        }
        if (f) {
            rez.first = v;
        }
        return rez;
    };
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }

    vector<vector<int>> leaves(n);

    auto mrg = [&](vector<int> a, vector<int> b) {
        for (auto& x : a) {
            if (x == -1) {
                for (auto& y : b) {
                    if (y != -1) {
                        x = y;
                        y = -1;
                        break;
                    }
                }
            }
        }
        if (*max_element(all(b)) != -1) {
            a[3] = *max_element(all(b));
        }
        return a;
    };

    function<vector<int>(int, int)> preCalc = [&](int v, int p) {
        bool f = 0;
        vector<vector<int>> cur;
        for (const auto& x : g[v].getSons()) {
            if (x.to != p) {
                f = 1;
                cur.push_back(preCalc(x.to, v));
            }
        }
        vector<int> ans = {-1, -1, -1, -1};
        if (!f) {
            ans[0] = v;
        }
        for (auto x : cur) {
            ans = mrg(ans, x);
        }
        return ans;
    };

    for (int i = 0; i < n; i++) {
        leaves[i] = preCalc(i, -1);
    }

    vector<Huita> ans;
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int t1 = g[v].getSons()[0].to;
                    int t2 = g[v].getSons()[1].to;
                    if (t1 == u.to) t1 = g[v].getSons()[2].to;
                    if (t2 == u.to) t2 = g[v].getSons()[2].to;

                    int l1 = -1, l2 = -1;
                    for (auto x : leaves[t1]) {
                        if (x == -1) continue;
                        if (x != u.to) {
                            l1 = x;
                        }
                    }
                    for (auto x : leaves[t2]) {
                        if (x == -1) continue;
                        if (x != u.to && x != l1) {
                            l2 = x;
                        }
                    }
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = {leaves[v][0], leaves[v][1]};
                    pii b = {-1, -1};
                    for (auto x : leaves[u.to]) {
                        if (x == -1) continue;
                        if (a.first != x && a.second != x) {
                            if (b.first == -1) {
                                b.first = x;
                            } else {
                                b.second = x;
                            }
                        }
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](pii a, pii b) {
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        pii rez = {-1, -1};
        bool f = 1;
        vector<pii> tmp;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                if (tmp.size() == 2) continue;
                pii cur = findLeaves2(x.to, v);
                if (cur.first >= 0 || cur.second >= 0) {
                    tmp.push_back(cur);
                }
            }
        }
        if (f) {
            rez.first = v;
            return rez;
        }
        assert(tmp.size() == 2);
        return mrg(tmp[0], tmp[1]);
    };
    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    if (a.first == -1 || a.second == -1 || b.first == -1 || b.second  == -1) {
                        assert(false);
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    dfs(0, -1);
    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](const pii& a, const pii& b) {
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int)> findLeaves = [&](int v, int p) {
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                return findLeaves(x.to, v);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        bool f = 1;
        vector<pii> tmp;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                if (tmp.size() == 2) continue;
                pii cur = findLeaves2(x.to, v);
                if (cur.first != -1 || cur.second != -1) {
                    tmp.push_back(cur);
                }
            }
        }
        if (tmp.size() == 0) {
            return make_pair(v, -1);
        }
        return mrg(tmp[0], tmp[1]);
    };

    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1) {

                    int t1 = g[v].getSons()[0].to;
                    int t2 = g[v].getSons()[1].to;
                    if (t1 == u.to) t1 = g[v].getSons()[2].to;
                    if (t2 == u.to) t2 = g[v].getSons()[2].to;
                    int l1 = findLeaves(t1, v);
                    int l2 = findLeaves(t2, v);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {

                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    for (int i = 0; i < n; i++) {
        if (g[i].size() >= 3) {
            dfs(i, -1);
            break;
        }
    }

    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\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;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct Edge {
    int to, w;

    Edge(int _to = 0, int _w = 0) :
        to(_to), w(_w) {}
};

struct Node {
    vector<Edge> sons;

    void push(int to, int w) {
        sons.push_back({to, w});
    }
    vector<Edge>& getSons() {
        return sons;
    }

    int size() {
        return sons.size();
    }
};

struct Huita {
    int v, u, w;
    Huita(int _v, int _u, int _w) {
        v = _v;
        u = _u;
        w = _w;
    }
};

ostream& operator<< (ostream& out, const Huita& tmp) {
    out << tmp.v << ' ' << tmp.u << ' ' << tmp.w;
    return out;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<Node> g(n);
    vector<Edge> buf;
    for (int i = 0; i < n - 1; i++) {
        int v = nxt() - 1, u = nxt() - 1, w = nxt();
        g[v].push(u, w);
        g[u].push(v, w);
    }

    if (n == 2) {
        ok();
        cout << "1\n" << 1 << ' ' << 2 << ' ' << g[0].sons[0].w;
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        if (g[i].size() == 2) {
            no();
            return 0;
        }
    }
    auto mrg = [&](const pii& a, const pii& b) {
        return make_pair(max(a.first, a.second), max(b.first, b.second));
    };
    vector<Huita> ans;

    function<int(int, int, int)> findLeaves = [&](int v, int p, int nt) {
        for (auto x : g[v].getSons()) {
            if (x.to != p && x.to != nt) {
                return findLeaves(x.to, v, nt);
            }
        }
        return v;
    };
    function<pii(int, int)> findLeaves2 = [&](int v, int p) {
        bool f = 1;
        vector<pii> tmp;
        for (auto x : g[v].getSons()) {
            if (x.to != p) {
                f = 0;
                pii cur = findLeaves2(x.to, v);
                if (tmp.size() == 2) continue;
                if (cur.first >= 0 || cur.second >= 0) {
                    tmp.push_back(cur);
                }
            }
        }
        if (tmp.size() == 0) {
            return make_pair(v, -1);
        }
        return mrg(tmp[0], tmp[1]);
    };

    function<void(int, int)> dfs = [&](int v, int p) {
        for (const auto& u : g[v].getSons()) {
            if (u.to != p) {
                dfs(u.to, v);
                if (g[u.to].size() == 1 || g[v].size() == 1) {
                    int l1 = findLeaves(v, u.to, -1);
                    int l2 = findLeaves(l1, -1, u.to);
                    ans.push_back({u.to + 1, l1 + 1, u.w / 2});
                    ans.push_back({u.to + 1, l2 + 1, u.w / 2});
                    ans.push_back({l1 + 1, l2 + 1, -u.w / 2});
                } else {
                    pii a = findLeaves2(v, u.to);
                    pii b = findLeaves2(u.to, v);
                    if (a.first == -1 || a.second == -1 || b.first == -1 || b.second  == -1) {
                        assert(false);
                    }
                    ans.push_back({a.first + 1, b.first + 1, u.w / 2});
                    ans.push_back({a.second + 1, b.second + 1, u.w / 2});
                    ans.push_back({a.first + 1, a.second + 1, -u.w / 2});
                    ans.push_back({b.first + 1, b.second + 1, -u.w / 2});
                }
            }
        }
    };
    for (int i = 0; i < n; i++) {
        if (g[i].size() == 1) {
            dfs(i, -1);
            break;
        }
    }

    ok();
    cout << ans.size() << '\n';
    for (const auto& x : ans) {
        cout << x << '\n';
    }
    return 0;
}