import java.util.concurrent.LinkedBlockingQueue

fun main() {
    val n = readLine()?.toInt() ?: return

    data class Edge(val i: Int, val from: Int, val to: Int)

    val vertex = Array(n + 1) { false }
    val edge = Array(n - 1) { 0 }
    val edges = hashMapOf<Int, MutableList<Edge>>()
    repeat(n - 1) {
        val (a, b) = readLine()?.split(" ")?.map(String::toInt) ?: return
        edges.getOrPut(a) { mutableListOf() }.add(Edge(it, a, b))
        edges.getOrPut(b) { mutableListOf() }.add(Edge(it, b, a))
    }
    val root = edges.maxBy { it.value.size }!!
    val colorCount = root.value.size
    val queue = LinkedBlockingQueue<Pair<Int, Int>>()
    queue.add(Pair(root.key, 0))
    while (queue.isNotEmpty()) {
        val (i, connectedColor) = queue.poll()
        vertex[i] = true
        val v = edges[i]!!
        val r = 1.until(v.size + 1).toMutableList()
        r.remove(connectedColor)
        v.forEach {
            if (edge[it.i] == 0) {
                val c = r.first()
                edge[it.i] = c
                r.removeAt(0)
                if (!vertex[it.to]) {
                    queue.add(Pair(it.to, c))
                }
                if (!vertex[it.from]) {
                    queue.add(Pair(it.from, c))
                }
            }
        }
    }
    buildString {
        appendln(colorCount)
        append(edge.joinToString(separator = "\n"))
    }.let {
        println(it.trimIndent())
    }
}
