import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;


/**
 * Pick questions that you love and solve them with love, try to get AC in one
 * go with cleanest code Just one thing to keep in mind these questions should
 * be out of your reach, which make you step out of comfort zone Try to pick
 * them from different topics CP is a sport, enjoy it. Don't make it pressure
 * cooker or job ****Use pen and paper************* check few examples analyze
 * them, some not given in sample also analyze then code Use pen and paper.
 * Solve on paper then code. If there is some reasoning e.g. sequence/paths, try
 * printing first 100 elements or 100 answers using brute and observe.
 * *********Read question with extreme caution. Mistake is happening here which
 * costs time, WA and easy problem not getting solved.********* Sometimes we
 * make question complex due to misunderstanding. Prefix sum and suffix sum is
 * highly usable concept, look for it. Think of cleanest approach. If too many
 * if else are coming then its indication of WA. Solve 1-2 more questions than
 * you solved during contest.
 */
public class Codeforces {

	private static final String NEWLINE = "\n";
	private static final String SPACE = " ";

	public static void main(String args[]) throws IOException {
//		FastReader in = new FastReader(); use in case of millions of strings
		Reader in = new Reader();
//		int t = in.nextInt();
//		while (t-->0) {
			int n = in.nextInt();
			LinkedList<Integer> g[] = new LinkedList[n];
			for (int i=0;i<n;i++) g[i] = new LinkedList<Integer>();
			for (int i=0;i<n;i++) {
				int u = in.nextInt()-1, v = in.nextInt()-1;
				g[u].add(v);
				g[v].add(u);
			}
			int ans[] = new int[n];
			Arrays.fill(ans, -1);
			int cnt = 0;
			for (int i=0;i<n;i++) {
				if (g[i].size()<=2) continue;
				for (int v:g[i]) {
					if (ans[v] == -1) ans[v] = cnt++;
				}
			}
			
			for (int i=0;i<n;i++) {
				if (ans[i] == -1) ans[i] = cnt++;
				System.out.println(ans[i]);
			}
//		}
		in.close();
	}
	
	static class Pair {
		Integer x;
		Integer y;

		private Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public boolean equals(Object o) {
			if (o == null || !(o instanceof Pair))
				return false;
			Pair cor = (Pair) o;
			return x.equals(cor.x) && y.equals(cor.y);
		}

		@Override
		public int hashCode() {
			int result = 17;
			return result;
		}

		static class PairComparatorX implements Comparator<Pair> {

			@Override
			public int compare(Pair o1, Pair o2) {
				return o1.x.compareTo(o2.x);
			}

		}

		static class PairComparatorY implements Comparator<Pair> {

			@Override
			public int compare(Pair o1, Pair o2) {
				return o1.y.compareTo(o2.y);
			}

		}

	}
	
	static class Reader {
		/**
		 * When reading millions of strings try using FastReader if getting tle
		 */
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;
		Scanner in = new Scanner(System.in);

		public Reader() {
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader(String file_name) throws IOException {
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		String next() {
			return in.next();
		}

		public String readLine() throws IOException {
			byte[] buf = new byte[64]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1) {
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (c == '.') {
				while ((c = read()) >= '0' && c <= '9') {
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException {
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException {
			if (din == null)
				return;
			din.close();
			if (in == null) 
				return;
			in.close();
		}

	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			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;
		}
	}

}