#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, deg[N], fa[N];
int root = 0;
vector<pair<pair<int, int>, int> > ans;
struct edge {
  int to, val;
  edge() {}
  edge(int to, int val) : to(to), val(val) {}
};
vector<edge> G[N];
vector<int> leaf[N];
void add_edge(int x, int y, int z) { G[x].push_back(edge(y, z)); }
void init() {
  scanf("%d", &n);
  int x, y, z;
  if (n == 2) {
    scanf("%d%d%d", &x, &y, &z);
    printf("YES\n1\n1 2 %d\n", z);
    exit(0);
  }
  for (int i = 1; i < n; ++i) {
    scanf("%d%d%d", &x, &y, &z);
    add_edge(x, y, z);
    add_edge(y, x, z);
    ++deg[x], ++deg[y];
  }
}
void pre(int x, int f) {
  fa[x] = f;
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i].to, w = G[x][i].val;
    if (to == f) continue;
    pre(to, x);
    leaf[x].push_back(leaf[to][0]);
  }
  if (G[x].size() == 1) {
    leaf[x].push_back(x);
  }
}
void add_to_root(int x, int val) {
  if (leaf[x].size() >= 2) {
    int f1 = leaf[x][0], f2 = leaf[x][1];
    ans.push_back(make_pair(make_pair(root, f1), val / 2));
    ans.push_back(make_pair(make_pair(root, f2), val / 2));
    ans.push_back(make_pair(make_pair(f1, f2), -val / 2));
  } else {
    ans.push_back(make_pair(make_pair(root, x), val));
  }
}
void dfs(int x, int f) {
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i].to, w = G[x][i].val;
    if (to == f) continue;
    dfs(to, x);
    add_to_root(to, w);
    if (x != root) add_to_root(x, -w);
  }
}
void solve() {
  int flag = 1;
  for (int i = 1; i <= n; ++i) {
    if (deg[i] == 2) {
      puts("NO");
      return;
    }
  }
  puts("YES");
  for (int i = 1; i <= n; ++i) {
    if (G[i].size() == 1) {
      root = i;
      break;
    }
  }
  pre(root, 0);
  dfs(root, 0);
  printf("%d\n", ans.size());
  for (int i = 0; i < (int)ans.size(); ++i) {
    printf("%d %d %d\n", ans[i].first.first, ans[i].first.second,
           ans[i].second);
  }
}
int main() {
  init();
  solve();
  return 0;
}
