{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}

import Control.Monad
import Control.Monad.State
import Data.List as L
import Data.Map as M
import Data.Maybe
import Data.Monoid
import Data.Set as S

infixl 9 !?
(!?) = flip M.lookup

main :: IO ()
main = do
  l1 <- getLine
  let n = read l1 :: Int
  ln <- sequence (replicate (n - 1) getLine)
  let abs = L.map (L.map read . words) ln :: [[Int]]
      (ans, (colors)) = runState (forM abs f) (M.empty)
      c = S.findMax $ S.unions $ M.elems colors

  print c
  forM_ ans print

f [a, b] = do
  (colors :: M.Map Int (S.Set Int)) <- get
  let uses = fromMaybe S.empty $ (colors !? a) `mappend` (colors !? b) :: S.Set Int
      c' = L.head $ L.dropWhile (`S.member` uses) [1..]

  put $ (M.insertWith S.union a (S.singleton c') $ M.insertWith S.union b (S.singleton c') colors)
  return c'
