#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 10

int get_int(void) {
  int num;
#ifdef BUF_SIZE
  char line[BUF_SIZE];
  if(!fgets(line, BUF_SIZE, stdin)) return 0;
  sscanf(line, "%d", &num);
#else
#error
#endif
  return num;
}

#define SET_MAX 1000000
#define INPUT_MAX 999999 // less than or equal
// 6000000**(1/3) = 181.7
// 180*181*182/6 < 181**3/6 < INPUT_MAX < 181*182*183/6
#define NUM_MAX 180
struct pair {
    int min;
    int odd_min;
};

#include <limits.h>
#define min(a,b) ((a) > (b) ? (b) : (a))

int main(void) {
    struct pair ans[SET_MAX] = {0};
    int idx = 0;
    int i;
    int tetra_area[NUM_MAX+1];
    // calc idx:1 ~ 99
    for(i = 1; i <= NUM_MAX; i++) {
        tetra_area[i] = i*(i+1)*(i+2)/6;
    }
    // answer to 1st question
    static int dp[INPUT_MAX+1];
    // answer to 2nd question
    static int odd_dp[INPUT_MAX+1];

    // In case of len = 1
    for(i = 0; i < INPUT_MAX+1; i++) {
        dp[i] = odd_dp[i] = i;
    }
    // calc len limit
    int len;
    for(len = 2; len <= NUM_MAX; len++) {
        int target = tetra_area[len];
        // update dp
        for(i = target; i <= INPUT_MAX; i++) {
            dp[i] = min(dp[i], dp[i-target]+1);
        }
    }
    for(len = 2; len <= NUM_MAX; len++) {
        int target = tetra_area[len];
        if(!(target%2)) continue; //require odd number
        for(i = target; i <= INPUT_MAX; i++) {
            odd_dp[i] = min(odd_dp[i], odd_dp[i-target]+1);
        }
    }
    // query
    while(1) {
        int sum = get_int();
        if(!sum) break;
        ans[idx].min = dp[sum]; ans[idx].odd_min = odd_dp[sum];
        idx++;
    }

    for(i = 0; i < idx; i++) {
        printf("%d %d\n", ans[i].min, ans[i].odd_min);
    }
    return 0;
}
