class Euler34 {

    private static class Options {
        boolean runCheckpoints = true;
    }

    private static boolean parseArguments(String[] args, Options options) {
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            if ("--skip-checkpoints".equals(arg)) {
                options.runCheckpoints = false;
                continue;
            }
            System.err.println("Unknown argument: " + arg);
            return false;
        }
        return true;
    }

    private static long[] digitFactorials() {
        long[] f = new long[10];
        f[0] = 1;
        for (int d = 1; d <= 9; d++) {
            f[d] = f[d - 1] * d;
        }
        return f;
    }

    private static boolean isCurious(long value, long[] fact) {
        long x = value;
        long sum = 0;
        while (x > 0) {
            sum += fact[(int)(x % 10)];
            x /= 10;
        }
        return sum == value;
    }

    private static long solve() {
        long[] fact = digitFactorials();
        long nineFactorial = fact[9];

        int digits = 1;
        long pow10 = 1;
        while (pow10 <= (long)digits * nineFactorial) {
            digits++;
            pow10 *= 10;
        }
        long upper = (long)(digits - 1) * nineFactorial;

        long total = 0;
        for (long n = 10; n <= upper; n++) {
            if (isCurious(n, fact)) {
                total += n;
            }
        }
        return total;
    }

    private static boolean runCheckpoints() {
        long[] fact = digitFactorials();
        if (!isCurious(145, fact)) {
            System.err.println("Checkpoint failed for 145");
            return false;
        }
        if (!isCurious(40585, fact)) {
            System.err.println("Checkpoint failed for 40585");
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        Options options = new Options();
        if (!parseArguments(args, options)) {
            System.exit(1);
        }
        if (options.runCheckpoints && !runCheckpoints()) {
            System.exit(2);
        }

        System.out.println(solve());
    }
}
