fun main(args: Array<String>) {

    /**
     * to:向き先
     * id:辺のID
     */
    data class Edge(val to: Int, val id: Int)


    // 頂点数
    val n = readLine()!!.toInt()

    /**
     * 次のようなグラフを作る
     * 1:[2]
     * 2:[1,3,4]
     * 3:[2]
     * 4:[2]
     */
    val graph: Array<MutableList<Edge>> = Array(n) {
        mutableListOf<Edge>()
    }

    // 頂点数-1回繰り返す
    repeat(n - 1) { i ->
        var (a, b) = readLine()!!.split(" ").map(String::toInt)
        a--
        b--
        graph[a].add(Edge(b, i))
        graph[b].add(Edge(a, i))
    }

    val ans = IntArray(n - 1)

    /**
     * v:頂点
     * p:どこからきたか
     */
    fun dfs(v: Int, color: Int, parent: Int) {
        var k = 1
        for (i in graph[v].indices) {
            val (to, edgeId) = graph[v][i]
            // 辺の向き先が親だった場合は、スキップする
            if (to == parent) {
                continue
            }

            // 親と同じ色だったらインクリメントする
            if (k == color) {
                k++
            }

            // idのところに解答を設定する
            ans[edgeId] = k
            k++
            dfs(to, ans[edgeId], v)
        }
    }

    dfs(0, -1, -1)
    ans.max()!!.let(::println)
    ans.forEach(::println)
}

