Evlampiy was gifted a rooted tree. The vertices of the tree are numbered from 1 to n. Each of its vertices also has an integer a_i written on it. For each vertex i, Evlampiy calculated c_i — the number of vertices j in the subtree of vertex i, such that a_j < a_i. 

<image>Illustration for the second example, the first integer is a_i and the integer in parentheses is c_i

After the new year, Evlampiy could not remember what his gift was! He remembers the tree and the values of c_i, but he completely forgot which integers a_i were written on the vertices.

Help him to restore initial integers!

Input

The first line contains an integer n (1 ≤ n ≤ 2000) — the number of vertices in the tree.

The next n lines contain descriptions of vertices: the i-th line contains two integers p_i and c_i (0 ≤ p_i ≤ n; 0 ≤ c_i ≤ n-1), where p_i is the parent of vertex i or 0 if vertex i is root, and c_i is the number of vertices j in the subtree of vertex i, such that a_j < a_i.

It is guaranteed that the values of p_i describe a rooted tree with n vertices.

Output

If a solution exists, in the first line print "YES", and in the second line output n integers a_i (1 ≤ a_i ≤ {10}^{9}). If there are several solutions, output any of them. One can prove that if there is a solution, then there is also a solution in which all a_i are between 1 and 10^9.

If there are no solutions, print "NO".

Examples

Input


3
2 0
0 2
2 0


Output


YES
1 2 1 

Input


5
0 1
1 3
2 1
3 0
2 0


Output


YES
2 3 2 1 2
#include <bits/stdc++.h>
using namespace std;
const int N = 20001;
int ans[N];
int f[N];
int sub[N];
int num[N];
struct node {
  int g, index;
  node(int g, int index) : g(g), index(index) {}
};
vector<node> vt[N];
void merge(vector<node>& f, vector<node>& s) {
  vector<node> tmp;
  for (int i = 0, j = 0; i < f.size() || j < s.size();) {
    if (i >= f.size()) {
      tmp.push_back(s[j]);
      j++;
      continue;
    }
    if (j >= s.size()) {
      tmp.push_back(f[i]);
      i++;
      continue;
    }
    if (f[i].g < s[j].g) {
      tmp.push_back(f[i]);
      i++;
    } else {
      tmp.push_back(s[j]);
      j++;
    }
  }
  f = move(tmp);
}
int main() {
  int n;
  while (cin >> n) {
    memset(f, 0, sizeof(f));
    memset(num, 0, sizeof(num));
    memset(sub, 0, sizeof(sub));
    memset(ans, 0, sizeof(ans));
    for (int i = 0; i < N; ++i) {
      vt[i].clear();
    }
    for (int i = 1; i <= n; ++i) {
      int p, k;
      cin >> p >> k;
      num[i] = k;
      f[i] = p;
      sub[p]++;
    }
    stack<int> st;
    for (int i = 1; i <= n; ++i) {
      if (sub[i] == 0) {
        st.push(i);
      }
    }
    bool has_ans = true;
    while (!st.empty()) {
      int index = st.top();
      st.pop();
      int k = num[index];
      if (vt[index].size() < k) {
        has_ans = false;
        break;
      }
      vt[index].insert(vt[index].begin() + k, node(0, index));
      for (int i = k; i < vt[index].size(); ++i) {
        if (i == k) {
          if (i - 1 >= 0) {
            vt[index][i].g = vt[index][i - 1].g + 1;
          } else {
            vt[index][i].g = 1;
          }
          continue;
        }
        if (i == k + 1) {
          if (vt[index][i].g >= vt[index][k].g) {
            break;
          }
        }
        vt[index][i].g++;
      }
      int p = f[index];
      if (0 == p) {
        for (int i = 0; i < vt[index].size(); ++i) {
          ans[vt[index][i].index] = vt[index][i].g;
        }
        break;
      }
      merge(vt[p], vt[index]);
      sub[p]--;
      if (0 == sub[p]) {
        st.push(p);
      }
    }
    if (!has_ans) {
      cout << "NO" << endl;
    } else {
      cout << "YES" << endl;
      for (int i = 1; i <= n; ++i) {
        cout << ans[i];
        if (i != n) {
          cout << " ";
        }
      }
      cout << endl;
    }
  }
  return 0;
}
