import Control.Applicative
import Control.Monad
import qualified Data.ByteString.Char8 as B
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import Data.List (foldl', unfoldr)
import Data.Maybe (fromJust)


type Stack     = [Int]
type Neighbors = [Int]


main :: IO ()
main = do
    n    <- readLn :: IO Int
    adjL <- V.replicateM n $ map ((subtract 1 ) . fst . fromJust . B.readInt) . drop 2 . B.words <$> B.getLine
    let d = VU.replicate n 0 :: VU.Vector Int
        f = d
        (d', f', _) = foldl' (\s i -> dfs [i] adjL s) (d, f, 1) [0..(n-1)]
    forM_ [0..(n-1)] $ \i ->
        putStrLn $ unwords (show (i + 1) : show (d' VU.! i) : show (f' VU.! i) : [])


dfs :: Stack -> V.Vector Neighbors -> (VU.Vector Int, VU.Vector Int, Int) -> (VU.Vector Int, VU.Vector Int, Int)
dfs [] _ (d, f, t) =
    (d, f, t)

dfs stack adjL (d, f, t) =
    let
        s  = head stack
        ss = tail stack
    in
        if d VU.! s == 0 then do
            dfs stack adjL (d VU.// [(s, t)], f, (t + 1))
        else
            case next (adjL V.! s) d of
                Nothing ->
                    if (f VU.! s) == 0 then
                        dfs ss adjL (d, f VU.// [(s, t)], (t + 1))
                    else
                        dfs ss adjL (d, f, t)
                Just x ->
                    dfs (x : stack) adjL (d, f, t)


next :: Neighbors -> VU.Vector Int -> Maybe Int
next []     d = Nothing
next (n:ns) d =
    case d VU.! n of
        0 -> Just n
        _ -> next ns d

