import Data.List
import Data.Maybe

data Tree a = Node {nodeNum::Int, childNodes::[Tree a]}
  deriving (Show)

main = do
  _ <- readLn :: IO Int
  es <- map ((\[x, y] -> (x, y)) . map read . words) . lines <$> getContents
  let nc = numColors es
  print nc
  let t = buildTree es
  let coloredEdges = paintAll t 
  mapM_ (print . fromJust . flip lookup coloredEdges) es

numColors :: [(Int,Int)] -> Int
numColors = maximum . map length . group . sort . foldr (\(x, y) zs -> x:y:zs) []

buildTree :: [(Int,Int)] -> Tree Int
buildTree edges = foldl (flip addNode) (Node top []) $ edges'
  where
    top = (fst . head) edges'
    edges' =  sort edges 

addNode :: (Int, Int) -> Tree Int -> Tree Int
addNode (parent, child) t@(Node p cs)
  | parent == p = Node p ((Node child []):cs)
  | parent /= p = Node p (map (addNode (parent, child)) cs)

paintAll :: Tree Int -> [((Int, Int), Int)]
paintAll (Node p cs) = concat $ zipWith (paintChild p) [1..] cs

paintChild :: Int -> Int -> Tree Int -> [((Int, Int), Int)]
paintChild pNum color (Node chNum cs) = ((pNum, chNum), color):(concat $ zipWith (paintChild chNum) (filter (/= color) [1..]) cs)