Problem: You are given a tree consisting of n nodes. You want to write some labels on the tree's edges such that the following conditions hold:

  * Every label is an integer between 0 and n-2 inclusive. 
  * All the written labels are distinct. 
  * The largest value among MEX(u,v) over all pairs of nodes (u,v) is as small as possible. 



Here, MEX(u,v) denotes the smallest non-negative integer that isn't written on any edge on the unique simple path from node u to node v.

Input

The first line contains the integer n (2 ≤ n ≤ 10^5) — the number of nodes in the tree.

Each of the next n-1 lines contains two space-separated integers u and v (1 ≤ u,v ≤ n) that mean there's an edge between nodes u and v. It's guaranteed that the given graph is a tree.

Output

Output n-1 integers. The i^{th} of them will be the number written on the i^{th} edge (in the input order).

Examples

Input


3
1 2
1 3


Output


0
1


Input


6
1 2
1 3
2 4
2 5
5 6


Output


0
3
2
4
1

Note

The tree from the second sample:

<image>

Solution (in JAVA):

Solution:
import java.util.*;
import java.lang.*;
import java.io.*;

public class C {
	private static FastReader fr;
	private static OutputStream out;
	private static int mod = (int)(1e9+7);

	private void solve() {
		int n = fr.nextInt();
		HashMap<Integer, HashMap<Integer, Integer>> g = new HashMap<>();
		for(int i=1;i<=n;i++) {
			g.put(i, new HashMap<>());
		}
		
		int arr[][] = new int[n-1][2];
		for(int i=0;i<n-1;i++) {
			int x = fr.nextInt();
			int y = fr.nextInt();
			arr[i][0] = x;
			arr[i][1] = y;
			
			g.get(x).put(y, -1);
			g.get(y).put(x, -1);
		}
		
		if(n == 2) {
			println(0);
			return;
		}
		
		HashSet<Integer> set = new HashSet<>();
		set.add(0);
		set.add(1);
		set.add(2);
		
		Stack<Integer> st = new Stack<>();
		for(int i=3;i<n-1;i++) {
			st.add(i);
		}
		
//		for(int i=1;i<=n;i++) {
//			int x = i;
//			for(int val: g.get(x).keySet()) {
//				println(x + " " + val);
//			}
//		}
		
		for(int i=1;i<=n;i++) {
			
			if(g.get(i).size() == 1 && set.size() > 0) {
				int x = i;
//				int y = g.get(i).get(0);
				
				for(int y: g.get(i).keySet()) {
					if(set.contains(0)) {
						g.get(x).put(y, 0);
						g.get(y).put(x, 0);
						set.remove(0);
					}else if(set.contains(1)) {
						g.get(x).put(y, 1);
						g.get(y).put(x, 1);
						set.remove(1);
					}else if(set.contains(2)) {
						g.get(x).put(y, 2);
						g.get(y).put(x, 2);
						set.remove(2);
					}
				}
			} 
		}
		
		for(int val: set) {
			st.add(val);
		}
		
		for(int i=1;i<n;i++) {
			HashMap<Integer, Integer> map = g.get(i);
			for(int y: map.keySet()) {
				if(map.get(y) == -1) {
					int val = st.pop(); 
					g.get(i).put(y, val);
					g.get(y).put(i, val);
				}
			}
		}
		
		for(int i=0;i<n-1;i++) {
			int x = arr[i][0];
			int y = arr[i][1];
			println(g.get(x).get(y));
		}
		
	}

	public static void main(String args[]) throws IOException{
		new C().run();
	}
	
	private ArrayList<Integer> factors(int n, boolean include){
		ArrayList<Integer> factors = new ArrayList<>();
		if(n < 0)
			return factors;
		
		if(include) {
			factors.add(1);
			if(n > 1)
				factors.add(n);
		}
		
		int i = 2;
		for(;i*i<n;i++) {
			if(n % i == 0) {
				factors.add(i);
				factors.add(n / i);
			}
		}
		
		if(i * i == n) {
			factors.add(i);
		}
		
		return factors;
	}
	
	private ArrayList<Integer> PrimeFactors(int n) {
	    ArrayList<Integer> primes = new ArrayList<>();
	 
	    int i = 2;
	    while (i * i <= n) {
	      if (n % i == 0) {
	        primes.add(i);
	 
	        while (n % i == 0) {
	          n /= i;
	        }
	      }
	 
	      i++;
	    }
	 
	    if (n > 1) {
	      primes.add(n);
	    }
	 
	    return primes;
	  }
	
	private boolean isPrime(int n) {
		if(n == 0 || n == 1) {
			return false;
		}
		
		if(n % 2 == 0) {
			return false;
		}
		
		for(int i=3;i*i<=n;i+=2) {
			if(n % i == 0) {
				return false;
			}
		}
		
		return true;
	}

	private ArrayList<Integer> Sieve(int n){
		boolean bool[] = new boolean[n+1];
		Arrays.fill(bool, true);
		bool[0] = bool[1] = false;
		
		for(int i=2;i*i<=n;i++) {
			if(bool[i]) {
				int j = 2;
				while(i*j <= n) {
					bool[i*j] = false;
					j++;
				}
			}
		}
		
		ArrayList<Integer> primes = new ArrayList<>();
		for(int i=2;i<=n;i++) {
			if(bool[i])
				primes.add(i);
		}
		
		return primes;
	}
	
	private HashMap<Integer, Integer> addToHashMap(HashMap<Integer, Integer> map, int arr[]){
		for(int val: arr) {
			if(!map.containsKey(val)) {
				map.put(val, 1);
			}else {
				map.put(val, map.get(val) + 1);
			}
		}
		return map;
	}
	
	private int factorial(int n) {
		long fac = 1;
		for(int i=2;i<=n;i++) {
			fac *= i;
			fac %= mod;
		}
		return (int)(fac % mod);
	}

	private static int pow(int base,int exp){
		if(exp == 0){
			return 1;
		}else if(exp == 1){
			return base;
		}
		int a = pow(base,exp/2);
		a = ((a % mod) * (a % mod)) % mod;
		if(exp % 2 == 1) {
			a = ((a % mod) * (base % mod));
		}
		return a;
	}

	private static int gcd(int a,int b){
		if(a == 0){
			return b;
		}
		
		return gcd(b%a,a);
	}
	
	private static int lcm(int a,int b){
		return (a * b)/gcd(a,b);
	}
	
	private void run() throws IOException{
		fr = new FastReader();
		out = new BufferedOutputStream(System.out);
		solve();
		out.flush();
		out.close();
	}
	
	private static class FastReader{
		private static BufferedReader br; 
		private static StringTokenizer st;
		
		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new BufferedOutputStream(System.out);
		}
		
		public String next() {
			while (st == null || !st.hasMoreElements()) 
			{ 
				try
				{ 
					st = new StringTokenizer(br.readLine()); 
				} 
				catch (IOException e) 
				{ 
					e.printStackTrace(); 
				} 
			} 
			return st.nextToken();
		}
		
		public String nextLine() { 
			String str = ""; 
			try
			{ 
				str = br.readLine(); 
			} 
			catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
			return str; 
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		 
		public char[] nextCharArray() {
			return next().toCharArray();
		}
		
		public int[] nextIntArray(int n) {
			int arr[] = new int[n];
			for(int i=0;i<n;i++) {
				arr[i] = nextInt();
			}
			return arr;
		}
		
		public long[] nextLongArray(int n) {
			long arr[] = new long[n];
			for(int i=0;i<n;i++) {
				arr[i] = nextLong();
			}
			return arr;
		}
		
		public String[] nextStringArray(int n) {
			String arr[] = new String[n];
			for(int i=0;i<n;i++) {
				arr[i] = next();
			}
			return arr;
		}
		
	}

	public static void print(Object str) {
        try {
            out.write(str.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
	public static void println(Object str) {
        try {
            out.write((str.toString() + "\n").getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
	public static void println() {
		println("");
	}
	
	public static void printArray(Object str[]){
		for(Object s : str) {
			try {
	            out.write(str.toString().getBytes());
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
		}
	}
}