import java.io.{BufferedReader, InputStreamReader}

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

object Main {

  object Node {
    val id2Nodes: mutable.HashMap[Int, Node] = mutable.HashMap[Int, Node]()

    def getNode(id: Int): Node = id2Nodes.getOrElseUpdate(id, new Node(id))
  }

  class Node(val id: Int) {
    var parent: Option[Node] = None
    var children: mutable.HashSet[Node] = mutable.HashSet[Node]()

    override def toString: String = {
      "Node(" + id + ")"
    }
  }

  object Edge {
    val id2Edges: mutable.HashMap[Int, Edge] = mutable.HashMap[Int, Edge]()

    def setEdge(id: Int, parent: Node, child: Node): Edge = {
      val edge = new Edge(id, parent, child)
      id2Edges.update(id, edge)
      edge
    }

    def getEdge(id: Int): Edge = id2Edges.get(id) match {
      case Some(edge) => edge
      case None => throw new Exception()
    }
  }

  class Edge(val id: Int, val parent: Node, val child: Node) {
    var color: Int = -1

    override def toString: String = {
      "Edge(" + id + "," + parent + "," + child + ")"
    }
  }


  def main(args: Array[String]): Unit = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val n = in.readLine().toInt
    val parentNode2Edges = mutable.HashMap[Node, ArrayBuffer[Edge]]()
    val childNode2Edges = mutable.HashMap[Node, Edge]()

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

      parentNode2Edges.update(edge.parent, parentNode2Edges.getOrElseUpdate(edge.parent, ArrayBuffer[Edge]()) += edge)
      childNode2Edges.update(edge.child, edge)
    }

    def coloring(nodes: List[Node]): Unit = {
      nodes match {
        case node :: restNodes =>
          parentNode2Edges.get(node) match {
            case Some(edges) =>
              Stream.from(1).filter(!childNode2Edges.get(node).toList.map(_.color).contains(_)).zip(edges).foreach { case (color, edge) =>
                  edge.color = color
              }
              coloring(restNodes ++ edges.map(_.child))
            case None =>
              coloring(restNodes)
          }
        case Nil =>
      }
    }

    coloring(Node.getNode(1) :: Nil)

    System.out.println(Edge.id2Edges.values.map(_.color).max)

    for {
      i <- 1 until n
    } {
      System.out.println(Edge.getEdge(i).color)
    }
  }

}
