import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Euler418 {

    static class Triple {
        BigInteger a = BigInteger.ZERO;
        BigInteger b = BigInteger.ZERO;
        BigInteger c = BigInteger.ZERO;
        BigInteger sum = BigInteger.ZERO;
    }

    static BigInteger cube(long x) {
        BigInteger t = BigInteger.valueOf(x);
        return t.multiply(t).multiply(t);
    }

    static long sqrtFloorLong(BigInteger x) {
        if (x.compareTo(BigInteger.ZERO) <= 0)
            return 0;
        BigInteger a = BigInteger.ONE.shiftLeft(x.bitLength() / 2);
        boolean decrease = false;
        for (;;) {
            BigInteger b = x.divide(a).add(a).shiftRight(1);
            if (a.compareTo(b) == 0 || (a.compareTo(b) < 0 && decrease)) {
                return a.longValue();
            }
            decrease = a.compareTo(b) > 0;
            a = b;
        }
    }

    static long multiplyClamp(long a, long b) {
        if (a == 0 || b == 0)
            return 0;
        long max = Long.MAX_VALUE / a;
        if (b > max)
            return Long.MAX_VALUE;
        return a * b;
    }

    static double lowerBoundRange(double l1, double l2, double l3, double rem) {
        double t = l2 - l1;
        double minValue;
        if (rem <= t) {
            minValue = l1 + rem;
        } else {
            rem -= t;
            double need = 2.0 * (l3 - l2);
            if (rem <= need) {
                minValue = l2 + rem / 2.0;
            } else {
                minValue = l3;
            }
        }
        return l3 - minValue;
    }

    static class Solver {
        List<Long> primes;
        List<Integer> exps;
        int pcount;

        BigInteger nValue = BigInteger.ONE;
        double logN = 0.0;
        double[] logP;
        double[] remLog;

        long[][] powLong;
        List<List<int[]>> splitByExp;
        int[] descIdx;

        long phaseANodes = 0;
        long phaseACap = 3000000;
        double bestLogRange = 1e100;
        Triple best = new Triple();

        Solver(List<Long> primes, List<Integer> exps) {
            this.primes = primes;
            this.exps = exps;
            this.pcount = primes.size();

            logP = new double[pcount];
            remLog = new double[pcount + 1];
            powLong = new long[pcount][];
            descIdx = new int[pcount];

            Integer[] idx = new Integer[pcount];
            for (int i = 0; i < pcount; i++)
                idx[i] = i;
            Arrays.sort(idx, (i, j) -> Long.compare(primes.get(j), primes.get(i)));
            for (int i = 0; i < pcount; i++)
                descIdx[i] = idx[i];

            int maxE = 0;
            for (int i = 0; i < pcount; i++) {
                logP[i] = Math.log(primes.get(i));
                logN += exps.get(i) * logP[i];
                maxE = Math.max(maxE, exps.get(i));

                powLong[i] = new long[exps.get(i) + 1];
                powLong[i][0] = 1;
                for (int e = 1; e <= exps.get(i); e++) {
                    powLong[i][e] = powLong[i][e - 1] * primes.get(i);
                }

                BigInteger piPow = BigInteger.valueOf(primes.get(i)).pow(exps.get(i));
                nValue = nValue.multiply(piPow);
            }

            for (int i = pcount - 1; i >= 0; i--) {
                remLog[i] = remLog[i + 1] + exps.get(i) * logP[i];
            }

            splitByExp = new ArrayList<>(maxE + 1);
            for (int e = 0; e <= maxE; e++) {
                List<int[]> v = new ArrayList<>();
                for (int x = 0; x <= e; x++) {
                    for (int y = 0; y <= e - x; y++) {
                        int z = e - x - y;
                        v.add(new int[] { x, y, z });
                    }
                }

                final int currentE = e;
                v.sort((a, b) -> {
                    int minA = Math.min(a[0], Math.min(a[1], a[2]));
                    int maxA = Math.max(a[0], Math.max(a[1], a[2]));
                    int minB = Math.min(b[0], Math.min(b[1], b[2]));
                    int maxB = Math.max(b[0], Math.max(b[1], b[2]));
                    int sa = maxA - minA;
                    int sb = maxB - minB;
                    if (sa != sb)
                        return Integer.compare(sa, sb);

                    int ma = Math.abs(3 * a[0] - currentE) + Math.abs(3 * a[1] - currentE)
                            + Math.abs(3 * a[2] - currentE);
                    int mb = Math.abs(3 * b[0] - currentE) + Math.abs(3 * b[1] - currentE)
                            + Math.abs(3 * b[2] - currentE);
                    return Integer.compare(ma, mb);
                });
                splitByExp.add(v);
            }
        }

        void sortBins(double[] logs, int[][] bins) {
            Integer[] ord = { 0, 1, 2 };
            Arrays.sort(ord, (i, j) -> Double.compare(logs[i], logs[j]));
            double[] nl = { logs[ord[0]], logs[ord[1]], logs[ord[2]] };
            int[][] nb = { bins[ord[0]], bins[ord[1]], bins[ord[2]] };
            for (int i = 0; i < 3; i++) {
                logs[i] = nl[i];
                bins[i] = nb[i];
            }
        }

        BigInteger valueFromBin(int[] binExp) {
            BigInteger v = BigInteger.ONE;
            for (int i = 0; i < pcount; i++) {
                int e = binExp[i];
                if (e > 0)
                    v = v.multiply(BigInteger.valueOf(powLong[i][e]));
            }
            return v;
        }

        void updateBestFromBins(double[] logs, int[][] bins) {
            double range = logs[2] - logs[0];
            if (range > bestLogRange + 1e-15)
                return;

            BigInteger[] v = { valueFromBin(bins[0]), valueFromBin(bins[1]), valueFromBin(bins[2]) };
            Arrays.sort(v);
            BigInteger sum = v[0].add(v[1]).add(v[2]);

            if (range < bestLogRange - 1e-15 || best.sum.equals(BigInteger.ZERO) || sum.compareTo(best.sum) < 0) {
                bestLogRange = range;
                best.a = v[0];
                best.b = v[1];
                best.c = v[2];
                best.sum = sum;
            }
        }

        void greedySeed() {
            double[] logs = new double[3];
            int[][] bins = new int[3][pcount];

            Integer[] idx = new Integer[pcount];
            for (int i = 0; i < pcount; i++)
                idx[i] = i;
            Arrays.sort(idx, (i, j) -> Long.compare(primes.get(j), primes.get(i)));

            for (int pi : idx) {
                for (int c = 0; c < exps.get(pi); c++) {
                    int target = 0;
                    if (logs[1] < logs[target])
                        target = 1;
                    if (logs[2] < logs[target])
                        target = 2;
                    logs[target] += logP[pi];
                    bins[target][pi]++;
                }
            }
            sortBins(logs, bins);
            bestLogRange = logs[2] - logs[0];
            updateBestFromBins(logs, bins);
        }

        void phaseADfs(int idx, double[] logs, int[][] bins) {
            if (phaseANodes++ >= phaseACap)
                return;
            if (idx == pcount) {
                updateBestFromBins(logs, bins);
                return;
            }
            if (lowerBoundRange(logs[0], logs[1], logs[2], remLog[idx]) >= bestLogRange - 1e-15) {
                return;
            }

            int e = exps.get(idx);
            List<int[]> splits = splitByExp.get(e);
            for (int[] s : splits) {
                double[] nl = logs.clone();
                int[][] nb = new int[][] { bins[0].clone(), bins[1].clone(), bins[2].clone() };

                nl[0] += s[0] * logP[idx];
                nl[1] += s[1] * logP[idx];
                nl[2] += s[2] * logP[idx];

                nb[0][idx] += s[0];
                nb[1][idx] += s[1];
                nb[2][idx] += s[2];

                sortBins(nl, nb);
                phaseADfs(idx + 1, nl, nb);
            }
        }

        long cubeRootFloor() {
            double approx = Math.exp(logN / 3.0);
            if (approx < 1.0)
                approx = 1.0;
            long x = (long) approx;
            while (cube(x + 1).compareTo(nValue) <= 0)
                x++;
            while (cube(x).compareTo(nValue) > 0)
                x--;
            return x;
        }

        long lowerABound(long high) {
            BigInteger rhs = nValue.multiply(best.a).multiply(best.a);
            BigInteger c2 = best.c.multiply(best.c);
            long lo = 1;
            long hi = high;
            while (lo < hi) {
                long mid = lo + (hi - lo) / 2;
                BigInteger lhs = c2.multiply(cube(mid));
                if (lhs.compareTo(rhs) >= 0) {
                    hi = mid;
                } else {
                    lo = mid + 1;
                }
            }
            return lo;
        }

        long maxDivisorLeq(int[] residual, long limit) {
            int[] eDesc = new int[pcount];
            for (int i = 0; i < pcount; i++)
                eDesc[i] = residual[descIdx[i]];

            long[] remMax = new long[pcount + 1];
            remMax[pcount] = 1;
            for (int i = pcount - 1; i >= 0; i--) {
                int pi = descIdx[i];
                remMax[i] = multiplyClamp(remMax[i + 1], powLong[pi][eDesc[i]]);
            }

            long[] bestB = new long[] { 0 };
            dfsDiv(0, 1L, limit, eDesc, remMax, bestB);
            return bestB[0];
        }

        void dfsDiv(int idx, long cur, long limit, int[] eDesc, long[] remMax, long[] bestB) {
            if (cur > limit)
                return;
            if (idx == pcount) {
                if (cur > bestB[0])
                    bestB[0] = cur;
                return;
            }
            if (multiplyClamp(cur, remMax[idx]) <= bestB[0])
                return;

            int pi = descIdx[idx];
            long[] pw = powLong[pi];
            int e = eDesc[idx];
            long lim = limit / cur;
            int kmax = e;
            while (kmax > 0 && pw[kmax] > lim)
                kmax--;

            for (int k = kmax; k >= 0; k--) {
                long nxt = cur * pw[k];
                if (multiplyClamp(nxt, remMax[idx + 1]) <= bestB[0])
                    break;
                dfsDiv(idx + 1, nxt, limit, eDesc, remMax, bestB);
            }
        }

        void evaluateCandidate(long a, int[] aExp) {
            BigInteger A = BigInteger.valueOf(a);
            BigInteger qa = nValue.divide(A);
            long u = sqrtFloorLong(qa);

            int[] residual = new int[pcount];
            for (int i = 0; i < pcount; i++) {
                residual[i] = exps.get(i) - aExp[i];
            }

            long b = maxDivisorLeq(residual, u);
            if (b < a)
                return;

            BigInteger B = BigInteger.valueOf(b);
            BigInteger c = qa.divide(B);
            if (c.compareTo(B) < 0)
                return;

            BigInteger lhs = c.multiply(best.a);
            BigInteger rhs = best.c.multiply(A);

            if (lhs.compareTo(rhs) < 0) {
                best.a = A;
                best.b = B;
                best.c = c;
                best.sum = A.add(B).add(c);
                // Math.log for biginteger approx
                bestLogRange = (c.bitLength() - A.bitLength()) * Math.log(2.0); // Safe enough approx for next dynamic
                                                                                // pruning!
                // Actually safer to compute precise log:
                double lC = c.doubleValue();
                double lA = A.doubleValue();
                // But doubleValue() may map to Infinity if > 10^308. But here limit is ~10^20
                // max.
                bestLogRange = Math.log(lC) - Math.log(lA);
            } else if (lhs.compareTo(rhs) == 0) {
                BigInteger s = A.add(B).add(c);
                if (s.compareTo(best.sum) < 0) {
                    best.a = A;
                    best.b = B;
                    best.c = c;
                    best.sum = s;
                }
            }
        }

        void phaseBSearch() {
            long aHigh = cubeRootFloor();
            long baseALow = lowerABound(aHigh);
            double baseLogLow = Math.log(baseALow);
            double logHigh = Math.log(aHigh);

            int[] aExp = new int[pcount];

            dfsBSearch(0, 1L, 0.0, aExp, baseLogLow, aHigh, logHigh);
        }

        void dfsBSearch(int idx, long cur, double lv, int[] aExp, double baseLogLow, long aHigh, double logHigh) {
            double dynamicLogLow = Math.max(baseLogLow, (logN - 2.0 * bestLogRange) / 3.0);
            if (idx == pcount) {
                if (lv + 1e-15 >= dynamicLogLow && cur <= aHigh) {
                    evaluateCandidate(cur, aExp);
                }
                return;
            }
            if (lv > logHigh + 1e-15)
                return;
            if (lv + remLog[idx] < dynamicLogLow - 1e-15)
                return;

            long p = primes.get(idx);
            int e = exps.get(idx);
            long mul = 1;
            for (int k = 0; k <= e; k++) {
                if (cur > aHigh / mul)
                    break;
                long nxt = cur * mul;
                aExp[idx] = k;
                dfsBSearch(idx + 1, nxt, lv + k * logP[idx], aExp, baseLogLow, aHigh, logHigh);
                if (k < e)
                    mul *= p;
            }
            aExp[idx] = 0;
        }

        BigInteger solve() {
            greedySeed();

            double[] logs = new double[3];
            int[][] bins = new int[3][pcount];
            phaseANodes = 0;
            phaseADfs(0, logs, bins);

            phaseBSearch();
            return best.sum;
        }
    }

    static Object[] factorizeFactorial(int n) {
        List<Long> primes = new ArrayList<>();
        List<Integer> exps = new ArrayList<>();
        boolean[] sieve = new boolean[n + 1];
        Arrays.fill(sieve, true);
        if (n >= 0)
            sieve[0] = false;
        if (n >= 1)
            sieve[1] = false;

        for (int i = 2; i <= n; i++) {
            if (!sieve[i])
                continue;
            for (int j = i * 2; j <= n; j += i)
                sieve[j] = false;
            primes.add((long) i);
            int e = 0;
            int t = n;
            while (t > 0) {
                t /= i;
                e += t;
            }
            exps.add(e);
        }
        return new Object[] { primes, exps };
    }

    static String solve() {
        Object[] factors = factorizeFactorial(43);
        @SuppressWarnings("unchecked")
        List<Long> primes = (List<Long>) factors[0];
        @SuppressWarnings("unchecked")
        List<Integer> exps = (List<Integer>) factors[1];

        Solver solver = new Solver(primes, exps);
        return solver.solve().toString();
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
