Problem:
Score : 400 points

Problem Statement

Given is a tree G with N vertices.
The vertices are numbered 1 through N, and the i-th edge connects Vertex a_i and Vertex b_i.

Consider painting the edges in G with some number of colors.
We want to paint them so that, for each vertex, the colors of the edges incident to that vertex are all different.

Among the colorings satisfying the condition above, construct one that uses the minimum number of colors.

Constraints

2 \le N \le 10^5

1 \le a_i \lt b_i \le N

All values in input are integers.

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
\vdots
a_{N-1} b_{N-1}

Output

Print N lines.

The first line should contain K, the number of colors used.

The (i+1)-th line (1 \le i \le N-1) should contain c_i, the integer representing the color of the i-th edge, where 1 \le c_i \le K must hold.

If there are multiple colorings with the minimum number of colors that satisfy the condition, printing any of them will be accepted.

Sample Input 1

3
1 2
2 3

Sample Output 1

2
1
2

Sample Input 2

8
1 2
2 3
2 4
2 5
4 7
5 6
6 8

Sample Output 2

4
1
2
3
4
1
1
2

Sample Input 3

6
1 2
1 3
1 4
1 5
1 6

Sample Output 3

5
1
2
3
4
5

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

// TODO: 計算量が非常に多い気がする.
#include <bits/stdc++.h>
using namespace std;
#define repex(i, a, b, c) for(int i = a; i < b; i += c)
#define repx(i, a, b) repex(i, a, b, 1)
#define rep(i, n) repx(i, 0, n)
#define pb push_back
#define a first
#define b second
const int MAX = 101010;
int memo[MAX];
vector<int> graph[MAX];
map<pair<int, int>, int> m; // 着色時の頂点ペア, 色を保存.
vector<pair<int, int>> o;   // 入力時の頂点ペアを保存.
set<int> color[MAX];
int maxColor;

// グラフを幅優先探索する.
// https://ja.wikipedia.org/wiki/幅優先探索
// ※bfsの動作確認用.
// @param s: 探索開始の頂点番号.
// @return: 特に無し.
void bfs(int s){
    
    // 1. 空のキュー.
    queue<int> q;
    
    // 2. 訪問済みフラグ設定.
    // ※スタート地点は, 距離ゼロを指定.
    memo[s] = 0;
    
    // 3. 探索地点 s をキュー q に追加.
    q.push(s);
    
    // 4. キュー q が 空になるまで, 探索.
    while(!q.empty()){
        
        // 5. 頂点 u を キュー q から取り出す.
        int u = q.front();
        q.pop();
        
        // 6. 取り出した要素を処理.
        int c = 1;
        for(auto &e : graph[u]){
            // 6-1. 頂点u の 隣接する頂点e が, 未訪問だったら, キュー q に追加.
            if(memo[e] == 0 && e != s){
                // 頂点e を キュー q に追加.
                q.push(e);
                // 頂点e に 距離memo[u] プラス 1 を 加算.
                memo[e] += (memo[u] + 1);
                // 色を着色.
                // すでに使用している色があれば, Skip.
                while(color[u].count(c) != 0) c++;
                color[u].insert(c);
                color[e].insert(c);
                m[{u, e}] = c;
                m[{e, u}] = c;
                // 必要とする色の最大数を更新.
                maxColor = max(maxColor, c);
            }
        }
    }
}

int main(){
    
    // 1. 入力情報.
    int N, a, b;
    scanf("%d", &N);
    
    // 2. グラフ作成.
    rep(i, N - 1){
        scanf("%d %d", &a, &b);
        a--, b--;
        graph[a].pb(b);
        graph[b].pb(a);
        o.pb({a, b}); // オリジナルの入力情報.
    }
    
    // 3. 頂点 0 から 探索.
    bfs(0);
    // rep(i, N) printf("%d ", memo[i]);
    // printf("\n");
    // printf("maxColor=%d\n", maxColor);
    // for(auto &p : m) printf("a=%d b=%d c=%d\n", p.a.a, p.a.b, p.b);
    
    // 4. 出力.
    printf("%d\n", maxColor);
    for(auto &p : o) printf("%d\n", m[p]);
    return 0;

}