#include <iostream>
#include <bitset>
using namespace std;
typedef unsigned int uint;
const uint MaxValue = 4000000;
class Eratostenes {
bitset<MaxValue/2> oddNotPrimes;
public:
Eratostenes() {
oddNotPrimes[0] = true;
for (uint i=3; i<MaxValue; i+=2) {
if (oddNotPrimes[i/2])
continue;
for (uint j=(i*3)/2; j<MaxValue/2; j+=i)
oddNotPrimes[j] = true;
}
}
bool isPrime(uint x) const {
return x==2 || (x%2!=0) && !oddNotPrimes.test(x/2);
}
uint nextPrime(uint x) const {
uint y = (x+1)/2;
do {
y++;
} while (oddNotPrimes.test(y));
return 2*y+1;
}
};
int main() {
Eratostenes primeTest;
const uint begin = 3900001;
for (uint i = 0; i<10; ++i) {
cout << i << "\t" << primeTest.isPrime(i) << endl;
}
for (uint i = begin; i<begin+100; i+=2)
if (primeTest.isPrime(i))
cout << i << endl;
cout << 30000 << "\t" << primeTest.nextPrime(30000) << endl;
cout << 30100 << "\t" << primeTest.nextPrime(30100) << endl;
cout << 3900067 << "\t" << primeTest.nextPrime(3900067) << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Yml0c2V0PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgdW5zaWduZWQgaW50IHVpbnQ7Cgpjb25zdCB1aW50IE1heFZhbHVlID0gNDAwMDAwMDsKCmNsYXNzIEVyYXRvc3RlbmVzIHsKCWJpdHNldDxNYXhWYWx1ZS8yPiBvZGROb3RQcmltZXM7CgpwdWJsaWM6CglFcmF0b3N0ZW5lcygpIHsKCQlvZGROb3RQcmltZXNbMF0gPSB0cnVlOwoJCWZvciAodWludCBpPTM7IGk8TWF4VmFsdWU7IGkrPTIpIHsKCQkJaWYgKG9kZE5vdFByaW1lc1tpLzJdKQoJCQkJY29udGludWU7CgkJCWZvciAodWludCBqPShpKjMpLzI7IGo8TWF4VmFsdWUvMjsgais9aSkKCQkJCW9kZE5vdFByaW1lc1tqXSA9IHRydWU7CgkJfQkKCX0KCglib29sIGlzUHJpbWUodWludCB4KSBjb25zdCB7CgkJcmV0dXJuIHg9PTIgfHwgKHglMiE9MCkgJiYgIW9kZE5vdFByaW1lcy50ZXN0KHgvMik7Cgl9CgoJdWludCBuZXh0UHJpbWUodWludCB4KSBjb25zdCB7CgkJdWludCB5ID0gKHgrMSkvMjsKCQlkbyB7CgkJCXkrKzsKCQl9IHdoaWxlIChvZGROb3RQcmltZXMudGVzdCh5KSk7CgkJcmV0dXJuIDIqeSsxOwoJfQp9OwoKaW50IG1haW4oKSB7CglFcmF0b3N0ZW5lcyBwcmltZVRlc3Q7Cgljb25zdCB1aW50IGJlZ2luID0gMzkwMDAwMTsKCWZvciAodWludCBpID0gMDsgaTwxMDsgKytpKSB7CgkJY291dCA8PCBpIDw8ICJcdCIgPDwgcHJpbWVUZXN0LmlzUHJpbWUoaSkgPDwgZW5kbDsKCX0KCglmb3IgKHVpbnQgaSA9IGJlZ2luOyBpPGJlZ2luKzEwMDsgaSs9MikKCQlpZiAocHJpbWVUZXN0LmlzUHJpbWUoaSkpCgkJCWNvdXQgPDwgaSA8PCBlbmRsOwoKCWNvdXQgPDwgMzAwMDAgPDwgIlx0IiA8PCBwcmltZVRlc3QubmV4dFByaW1lKDMwMDAwKSA8PCBlbmRsOwoJY291dCA8PCAzMDEwMCA8PCAiXHQiIDw8IHByaW1lVGVzdC5uZXh0UHJpbWUoMzAxMDApIDw8IGVuZGw7Cgljb3V0IDw8IDM5MDAwNjcgPDwgIlx0IiA8PCBwcmltZVRlc3QubmV4dFByaW1lKDM5MDAwNjcpIDw8IGVuZGw7CgoJcmV0dXJuIDA7Cn0K