{-# OPTIONS_GHC -Odph #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE NumDecimals #-}
module Main (main) where
import Control.Applicative
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS
import Data.Function (fix)
import Data.Maybe (fromJust)
import Data.Vector ((!),Vector())
import qualified Data.Vector as V
import Debug.Trace (traceId)
import Debug.Trace (traceShowId)
import System.IO (hFlush)
import System.IO (stdout)
import Data.Vector.Unboxed ((!))
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Mutable as MV
import qualified Control.Monad.ST as ST
import qualified Debug.Trace as Log
import qualified Data.Vector.Generic as GV

getInt :: IO Int
getInt = fst . fromJust . BS.readInt <$> BS.getLine


main :: IO ()
main = do
  let !t1 = V.force $ dpTable 1e6
      !t2 = V.force $ dpTableOdd 1e6
  -- print fs
  fix $ \continue -> do
    x <- getInt
    if (x == 0)
      then return ()
      else do
      putStrLn $ show (t1 V.! x) ++ ' ':show (t2 V.! x)
      hFlush stdout
      continue

f :: Int -> Int
f !n = (n * (n+1) * (n+2)) `div` 6

fs :: Vector Int
fs = V.map f $ V.enumFromTo 1 200

fsOdd :: Vector Int
fsOdd = V.filter odd $ fs

dpTable :: Int -> V.Vector Int
-- dpTable n | traceShow n False = undefined
dpTable n = constructN'' n ge
  where
    ge :: V.Vector Int -> Int
    ge !v
      | k == 0 = 0
      | otherwise       = 1 + V.foldl' (\l r -> min l $!g r) maxBound fs
      where
        k = V.length v
        g !fi
          | k - fi >= 0 = v V.! (k - fi)
          | otherwise   = maxBound

-- constructN' :: Int -> (V.Vector a -> a) -> V.Vector a
-- constructN' !n fun = ST.runST $ do
--     v  <- MV.new n
--     flip fix 0 $ \loop !len -> do
--       if len == n
--         then V.freeze v
--         else do
--         v' <- V.unsafeFreeze v
--         let !x = fun (V.unsafeTake len v')
--         x `seq` MV.write v len x
--         GV.elemseq v' x $ loop (len+1)

constructN'' :: Int -> (V.Vector a -> a) -> V.Vector a
constructN'' !n fun = ST.runST $ do
    v  <- MV.new n
    v' <- V.unsafeFreeze v
    flip fix 0 $ \loop !len -> do
      if len == n
        then return v'
        else do
        let v'' = V.unsafeTake len v'
            !x = fun v''
        GV.elemseq v'' x $ MV.write v len x
        loop (len+1)
    
dpTableOdd :: Int -> V.Vector Int
dpTableOdd n = constructN'' n ge
  where
    ge !v
      | V.length v == 0 = 0
      | otherwise       = 1 + V.foldl' (\l r -> min l (g r)) maxBound fsOdd -- [ v V.! (k - fi) | fi <- fs, k - fi >= 0]
      where
        k = V.length v
        g fi
          | k - fi >= 0 = v V.! (k - fi)
          | otherwise   = maxBound
       
       