#include <bits/stdc++.h>
using namespace std;
const int mn = 1005;
const int mod = 1000000007;
int n;
vector<int> g[mn];
struct edge {
  int u, v, w, id;
  int to(int x) { return x == u ? v : u; }
  void read(int i) {
    scanf("%d%d%d", &u, &v, &w);
    id = i;
  }
} e[mn];
inline bool isLeaf(int x) { return (int)g[x].size() == 1; }
bool spj() {
  for (int i = 1; i <= n; i++)
    if ((int)g[i].size() == 2) {
      puts("NO");
      exit(0);
    }
}
vector<tuple<int, int, int>> ans;
inline int findLeaf(int x, int fa) {
  if (isLeaf(x)) return x;
  for (auto &i : g[x]) {
    if (e[i].to(x) != fa) {
      return findLeaf(e[i].to(x), x);
    }
  }
}
pair<int, int> findLeaves(int x, int fa) {
  pair<int, int> ans(0, 0);
  for (auto &i : g[x]) {
    if (e[i].to(x) != fa) {
      if (ans.first == 0)
        ans.first = findLeaf(e[i].to(x), x);
      else
        ans.second = findLeaf(e[i].to(x), x);
    }
  }
  return ans;
}
void flow(int x) {
  edge E = e[x];
  if (isLeaf(E.u) || isLeaf(E.v)) {
    if (isLeaf(E.u)) swap(E.u, E.v);
    if (isLeaf(E.u)) {
      ans.push_back({E.u, E.v, E.w});
    } else {
      pair<int, int> u = findLeaves(E.u, E.v);
      ans.push_back({u.first, E.v, E.w / 2});
      ans.push_back({u.second, E.v, E.w / 2});
      ans.push_back({u.first, u.second, -E.w / 2});
    }
  } else {
    pair<int, int> u = findLeaves(E.u, E.v);
    pair<int, int> v = findLeaves(E.v, E.u);
    ans.push_back({u.first, v.first, E.w / 2});
    ans.push_back({u.second, v.second, E.w / 2});
    ans.push_back({u.first, u.second, -E.w / 2});
    ans.push_back({v.first, v.second, -E.w / 2});
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    e[i].read(i);
    g[e[i].u].push_back(i);
    g[e[i].v].push_back(i);
  }
  spj();
  puts("YES");
  for (int i = 1; i < n; i++) {
    flow(i);
  }
  printf("%d\n", (int)ans.size());
  for (auto &i : ans) printf("%d %d %d\n", get<0>(i), get<1>(i), get<2>(i));
  return 0;
}
