import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class DIV2C_Ehab_and_Path_etic_MEXs {

    private static final StreamTokenizer IN = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    private static final PrintWriter OUT = new PrintWriter(new OutputStreamWriter(System.out));

    private int n;
    private Map<Integer, List<Edge>> edges = new HashMap<>();
    private int[] ans;

    private class Edge {
        int index;
        int lable = -1;

        public Edge(int index) {
            this.index = index;
        }
    }

    private void input() {
        n = nextInt();
        ans = new int[n-1];
        Arrays.fill(ans, -1);

        for (int i = 0; i < n - 1; i++) {
            int u = nextInt();
            int v = nextInt();

            List<Edge> children = edges.getOrDefault(u, new ArrayList<>(8));
            children.add(new Edge(i));
            if (children.size() == 1) {
                edges.put(u, children);
            }

            children = edges.getOrDefault(v, new ArrayList<>(8));
            children.add(new Edge(i));
            if (children.size() == 1) {
                edges.put(v, children);
            }
        }
    }

    private void process() {
        AtomicInteger lable = new AtomicInteger(0);
        int root = -1;
        int maxChildren = Integer.MAX_VALUE;

        for (int i = 1; i < n; i++) {
            if (root == -1 || maxChildren < edges.get(i).size()) {
                root = i;
                maxChildren = edges.get(i).size();
            }
        }

        if (root != -1) {
            List<Edge> children = edges.get(root);
            for (int i = 0; i < children.size(); i++) {
                children.get(i).lable = i;
            }
        }

        edges.values().stream().flatMap(List::stream)
                .filter(e -> e.lable >= 0)
                .peek(e -> ans[e.index] = e.lable)
                .count();

        int mark = n - 2;

        for (int i = 0; i < n - 1; i++) {
            if (ans[i] == -1) {
                ans[i] = mark--;
            }
        }
    }

    private void output() {
        Arrays.stream(ans).forEach(System.out::println);
        OUT.flush();
    }

    private static int nextInt() {
        try {
            if (IN.nextToken() != StreamTokenizer.TT_EOF) {
                return (int) IN.nval;
            } else {
                throw new EOFException();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static String nextStr() {
        try {
            if (IN.nextToken() != StreamTokenizer.TT_EOF) {
                return IN.sval;
            } else {
                throw new EOFException();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws IOException {
        DIV2C_Ehab_and_Path_etic_MEXs main = new DIV2C_Ehab_and_Path_etic_MEXs();
        main.input();
        main.process();
        main.output();
    }
}
