using
System;
class
GFG {
static
bool
[] sieve()
{
bool
[] isPrime =
new
bool
[100001];
for
(
int
i = 0; i < 100001; i++)
isPrime[i] =
true
;
isPrime[0] =
false
;
isPrime[1] =
false
;
for
(
int
i = 2; i * i < 100001; i++) {
if
(isPrime[i] ==
true
) {
for
(
int
j = i * i; j < 100001; j += i) {
isPrime[j] =
false
;
}
}
}
return
isPrime;
}
static
int
cnt1XPrime(
int
sum,
int
len,
int
tight,
String X,
bool
[] isPrime,
int
[, , ] dp)
{
if
(len == X.Length) {
return
isPrime[sum] ? 1 : 0;
}
if
(dp[sum, len, tight] != -1) {
return
dp[sum, len, tight];
}
int
end = (tight == 1) ? (X[len] - 48) : 9;
int
res = 0;
for
(
int
i = 0; i <= end; i++) {
res += cnt1XPrime(
sum + i, len + 1,
(tight & ((i == end) ? 1 : 0)), X, isPrime,
dp);
}
return
dp[sum, len, tight] = res;
}
static
int
cntLRprime(
int
L,
int
R)
{
string
LStr = (L - 1).ToString();
string
RStr = (R).ToString();
int
[, , ] dp =
new
int
[1000, 100, 2];
for
(
int
i = 0; i < 1000; i++) {
for
(
int
j = 0; j < 100; j++) {
for
(
int
k = 0; k < 2; k++)
dp[i, j, k] = -1;
}
}
bool
[] isPrime = sieve();
int
cntL = cnt1XPrime(0, 0, 1, LStr, isPrime, dp);
for
(
int
i = 0; i < 1000; i++) {
for
(
int
j = 0; j < 100; j++) {
for
(
int
k = 0; k < 2; k++)
dp[i, j, k] = -1;
}
}
int
cntR = cnt1XPrime(0, 0, 1, RStr, isPrime, dp);
return
(cntR - cntL);
}
public
static
void
Main(String[] args)
{
int
L = 11, R = 999;
Console.Write(cntLRprime(L, R));
}
}