import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Euler35 {

    private static class Options {
        int limit = 1000000;
        boolean runCheckpoints = true;
    }

    private static boolean parseArguments(String[] args, Options options) {
        for (String arg : args) {
            if (arg.equals("--skip-checkpoints")) {
                options.runCheckpoints = false;
                continue;
            }
            if (arg.startsWith("--limit=")) {
                String tail = arg.substring("--limit=".length());
                if (tail.isEmpty()) {
                    System.err.println("Invalid limit format");
                    return false;
                }
                try {
                    options.limit = Integer.parseInt(tail);
                    continue;
                } catch (NumberFormatException e) {
                    System.err.println("Invalid limit format");
                    return false;
                }
            }
            System.err.println("Unknown argument: " + arg);
            return false;
        }
        return options.limit >= 2;
    }

    private static boolean[] primeSieve(int limit) {
        boolean[] prime = new boolean[limit + 1];
        for (int i = 2; i <= limit; i++) {
            prime[i] = true;
        }
        for (int p = 2; p * p <= limit; p++) {
            if (prime[p]) {
                for (int q = p * p; q <= limit; q += p) {
                    prime[q] = false;
                }
            }
        }
        return prime;
    }

    private static boolean isPrimeTrial(int n) {
        if (n < 2) return false;
        if (n % 2 == 0) return n == 2;
        for (int p = 3; p * p <= n; p += 2) {
            if (n % p == 0) return false;
        }
        return true;
    }

    private static boolean isCircularPrime(int n, boolean[] sieve) {
        String s = String.valueOf(n);
        int len = s.length();
        for (int shift = 0; shift < len; shift++) {
            String rotated = s.substring(shift) + s.substring(0, shift);
            int rot = Integer.parseInt(rotated);
            boolean isPrime;
            if (rot < sieve.length) {
                isPrime = sieve[rot];
            } else {
                isPrime = isPrimeTrial(rot);
            }
            if (!isPrime) {
                return false;
            }
        }
        return true;
    }

    private static int solve(int limit) {
        boolean[] sieve = primeSieve(limit + 100);
        int count = 0;
        for (int n = 2; n < limit; n++) {
            if (!sieve[n]) continue;
            if (isCircularPrime(n, sieve)) {
                count++;
            }
        }
        return count;
    }

    private static boolean runCheckpoints() {
        boolean[] sieve = primeSieve(1000);
        if (!isCircularPrime(197, sieve)) {
            System.err.println("Checkpoint failed for 197");
            return false;
        }
        if (solve(100) != 13) {
            System.err.println("Checkpoint failed for limit=100");
            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.limit));
    }
}
