type Point = (Double,Double)
toStr :: Point -> String
toStr (x,y) = (show x) ++ " " ++ (show y)

add :: Point -> Point -> Point
add (x1,y1) (x2,y2) = (x1+x2, y1+y2)

smult :: Double -> Point -> Point
smult c (x,y) = (c*x,c*y)

divide :: Point -> Point -> Double -> Point
divide v w a = smult a v `add` smult (1-a) w

rotate :: Double -> Point -> Point
rotate theta (x,y) = (cos theta * x - sin theta * y, sin theta * x + cos theta * y)

tri :: Point -> Point -> Point
tri v w = v `add` rotate (pi/3) (w `add` (smult (-1) v))

calcKP :: Int -> [Point] -> [Point]
calcKP 0 xs = xs
calcKP _ [] = []
calcKP n xs = calcKP (n-1) (calcKPOne xs)

foldfunc :: [Point] -> (Point,Point) -> [Point]
foldfunc acc (left,right) = acc ++ [x, tri x z, z, right]
    where x = divide left right (2/3)
          z = divide left right (1/3)

calcKPOne :: [Point] -> [Point]
calcKPOne points = foldl foldfunc [head points] (zip points (tail points))

o = (0,0) :: Point
p = (100,0) :: Point

main = do
    n <- getLine >>= return . read
    let points = calcKP n [o,p]
    mapM_ (putStrLn . toStr) points
