import java.util.*

fun readString() = readLine()!!
fun readInt() = readLine()!!.toInt()
fun readLong() = readLine()!!.toLong()
fun readIntList() = readLine()!!.split(" ").map(String::toInt)
fun readLongList() = readLine()!!.split(" ").map(String::toLong)

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

fun main(args: Array<String>) {
    val N = readInt()
    val graph = Array(N) { mutableListOf<Int>() }
    val edges = Array(N - 1) { Edge(-1, -1) }

    for (i in 0 until N - 1) {
        val tmp = readIntList()
        edges[i] = Edge(tmp[0] - 1, tmp[1] - 1)
        graph[edges[i].from].add(edges[i].to)
        graph[edges[i].to].add(edges[i].from)
    }

    val colorMap: MutableMap<Edge, Int> = mutableMapOf()
    var K = 0
    val isUsed = Array(N) { false }
    isUsed[0] = true
    val parentColor = Array(N) { 0 }

    val queue = ArrayDeque<Int>()
    queue.add(0)

    while (queue.isNotEmpty()) {
        val node = queue.pop()
        K = graph[node].size.coerceAtLeast(K)
        var currentColor = 1

        for (i in graph[node]) {
            if (isUsed[i]) continue
            if (currentColor == parentColor[node]) currentColor++
            parentColor[i] = currentColor
            colorMap[Edge(node, i)] = currentColor
            colorMap[Edge(i, node)] = currentColor
            currentColor++
            isUsed[i] = true
            queue.add(i)
        }
    }

    println(K)
    for (edge in edges) {
        println(colorMap[edge])
    }
}
