data Edge = Edge Int Int Int deriving (Eq)
instance Show Edge where
  show (Edge a b c) = show a ++ " " ++ show b ++ " "  ++ show c

gep 2 = (1, 0)
gep x = let 
          p = head $ filter (\c-> 2^c >= x) [0..]
          q = if 2^p == x then p else p - 1
          r =  x - 2^q
        in (q, r)

graph :: Int-> (Int, Int, [Edge])
graph x = (nn, en, edges)
  where
    (a, m) = gep x 
    nn = a + 1
    edges = [Edge p q r | p <- [1..nn-1], let q = p + 1, r<-[0, 2^(p-1)]] ++
      etge nn (2^(nn - 1) - 1) m
    en = length edges 

etge :: Int->Int->Int->[Edge]
etge a b 0 = []
etge a b 1 = [Edge 1 a (b+1)]
etge a b x = let
              (p, q) = gep x
             in  Edge (p + 1) a (b + 1) : etge a (b + 2^p) q


format :: (Int, Int, [Edge]) -> String
format (a, b, edges) = foldl (\x y -> x ++ show y ++ "\n") (show a ++ " " ++ show b ++ "\n") edges

main = do
  n <- readLn
  putStrLn $ format $ graph n