var BitArray = function(size) {
this.length = size;
this.buffer = new ArrayBuffer(Math.ceil(this.length / 32) * 4);
this.words = new Uint32Array(this.buffer);
};
BitArray.prototype.size = function() {
return this.length;
};
BitArray.prototype.set = function(bitIndex) {
var wordIndex = Math.floor(bitIndex / 32);
this.words[wordIndex] |= (1 << bitIndex);
};
BitArray.prototype.get = function(bitIndex) {
var wordIndex = Math.floor(bitIndex / 32);
return !!(this.words[wordIndex] & (1 << bitIndex));
};
function maxPalindromicPrime(bound) {
var sieve_size = (bound - 1) % 6 < 4 ? Math.floor(bound / 6) * 2 + 1 : Math.floor((bound + 1) / 3);
var sieve = new BitArray(sieve_size);
var limit = Math.floor(Math.sqrt(bound));
for(var i = 1;; ++i) {
if(!sieve.get(i)) {
var p = i * 3 + (i & 1) + 1;
if(p > limit) break;
for(var j = p * 2 + i; j < sieve_size; j += p * 2)
sieve.set(j);
for(var j = p * 2 - i - 1; j < sieve_size; j += p * 2)
sieve.set(j);
}
}
for(var i = sieve_size - 1; i > 0; --i) {
if(!sieve.get(i)) {
var n = i * 3 + (i & 1) + 1;
if(isPalindrome(n)) {
return n;
}
}
}
}
function isPalindrome(n) {
var s = n.toString();
var len = s.length;
for(var i = 0; i < len / 2; ++i) {
if(s[i] != s[len - i - 1]) return false;
}
return true;
}
console.log(maxPalindromicPrime(Math.pow(2, 30)));