import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

int[] T, O;

int calc(int x) {
    return x * (x + 1) * (x + 2) / 6;
}

void prepare() {
    for (int i = 1; ; i++) {
        int x = calc(i);
        if (x > 1000000) break;
        T ~= x;
        if (x % 2 == 1) O ~= x;
    }
    O.sort!"a > b";
    T.sort!"a > b";
}

void main() {
    prepare;
    int N;
    bool input() {
        scanf("%d\n", &N);
        if (N == 0) return false;
        return true;
    }

    auto dp = new int[1000001];
    dp[] = 1 << 28;
    dp[0] = 0;
    foreach (t; T) {
        foreach (i; 0 .. 100001) {
            if (i + t >= 1000000) continue;
            dp[i + t] = min(dp[i + t], dp[i] + 1);
        }
    }

    auto dp2 = new int[1000001];
    dp2[] = 1 << 28;
    dp2[0] = 0;
    foreach (t; O) {
        foreach (i; 0 .. 100001) {
            if (i + t >= 1000000) continue;
            dp2[i + t] = min(dp2[i + t], dp2[i] + 1);
        }
    }

    void solve() {
        writeln(dp[N], " ", dp2[N]);
    }
    while (input) solve;
}