#include <bits/stdc++.h>
using namespace std;
struct edge {
  int u, v, w, s;
  edge(int u = 0, int v = 0, int w = 0, int s = 0) : u(u), v(v), w(w), s(s) {}
  void read() { scanf("%d%d", &(u), &(v)), scanf("%d%d", &(w), &(s)); }
  void reduce(int x) { w -= x, s -= x; }
  void show() { printf("%d %d %d %d\n", u, v, w, s); }
};
int n;
edge e[int(2e5 + 5)];
vector<int> T[int(2e5 + 5)];
long long dpmin[int(2e5 + 5)], dpmax[int(2e5 + 5)], dpw[int(2e5 + 5)];
void dfs1(int u = 1) {
  for (int i : T[u]) {
    int v = e[i].v, w = e[i].w, s = e[i].s;
    dfs1(v);
    if (dpmin[v] > s) {
      printf("-1\n");
      exit(0);
    }
    dpmax[v] = min(dpmax[v], (long long)s);
    dpmin[u] += w - min(w - 1ll, s - dpmin[v]) + dpmin[v];
    dpmax[u] += w + dpmax[v];
    dpw[u] += w + dpw[v];
  }
}
long long goal[int(2e5 + 5)];
inline void transfer(int u, int v, long long w) { goal[u] -= w, goal[v] += w; }
void dfs2(int u = 1) {
  for (int i : T[u]) {
    int v = e[i].v;
    transfer(u, v, dpw[v] - dpmax[v]);
  }
  for (int i : T[u]) {
    if (goal[u] == 0) break;
    int v = e[i].v;
    transfer(u, v, min(goal[u], dpmax[v] - dpmin[v]));
  }
  for (int i : T[u]) {
    int v = e[i].v, w = e[i].w, s = e[i].s;
    if (goal[u] > 0) {
      int tmp = min(goal[u], min(w - 1ll, s - dpmin[v]));
      goal[u] -= tmp;
      e[i].reduce(tmp);
    }
    dfs2(v);
  }
}
int main() {
  std::ios::sync_with_stdio(false);
  scanf("%d", &(n));
  for (long long i = 2, __R = n; i <= __R; i++) {
    e[i].read();
    T[e[i].u].push_back(i);
  }
  dfs1();
  goal[1] = dpw[1] - dpmax[1];
  dfs2();
  printf("%d\n", n);
  for (long long i = 2, __R = n; i <= __R; i++) e[i].show();
  return 0;
}
