{-# OPTIONS_GHC -Odph #-}
{-# 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 Debug.Trace (traceShow)

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

main :: IO ()
main = do
  let !t1 = dpTable 1e6
      !t2 = 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
  return ()

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
{-# NOINLINE fsOdd #-}

dpTable :: Int -> V.Vector Int
-- dpTable n | traceShow n False = undefined
dpTable n = V.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 -- [ 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
                          
dpTableOdd :: Int -> V.Vector Int
dpTableOdd n = V.constructN n ge
  where
    -- gen :: V.Vector Int -> Int
    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]
--      | otherwise       = 1 + V.foldl' min maxBound [ v V.! (k - fi) | fi <- fsOdd, k - fi >= 0]
      where
        k = V.length v
        g fi
          | k - fi >= 0 = v V.! (k - fi)
          | otherwise   = maxBound
       
       