{-# LANGUAGE BangPatterns #-}

module Main where

import Data.Foldable
import Data.Traversable
import qualified Data.HashMap.Strict as HM
import qualified Data.Sequence as S
import qualified Data.Vector.Mutable as MV

type Map = HM.HashMap Int

newtype Id = Id
    { unId :: Int
    } deriving (Eq, Show)

newtype Color = Color
    { unColor :: Int
    } deriving (Eq, Show)

data Node = Node
    { nId    :: !Id
    , nNodes :: !(S.Seq Id)
    , nEdges :: !(S.Seq Id)
    } deriving Show

data Edge = Edge
    { eId    :: !Id
    , eVertA :: !Id
    , eVertB :: !Id
    , eColor :: !Color
    } deriving Show

main :: IO ()
main = do
    n    <- read <$> getLine :: IO Int
    iabs <- forM [1..n-1] $ \id -> do
        a:b:_ <- map read . words <$> getLine
        return (Id id, Id a, Id b)
    let !nodes = createNodes $ map Id [1..n]
    let !edges = createEdges iabs
    let !constructedNodes = constructNodes nodes edges
    let !constructedEdges = constructEdges constructedNodes edges
    print $ foldl max 0 $ map (unColor . eColor) $ HM.elems constructedEdges
    forM_ constructedEdges $ \edge -> print $ unColor $ eColor edge

createNodes :: [Id] -> Map Node
createNodes ids = foldl insertNode HM.empty ids
    where
    insertNode :: Map Node -> Id -> Map Node
    insertNode m id = HM.insert (unId id) (newNode id) m

    newNode :: Id -> Node
    newNode id = Node id S.empty S.empty

    n :: Int
    !n = length ids

createEdges :: [(Id, Id, Id)] -> Map Edge
createEdges = foldl insertEdge HM.empty
    where
    insertEdge :: Map Edge -> (Id, Id, Id) -> Map Edge
    insertEdge m (id, a, b) = HM.insert (unId id) (newEdge id a b) m

    newEdge :: Id -> Id -> Id -> Edge
    newEdge id a b = Edge id a b $ Color 0

constructNodes :: Map Node -> Map Edge -> Map Node
constructNodes = foldl connectNodes
    where
    connectNodes :: Map Node -> Edge -> Map Node
    connectNodes nodes edge =
        foldl insertInMap nodes [insertVertA, insertVertB]
        where
        insertInMap :: Map Node -> Node -> Map Node
        insertInMap m node = HM.insert (unId $ nId node) node m

        insertVertA :: Node
        !insertVertA = storeNode vertA (nId vertB) (eId edge)

        insertVertB :: Node
        !insertVertB = storeNode vertB (nId vertA) (eId edge)

        vertA :: Node
        !vertA = extractNode edge eVertA
        
        vertB :: Node
        !vertB = extractNode edge eVertB

        extractNode :: Edge -> (Edge -> Id) -> Node
        extractNode edge vert = nodes HM.! unId (vert edge)
    
    storeNode :: Node -> Id -> Id -> Node
    storeNode node nId eId =
        node { nNodes = nId S.:<| nodes, nEdges = eId S.:<| edges }
        where
        nodes :: S.Seq Id
        !nodes = nNodes node

        edges :: S.Seq Id
        !edges = nEdges node

constructEdges :: Map Node -> Map Edge -> Map Edge
constructEdges nodes =
    constructOneEdge (Id 0) (Color 0) (nodes HM.! 1)
    where
    constructOneEdge :: Id -> Color -> Node -> Map Edge -> Map Edge
    constructOneEdge prevId prevColor node edges =
        foldl constructNextEdges newEdges nexts
        where
        constructNextEdges m (nextNode, nextEdge, nextColor) =
            constructOneEdge (nId node) nextColor (nodes HM.! unId nextNode) m
        
        nextNodes :: [(Id, Id)]
        nextNodes = filter ((/= prevId) . fst) $ zip (toList $ nNodes node) (toList $ nEdges node)
        
        nextColors :: [Color]
        nextColors = filter (/= prevColor) $ map Color [1..length $ nNodes node]
        
        nexts :: [(Id, Id, Color)]
        !nexts = zip3 (map fst nextNodes) (map snd nextNodes) nextColors
        
        newEdges :: Map Edge
        !newEdges = foldl (\m (node, edge, color) -> HM.insert (unId edge) (newEdge edge color) m) edges nexts
        
        newEdge :: Id -> Color -> Edge
        newEdge edge color = (edges HM.! unId edge) { eColor = color }
