#include <cstdio>
#include <iostream>
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
template <typename T>
struct ExactDiv {
ExactDiv() {}
ExactDiv(T n) : t(T(-1) / n), i(mul_inv(n)) {}
T mul_inv(T n) {
T x = n;
for (int i = 0; i < 5; ++i) x *= 2 - n * x;
return x;
}
friend T operator / (T n, ExactDiv d) { return n * d.i; };
bool divide(T n) { return n * this->i <= this->t; }
T t, i;
};
ExactDiv<u64> ediv[200000];
bool is_odd_prime_slow(i64 n) {
for (i64 i = 3; i * i <= n; i += 2) {
if (n % i == 0) return false;
}
return true;
}
bool is_odd_prime_fast(i64 n) {
for (i64 i = 3; i * i <= n; i += 2) {
if (ediv[i].divide(n)) return false;
}
return true;
}
int main() {
for (int i = 1; i <= int(2e5); i += 2) ediv[i] = ExactDiv<u64>(i);
i64 beg = 1e10 + 1;
i64 end = 1e10 + 2e5;
clock_t t0 = clock();
int ans1 = 0;
for (i64 i = beg; i < end; i += 2) ans1 += is_odd_prime_slow(i);
clock_t t1 = clock();
int ans2 = 0;
for (i64 i = beg; i < end; i += 2) ans2 += is_odd_prime_fast(i);
clock_t t2 = clock();
printf("%d %.3f sec\n", ans1, double(t1 - t0) / CLOCKS_PER_SEC);
printf("%d %.3f sec\n", ans2, double(t2 - t1) / CLOCKS_PER_SEC);
return 0;
}
I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgaTY0ID0gbG9uZyBsb25nOwp1c2luZyB1MzIgPSB1bnNpZ25lZDsKdXNpbmcgdTY0ID0gdW5zaWduZWQgbG9uZyBsb25nOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBFeGFjdERpdiB7CiAgRXhhY3REaXYoKSB7fQogIEV4YWN0RGl2KFQgbikgOiB0KFQoLTEpIC8gbiksIGkobXVsX2ludihuKSkge30KICBUIG11bF9pbnYoVCBuKSB7CiAgICBUIHggPSBuOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyArK2kpIHggKj0gMiAtIG4gKiB4OwogICAgcmV0dXJuIHg7CiAgfQogIGZyaWVuZCBUIG9wZXJhdG9yIC8gKFQgbiwgRXhhY3REaXYgZCkgeyByZXR1cm4gbiAqIGQuaTsgfTsKICBib29sIGRpdmlkZShUIG4pIHsgcmV0dXJuIG4gKiB0aGlzLT5pIDw9IHRoaXMtPnQ7IH0KICBUIHQsIGk7Cn07CgpFeGFjdERpdjx1NjQ+IGVkaXZbMjAwMDAwXTsKCmJvb2wgaXNfb2RkX3ByaW1lX3Nsb3coaTY0IG4pIHsKICBmb3IgKGk2NCBpID0gMzsgaSAqIGkgPD0gbjsgaSArPSAyKSB7CiAgICBpZiAobiAlIGkgPT0gMCkgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4gdHJ1ZTsKfQoKYm9vbCBpc19vZGRfcHJpbWVfZmFzdChpNjQgbikgewogIGZvciAoaTY0IGkgPSAzOyBpICogaSA8PSBuOyBpICs9IDIpIHsKICAgIGlmIChlZGl2W2ldLmRpdmlkZShuKSkgcmV0dXJuIGZhbHNlOwogIH0KICByZXR1cm4gdHJ1ZTsKfQoKaW50IG1haW4oKSB7CiAgZm9yIChpbnQgaSA9IDE7IGkgPD0gaW50KDJlNSk7IGkgKz0gMikgZWRpdltpXSA9IEV4YWN0RGl2PHU2ND4oaSk7CgogIGk2NCBiZWcgPSAxZTEwICsgMTsKICBpNjQgZW5kID0gMWUxMCArIDJlNTsKCiAgY2xvY2tfdCB0MCA9IGNsb2NrKCk7CiAgaW50IGFuczEgPSAwOwogIGZvciAoaTY0IGkgPSBiZWc7IGkgPCBlbmQ7IGkgKz0gMikgYW5zMSArPSBpc19vZGRfcHJpbWVfc2xvdyhpKTsKICBjbG9ja190IHQxID0gY2xvY2soKTsKICBpbnQgYW5zMiA9IDA7CiAgZm9yIChpNjQgaSA9IGJlZzsgaSA8IGVuZDsgaSArPSAyKSBhbnMyICs9IGlzX29kZF9wcmltZV9mYXN0KGkpOwogIGNsb2NrX3QgdDIgPSBjbG9jaygpOwoKICBwcmludGYoIiVkICUuM2Ygc2VjXG4iLCBhbnMxLCBkb3VibGUodDEgLSB0MCkgLyBDTE9DS1NfUEVSX1NFQyk7CiAgcHJpbnRmKCIlZCAlLjNmIHNlY1xuIiwgYW5zMiwgZG91YmxlKHQyIC0gdDEpIC8gQ0xPQ0tTX1BFUl9TRUMpOwogIHJldHVybiAwOwp9