using static System.Math;using static System.Console;using System.Collections.Generic;using System.Linq;using System;using System.Collections;
using System.Runtime.Serialization;
using System.Collections.Specialized;
using System.Security.Cryptography;

class Program
{
    #region Reader
    static string ReadStr => Console.ReadLine();
    static string[] ReadStrs => Console.ReadLine().Split(' ');
    static int ReadInt => Convert.ToInt32(Console.ReadLine());
    static int[] ReadInts => Console.ReadLine().Split(' ').Select(s => Convert.ToInt32(s)).ToArray();
    static long ReadLong => Convert.ToInt64(Console.ReadLine());
    static long[] ReadLongs => Console.ReadLine().Split(' ').Select(s => Convert.ToInt64(s)).ToArray();
    #endregion
    #region Method
    static int mod = (int)Pow(10, 9) + 7;
    public static int Mod(int a,int mod) { return a % mod >= 0 ? a % mod : a % mod + mod; }
    public static long Mod(long a, int mod) { return a % mod >= 0 ? a % mod : a % mod + mod; }
    #endregion





    static void Main()
    {

        List<int> As = new List<int>();

        int index = 0;
        while (true)
        {
            int a = index * (index + 1) * (index + 2) / 6;
            if (a <= 1000000)
            {
                As.Add(a);
            }
            else
            {
                break;
            }
            index++;
        }
        int M = As.Count;




            int N = 1000000;


            int infty = 1000000000;

            //個数のdp[使ってよいポロック,生成された数字]



            int[] ans = new int[N+1];
            for (int i = 0; i < N+1; i++)
            {
                ans[i] = infty;
            }
            int[] prevDp = new int[N+1];
            int[] currentDp;
            for (int i = 0; i < N; i++)
            {
                prevDp[i] = infty;
            }
            prevDp[0] = 0;

            for (int m = 1; m < M; m++)
            {
                currentDp = new int[N+1];
                for (int i = 0; i <= N; i++)
                {
                    currentDp[i] = infty;
                }
                for (int n = 0; n <= N; n++)
                {
                    //m-1を使わなかったら
                    //dp[m, n] = Min(dp[m - 1, n], dp[m, n]);
                    currentDp[n] = Min(prevDp[n], currentDp[n]);

                    if (n + As[m] <= N)
                    {
                        //使ったら(重複可)
                        //dp[m, n + As[m - 1]] = Min(dp[m, n + As[m - 1]],dp[m, n] + 1);
                        currentDp[n + As[m]] = Min(currentDp[n + As[m]], currentDp[n] + 1);
    
                            ans[n + As[m]] = Min(ans[n + As[m]], currentDp[n + As[m]]);
                        
                    }

                }
                prevDp = currentDp;
            }




            int[] ans2 = new int[N+1];
            for (int i = 0; i < N+1; i++)
            {
                ans2[i] = infty;
            }
            prevDp = new int[N + 1];
            currentDp = null;
            for (int i = 0; i < N; i++)
            {
                prevDp[i] = infty;
            }
            prevDp[0] = 0;

            for (int m = 1; m < M; m++)
            {
                currentDp = new int[N + 1];
                for (int i = 0; i <= N; i++)
                {
                    currentDp[i] = infty;
                }
                for (int n = 0; n <= N; n++)
                {
                    //m-1を使わなかったら
                    //dp[m, n] = Min(dp[m - 1, n], dp[m, n]);
                    currentDp[n] = Min(prevDp[n], currentDp[n]);

                    if (n + As[m] <= N&&As[m]%2 == 1)
                    {
                        //使ったら(重複可)
                        //dp[m, n + As[m - 1]] = Min(dp[m, n + As[m - 1]],dp[m, n] + 1);
                        currentDp[n + As[m]] = Min(currentDp[n + As[m]], currentDp[n] + 1);
                
                            ans2[n + As[m]] = Min(ans2[n + As[m]], currentDp[n + As[m]]);
                        
                    }

                }
                prevDp = currentDp;
            }

        List<string> anses = new List<string>();


        while (true)
        {
            int q = ReadInt;
            if(q == 0)
            {
                break;
            }

            anses.Add(ans[q] + " " + ans2[q]);

        }




        
        WriteLine(string.Join("\n", anses));
    }



}



Measured memory_bytes: 44996