import java.io.PrintWriter
import java.util.ArrayDeque

fun main(args: Array<String>) {
    PrintWriter(System.out).use { out ->
        solve(out)
        out.flush()
    }
}


/** edge info */
data class Edge<T>(val to: Int, var cost: T, var index: Int)

fun solve(out: PrintWriter) {
    val n = readInteger()
    val edges = Array(n) { mutableListOf<Edge<Int>>() }
    repeat(n - 1) {
        val (a, b) = readIntegerList().map { it - 1 }
        edges[a].add(Edge(b, 1, it))
        edges[b].add(Edge(a, 1, it))
    }

    val ansArray = IntArray(n - 1)
    val usedColorSetList = Array(n) { mutableSetOf<Int>() }
    val isUnchecked = BooleanArray(edges.size) { true }
    val nodeQueue = ArrayDeque<Int>()
    nodeQueue.addLast(0)
    isUnchecked[0] = false
    while (nodeQueue.isNotEmpty()) {
        val node = nodeQueue.removeFirst()

        var unusedColor = 0
        for (edge in edges[node]) {
            if (isUnchecked[edge.to]) {
                for (i in (unusedColor + 1)..n) {
                    if (usedColorSetList[node].contains(i) == false) {
                        unusedColor = i
                        break
                    }
                }
                ansArray[edge.index] = unusedColor
                usedColorSetList[node].add(unusedColor)
                usedColorSetList[edge.to].add(unusedColor)

                isUnchecked[edge.to] = false
                nodeQueue.addLast(edge.to)
            }
        }
    }
    println(ansArray.max())
    println(ansArray.joinToString("\n"))
}

fun readInteger() = readLine()!!.toInt()
fun readLong() = readLine()!!.toLong()
fun readStringList() = readLine()!!.split(" ")
fun readIntegerList() = readStringList().map(String::toInt)
fun readLongList() = readStringList().map(String::toLong)
fun readDoubleList() = readStringList().map(String::toDouble)
