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
import java.util.*;
import java.io.*;

public class B612 {
    static ArrayList<Integer> [] adj;
    static int [] c, a, sz;
    static boolean bad;
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        int n = sc.nextInt();
        adj = new ArrayList[n + 1]; sz = new int[n + 1];
        c = new int[n + 1]; a = new int[n + 1];
        for (int i = 1; i <= n; i++) adj[i] = new ArrayList<>();
        int root = -1;
        for (int i = 1; i <= n; i++) {
            int p = sc.nextInt(); int less = sc.nextInt();
            c[i] = less;
            if (p == 0) {
                root = i; continue;
            }
            adj[p].add(i);
            adj[i].add(p);
        }
        ArrayList<Integer> vals = new ArrayList<>();
        for (int i = 1; i <= n; i++) vals.add(i);
        dfs1(root, -1);
        dfs(root, -1, vals);
        if (bad) {
            out.println("NO");
        } else {
            out.println("YES");
            for (int i = 1; i <= n; i++) out.print(a[i] + " ");
        }
        out.close();
    }

    static void dfs1(int cur, int par) {
        sz[cur] = 1;
        for (Integer next: adj[cur]) {
            if (next != par) {
                dfs1(next, cur);
                sz[cur] += sz[next];
            }
        }
    }

    static void dfs(int cur, int par, ArrayList<Integer> vals) {
        int seen = 0;
        if (c[cur] >= sz[cur]) {
            bad = true;
            return;
        }
        for (Integer i: vals) {
            if (seen == c[cur]) {
                a[cur] = i;
            }
            ++seen;
        }
        vals.remove((Object) a[cur]);
        int idx = 0; boolean ok = true;
        for (Integer next: adj[cur]) {
            if (next != par) {
                 ArrayList<Integer> add = new ArrayList<>();
                 if (idx + sz[next] - 1 > vals.size() - 1) {
                     ok = false; break;
                 }
                 int finish = idx + sz[next] - 1;
                 for (; idx <= finish; idx++) {
                     add.add(vals.get(idx));
                 }
                 idx = finish + 1;
                 dfs(next, cur, add);
            }
        }
        if (!ok) {
            bad = true;
        }
    }


    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }


    }

}