import std.stdio, std.conv, std.string, std.range, std.algorithm, std.array,
  std.functional, std.container, std.typecons;

void main() {
  int N = readln.chomp.to!int;
  int[][] G = new int[][N];
  Tuple!(int, int)[] vp = new Tuple!(int, int)[0];
  foreach(ref r; G) r = new int[0];
  foreach(i; 1..N) {
    auto inp = readln.split.to!(int[]);
    int a = inp[0] - 1, b = inp[1] -1;
    G[a] ~= b;
    G[b] ~= a;
    vp ~= tuple(a, b);
  }

  int[Tuple!(int, int)] cv;
  ulong bfs() {
    int[] cn = new int[N];
    cn[0] = 0;
    bool[] seen = new bool[N];
    seen[0] = true;
    auto que = DList!int();
    que.insertBack(0);
    ulong K = 0;

    while(!que.empty()) {
      int v = que.front; que.removeFront();
      seen[v] = true;
      K = max(K, G[v].length);

      int c = 1;
      foreach(u; G[v]) {
        if(seen[u]) continue;
        if(c == cn[v]) c++;
        cv[tuple(v, u)] = cv[tuple(v, u)] = cn[u] = c;
        c++;
        que.insertBack(u);
      }
    }
    return K;
  }

  ulong K = bfs();
  K.writeln;
  foreach(v; vp) writeln(cv[v]);
}
