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.io.*;
import java.util.*;
import java.math.*;
import java.awt.Point;
 
public class Code {
	//static final long MOD = 998244353L;
	//static final long INF = -1000000000000000007L;
	//static final long MOD = 1000000007L;
	static final int INF = 1000000007;
	
	static ArrayList<Integer>[] tree;
	static int[] numChildren;
	static int root;
	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		PrintWriter pw = new PrintWriter(System.out);
		int N = sc.ni();
		tree = new ArrayList[N];
		for (int i = 0; i < N; i++) {
			tree[i] = new ArrayList<Integer>();
		}
		int[] C = new int[N];
		numChildren = new int[N];
		Arrays.fill(numChildren,-1);
		int[] parents = new int[N];
		for (int i = 0; i < N; i++) {
			parents[i] = sc.ni()-1;
			C[i] = sc.ni();
			if (parents[i] >= 0)
				tree[parents[i]].add(i);
			else
				root = i;
		}
		for (int i = 0; i < N; i++) {
			if (tree[i].size() == 0) {
				numChildren[i] = 0;
			}
		}
		numChildren[root] = children(root);
		
		//pw.println(Arrays.toString(numChildren));
		int num = N;
		int[] nums = new int[N];
		while (num > 0) {
			//Find the highest up "biggest node"
			boolean[] visited = new boolean[N];
			visited[root] = true;
			ArrayDeque<Integer> bfs = new ArrayDeque<Integer>();
			bfs.add(root);
			int next = -1;
			while (! bfs.isEmpty()) {
				int node = bfs.poll();
				if (nums[node] == 0 && numChildren[node] == C[node]) {
					next = node;
					break;
				}
				
				for (int child: tree[node]) {
					if (!visited[child]) {
						bfs.add(child);
						visited[child] = true;
					}
				}
			}
			
			if (next == -1) {
				pw.println("NO");
				pw.close();
				return;
			}
			
			nums[next] = num;
			int parent = parents[next];
			while (parent >= 0) {
				numChildren[parent] -= 1;
				parent = parents[parent];
			}
			num--;
		}
		pw.println("YES");
		for (int n: nums) {
			pw.print(n + " ");
		}
		pw.close();
	}
	
	public static int children(int node) {
		int ans = tree[node].size();
		for (int child: tree[node]) {
			if (numChildren[child] >= 0) {
				ans += numChildren[child];
			} else {
				ans += children(child);
			}
		}
		numChildren[node] = ans;
		return ans;
	}
	
	//Find the GCD of two numbers
	public static long gcd(long a, long b) {
		if (b == 0)
			return a;
		else
			return gcd(b,a%b);
	}
	
	//Fast exponentiation (x^y mod m)
	public static long power(long x, long y, long m) { 
		long ans = 1;
		x %= m;
		while (y > 0) { 
			if(y % 2 == 1) 
				ans = (ans * x) % m; 
			y /= 2;  
			x = (x * x) % m;
		} 
		return ans; 
	}
	
	public static int[][] shuffle(int[][] array) {
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    int[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		return array;
	}
	
    public static int[][] sort(int[][] array) {
    	//Sort an array (immune to quicksort TLE)

		Arrays.sort(array, new Comparator<int[]>() {
			  @Override
        	  public int compare(int[] arr1, int[] arr2) {
				  return arr1[1]-arr2[1]; //ascending order
	          }
		});
		return array;
	}
    
    public static long[][] sort(long[][] array) {
    	//Sort an array (immune to quicksort TLE)
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    long[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		Arrays.sort(array, new Comparator<long[]>() {
			  @Override
        	  public int compare(long[] arr1, long[] arr2) {
				  return 0;
	          }
		});
		return array;
	}
    
    static class FastScanner { 
        BufferedReader br; 
        StringTokenizer st; 
  
        public FastScanner() { 
            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 ni() { 
            return Integer.parseInt(next()); 
        } 
  
        long nl() { 
            return Long.parseLong(next()); 
        } 
  
        double nd() { 
            return Double.parseDouble(next()); 
        } 
  
        String nextLine() { 
            String str = ""; 
            try { 
                str = br.readLine(); 
            } catch (IOException e) {
                e.printStackTrace(); 
            } 
            return str;
        }
    }
}