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

public class Euler60 {
    private static class Options {
        int setSize = 5;
        int primeLimit = 10000;
        boolean runCheckpoints = true;
    }

    private static boolean parseArguments(String[] args, Options options) {
        for (String arg : args) {
            if ("--skip-checkpoints".equals(arg)) {
                options.runCheckpoints = false;
            } else if (arg.startsWith("--set-size=")) {
                try {
                    options.setSize = Integer.parseInt(arg.substring(11));
                } catch (NumberFormatException e) {
                    System.err.println("Invalid number in --set-size");
                    return false;
                }
            } else if (arg.startsWith("--prime-limit=")) {
                try {
                    options.primeLimit = Integer.parseInt(arg.substring(14));
                } catch (NumberFormatException e) {
                    System.err.println("Invalid number in --prime-limit");
                    return false;
                }
            } else {
                System.err.println("Unknown argument: " + arg);
                return false;
            }
        }
        return options.setSize >= 2 && options.primeLimit >= 100;
    }

    private static long modMul(long a, long b, long mod) {
        return BigInteger.valueOf(a).multiply(BigInteger.valueOf(b)).remainder(BigInteger.valueOf(mod)).longValue();
    }

    private static long modPow(long base, long exp, long mod) {
        long result = 1L;
        base %= mod;
        while (exp > 0) {
            if ((exp & 1L) == 1L) {
                result = modMul(result, base, mod);
            }
            base = modMul(base, base, mod);
            exp >>= 1;
        }
        return result;
    }

    private static boolean isPrimeLong(long n) {
        if (n < 2L) return false;
        long[] primes = {2L, 3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L};
        for (long p : primes) {
            if (n == p) return true;
            if (n % p == 0L) return false;
        }

        long d = n - 1L;
        int s = 0;
        while ((d & 1L) == 0L) {
            d >>= 1;
            s++;
        }

        long[] witnesses = {2L, 325L, 9375L, 28178L, 450775L, 9780504L, 1795265022L};
        for (long a : witnesses) {
            if (a % n == 0L) continue;

            long x = modPow(a, d, n);
            if (x == 1L || x == n - 1L) continue;

            boolean witness = true;
            for (int r = 1; r < s; r++) {
                x = modMul(x, x, n);
                if (x == n - 1L) {
                    witness = false;
                    break;
                }
            }

            if (witness) return false;
        }

        return true;
    }

    private static List<Integer> sievePrimes(int limit) {
        boolean[] isPrime = new boolean[limit + 1];
        Arrays.fill(isPrime, true);
        isPrime[0] = false;
        isPrime[1] = false;

        for (int p = 2; p <= limit / p; p++) {
            if (!isPrime[p]) continue;
            for (int q = p * p; q <= limit; q += p) {
                isPrime[q] = false;
            }
        }

        List<Integer> primes = new ArrayList<>();
        for (int p = 2; p <= limit; p++) {
            if (isPrime[p] && p != 2 && p != 5) {
                primes.add(p);
            }
        }
        return primes;
    }

    private static long concatNumbers(int a, int b) {
        long pow10 = 10L;
        int t = b;
        while (t >= 10) {
            t /= 10;
            pow10 *= 10L;
        }
        return (long)a * pow10 + (long)b;
    }

    private static int solve(int setSize, int primeLimit) {
        List<Integer> primes = sievePrimes(primeLimit);
        int n = primes.size();

        byte[][] compatible = new byte[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                long ab = concatNumbers(primes.get(i), primes.get(j));
                long ba = concatNumbers(primes.get(j), primes.get(i));
                if (isPrimeLong(ab) && isPrimeLong(ba)) {
                    compatible[i][j] = 1;
                    compatible[j][i] = 1;
                }
            }
        }

        int[] bestSum = {Integer.MAX_VALUE};
        List<Integer> chosen = new ArrayList<>();
        List<Integer> allIndices = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            allIndices.add(i);
        }

        dfs(chosen, allIndices, 0, setSize, bestSum, primes, compatible);
        return bestSum[0];
    }

    private static void dfs(List<Integer> chosen, List<Integer> candidates, int currentSum,
                            int setSize, int[] bestSum, List<Integer> primes, byte[][] compatible) {
        if (chosen.size() == setSize) {
            if (currentSum < bestSum[0]) {
                bestSum[0] = currentSum;
            }
            return;
        }

        int need = setSize - chosen.size();
        if (candidates.size() < need) {
            return;
        }

        for (int idx = 0; idx < candidates.size(); idx++) {
            int pIndex = candidates.get(idx);
            int nextSum = currentSum + primes.get(pIndex);
            if (nextSum >= bestSum[0]) {
                continue;
            }

            chosen.add(pIndex);

            List<Integer> nextCandidates = new ArrayList<>();
            for (int j = idx + 1; j < candidates.size(); j++) {
                int qIndex = candidates.get(j);
                boolean ok = true;
                for (int cIndex : chosen) {
                    if (cIndex == qIndex) continue;
                    if (compatible[cIndex][qIndex] == 0) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    nextCandidates.add(qIndex);
                }
            }

            dfs(chosen, nextCandidates, nextSum, setSize, bestSum, primes, compatible);
            chosen.remove(chosen.size() - 1);
        }
    }

    private static boolean runCheckpoints() {
        if (solve(4, 1000) != 792) {
            System.err.println("Checkpoint failed for set_size=4");
            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(options.setSize, options.primeLimit));
    }
}
