import java.io.{BufferedReader, InputStreamReader}

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

object Main {

  type Node = Int
  type Edge = (Int, Int)

  def main(args: Array[String]): Unit = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val n = in.readLine().toInt

    val nodes = new Array[Node](n)
    val edges = new Array[Edge](n - 1)
    val colors = new Array[Int](n - 1)
    var maxColor = Int.MinValue

    val parentNode2EdgeIds = new Array[ArrayBuffer[Int]](nodes.length)
    for {i <- parentNode2EdgeIds.indices} {
      parentNode2EdgeIds(i) = ArrayBuffer[Int]()
    }
    val childNode2EdgeIds = new Array[Int](nodes.length)

    for {
      i <- 1 until n
    } {
      val edge = in.readLine().split("\\s+").map(_.toInt) match {
        case Array(a, b) => (a, b)
      }

      edges(i - 1) = edge

      parentNode2EdgeIds(edge._1 - 1) += i
      childNode2EdgeIds(edge._2 - 1) = i
    }

    def coloring(nodes: List[Node]): Unit = {
      nodes match {
        case node :: restNodes =>
          val edgeIds = parentNode2EdgeIds(node - 1)
          if (edgeIds != null) {
            val skipColors = (childNode2EdgeIds(node - 1) match {
              case 0 => None
              case edgeId => Some(colors(edgeId - 1))
            }).toList

            Stream.from(1).filter(!skipColors.contains(_)).zip(edgeIds).foreach { case (color, edgeId) =>
              colors(edgeId - 1) = color
              maxColor = Math.max(maxColor, color)
            }
            coloring(restNodes ++ edgeIds.map(edgeId => edges(edgeId - 1)._2))
          } else {
            coloring(restNodes)
          }
        case Nil =>
      }
    }

    coloring(1 :: Nil)

    System.out.println(maxColor)

    for {
      i <- 0 until n-1
    } {
      System.out.println(colors(i))
    }
  }

}
