#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned long long ull; const ll MOD = 1000000007; #define rep(i,n) for(int i=0;i=0;i--) #define all(x) (x).begin(),(x).end() template inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } template inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; } vector sieve(size_t max) { vector IsPrime; if (max + 1 > IsPrime.size()) { IsPrime.resize(max + 1, true); } IsPrime[0] = false; // 0は素数ではない IsPrime[1] = false; // 1は素数ではない vector primes; for (size_t i = 2; i * i <= max; ++i) { if (IsPrime[i]) // iが素数ならば { //偶数を持つ場合は除外 string s = to_string(i); bool flg = true; for (auto c : s) { if ((c - '0') % 2 == 0) { flg = false; break; } } //11はあとから追加 if (s == "11") flg = false; if(flg)primes.push_back(s); for (size_t j = 2; i * j <= max; ++j) // (max以下の)iの倍数は IsPrime[i * j] = false; // 素数ではない } } primes.push_back("11"); return primes; } bool canErase(string strP, string S, vector& used) { vector pos; //Sの未使用部分がpを部分列として含むことを確認 int i = 0, j = 0; for (; i < strP.size() && j < S.size();) { for (; j < S.size(); j++) { if (S[j] == strP[i] && !used[j]) { pos.push_back(j); i++; j++; break; } } } if (pos.size() < strP.size()) return false; for (int x : pos) used[x] = true; return true; } int main() { int N; string S; cin >> N >> S; auto primes = sieve(100000); ll count = 0; vector used(N, false); for (auto p : primes) { while(canErase(p, S, used))count++; } cout << count << endl; return 0; }