Problem:
Prime-Factor Prime
A positive integer is called a "prime-factor prime" when the number of its prime factors is prime. For example, $12$ is a prime-factor prime because the number of prime factors of $12 = 2 \times 2 \times 3$ is $3$, which is prime. On the other hand, $210$ is not a prime-factor prime because the number of prime factors of $210 = 2 \times 3 \times 5 \times 7$ is $4$, which is a composite number.
In this problem, you are given an integer interval $[l, r]$. Your task is to write a program which counts the number of prime-factor prime numbers in the interval, i.e. the number of prime-factor prime numbers between $l$ and $r$, inclusive.
Input
The input consists of a single test case formatted as follows.
$l$ $r$
A line contains two integers $l$ and $r$ ($1 \leq l \leq r \leq 10^9$), which presents an integer interval $[l, r]$. You can assume that $0 \leq r-l < 1,000,000$.
Output
Print the number of prime-factor prime numbers in $[l,r]$.
Sample Input 1
1 9
Output for Sample Input 1
4
Sample Input 2
10 20
Output for Sample Input 2
6
Sample Input 3
575 57577
Output for Sample Input 3
36172
Sample Input 4
180 180
Output for Sample Input 4
1
Sample Input 5
9900001 10000000
Output for Sample Input 5
60997
Sample Input 6
999000001 1000000000
Output for Sample Input 6
592955
In the first example, there are 4 prime-factor primes in $[l,r]$: $4,6,8,$ and $9$.

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
#include <chrono>
#include <complex>
#include <cmath>
#include <unistd.h>
#define pc_u putchar
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i,a,b) for(it i=(it)(a);i<(it)b;i++)
#define rep2(i,a,b,c) for(it i=(it)(a);i<(it)b;i+=(it)c)
#define repp(i,a,b) for(it i=(it)(a);i<=(it)b;i++)
#define repp2(i,a,b,c) for(it i=(it)(a);i<=(it)b;i+=(it)c)
#define irep(i,a,b) for(int i=(int)(a);i<(int)b;i++)
#define irep2(i,a,b,c) for(int i=(int)(a);i<(int)b;i+=c)
#define irepp(i,a,b) for(int i=(int)(a);i<=(int)b;i++)
#define irepp2(i,a,b,c) for(int i=(int)(a);i<=(int)b;i+=c)
#define nrep(i,a,b) for(it i=(it)(a)-1;i>=(it)b;i--)
#define nrepp(i,a,b) for(it i=(it)(a);i>=(it)b;i--)
#define inrep(i,a,b) for(int i=(int)(a)-1;i>=(int)b;i--)
#define inrepp(i,a,b) for(int i=(int)(a);i>=(int)b;i--)
#define inrep2(i,a,b,c) for(int i=(int)(a)-1;i>=(int)b;i-=c)
#define inrepp2(i,a,b,c) for(int i=(int)(a);i>=(int)b;i-=c)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define Min(x) *min_element(all(x))
#define Max(x) *max_element(all(x))
#define popcount(x) __builtin_popcountll(x)
#define moda 998244353LL
#define modb 1000000007LL
#define modc 968244353LL
#define dai 2502502502502502502LL
#define sho -dai
#define aoi 1e18+1e6
#define giri 1010000000
#define en 3.14159265358979
#define eps 1e-14
#define fi first
#define se second
#define elif else if
template<typename T> using pq=priority_queue<T>;
template<typename T> using pqg=priority_queue<T,vector<T>,greater<T>>;
#define uni(a) a.erase(unique(all(a)),a.end())
using it=long long;
using itn=int;
using un=unsigned long long;
using idb=double;
using db=long double;
using st=string;
using ch=char;
using bo=bool;
using P=pair<it,it>;
using ip=pair<int,int>;
using vi=vector<it>;
using ivi=vector<int>;
using ivd=vector<idb>;
using vd=vector<db>;
using vs=vector<st>;
using vc=vector<ch>;
using vb=vector<bo>;
using vp=vector<P>;
using ivp=vector<ip>;
using sp=set<P>;
using isp=set<ip>;
using ss=set<st>;
using sca=set<ch>;
using si=set<it>;
using isi=set<int>;
using svi=set<vi>;
using vvi=vector<vi>;
using ivvi=vector<ivi>;
using ivvd=vector<ivd>;
using vvd=vector<vd>;
using vvs=vector<vs>;
using vvb=vector<vb>;
using vvc=vector<vc>;
using vvp=vector<vp>;
using ivvp=vector<ivp>;
using vsi=vector<si>;
using ivsi=vector<isi>;
using isvi=set<ivi>;
using vsc=vector<sca>;
using vsp=vector<sp>;
using ivsp=vector<isp>;
using vvsi=vector<vsi>;
using ivvsi=vector<ivsi>;
using vvsp=vector<vsp>;
using ivvsp=vector<ivsp>;
using svvb=set<vvb>;
using vvvi=vector<vvi>;
using ivvvi=vector<ivvi>;
using ivvvd=vector<ivvd>;
using vvvd=vector<vvd>;
using vvvb=vector<vvb>;
using ivvvp=vector<ivvp>;
using vvvp=vector<vvp>;
using vvvvi=vector<vvvi>;
using ivvvvi=vector<ivvvi>;
using vvvvd=vector<vvvd>;
using vvvvb=vector<vvvb>;
using ivvvvp=vector<ivvvp>;
using vvvvp=vector<vvvp>;
using ivvvvvi=vector<ivvvvi>;
using vvvvvi=vector<vvvvi>;
using ivvvvvvi=vector<ivvvvvi>;
using vvvvvvi=vector<vvvvvi>;
using ivvvvvvvi=vector<ivvvvvvi>;
using vvvvvvvi=vector<vvvvvvi>;
using vvvvvvvvi=vector<vvvvvvvi>;
const int dx[8]={0,1,0,-1,1,1,-1,-1};
const int dy[8]={1,0,-1,0,1,-1,1,-1};
st abc="abcdefghijklmnopqrstuvwxyz";
st ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
st num="0123456789";
st mb="xo";
st MB="XO";
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

namespace {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  int s = (int)v.size();
  for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}

istream &operator>>(istream &is, __int128_t &x) {
  string S;
  is >> S;
  x = 0;
  int flag = 0;
  for (auto &c : S) {
    if (c == '-') {
      flag = true;
      continue;
    }
    x *= 10;
    x += c - '0';
  }
  if (flag) x = -x;
  return is;
}

istream &operator>>(istream &is, __uint128_t &x) {
  string S;
  is >> S;
  x = 0;
  for (auto &c : S) {
    x *= 10;
    x += c - '0';
  }
  return is;
}

ostream &operator<<(ostream &os, __int128_t x) {
  if (x == 0) return os << 0;
  if (x < 0) os << '-', x = -x;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
  if (x == 0) return os << 0;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}

void input() {}
template <typename T, class... U>
void input(T &t, U &...u) {
  cin >> t;
  input(u...);
}
template <typename T, class... U>
void input1(T &t, U &...u) {
  input(u...);
}
void print() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void print(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u)) cout << sep;
  print(u...);
}
template <typename T, class... U, char sep = ' '>
void print1(const T &t, const U &...u) {
  print(u...);
}

struct IoSetupNya {
  IoSetupNya() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(7);
  }
} iosetupnya;

}  //namespace Nyaan

template<typename T>
T Sum(vector<T> &a){
  T s=0;
  for(auto i:a)s+=i;
  return s;
}

template<typename T>
T Sum(vector<T> &a,int l,int r){
  T s=0;
  irep(i,l,r)s+=a[i];
  return s;
}

template <typename T>
void dec(vector<T> &t){
  for(auto &i:t)i--;
}

template <typename T>
void inc(vector<T> &t,T k=1){
  for(auto &i:t)i+=k;
}

template <typename T>
vector<T> make_vec(int n,T t){
  vector<T> g(n);
  for(auto &i:g)i=t;
  return g;
}

template <typename T>
vector<T> subvec(vector<T> a,int f,int l){
  vector<T> g(l);
  irep(i,f,f+l)g[i-f]=a[i];
  return g;
}

template<typename T>
T gcda(T a,T b){
  if(!a||!b)return max(a,b);
  while(a%b&&b%a){
    if(a>b)a%=b;
    else b%=a;
  }
  return min(a,b);
}

it lcma(it a,it b){
  return a/gcda(a,b)*b;
}

db distance(db a,db b,db c,db d){return sqrt((a-c)*(a-c)+(b-d)*(b-d));}

bo outc(int h,int w,int x,int y){
  return (x<0||x>=h||y<0||y>=w);
}

template<typename T>
vector<vector<T>> nep(vector<T> a){
  vector<vector<T>> e;
  sort(all(a));
  do{
    e.emplace_back(a);
  }while(next_permutation(all(a)));
  return e;
}

template<typename T>
void chmin(T &a,T b){a=min(a,b);}
template<typename T>
void chmax(T &a,T b){a=max(a,b);}

void yn(bo a){print(a?string("Yes"):string("No"));}
void YN(bo a){print(a?string("YES"):string("NO"));}

struct dsu1{
  ivi par,siz;
  dsu1(int n){
    init(n);
  }
  void init(int n){
    irep(i,0,n){
      par.emplace_back(i);
    }
    siz.resize(n,1);
  }
  int leader(int u){
    if(par[u]==u)return u;
    return par[u]=leader(par[u]);
  }
  void merge(int u,int v){
    int ru=leader(u),rv=leader(v);
    if(ru==rv)return;
    if(size(ru)<size(rv))swap(ru,rv);
    siz[ru]+=siz[rv];
    par[rv]=ru;
  }
  bool same(int u,int v){
    return leader(u)==leader(v);
  }
  int size(int u){
    return siz[leader(u)];
  }
};

struct edge{
  int f;
  int t;
  it l;
};
void input(edge &a){input(a.f,a.t,a.l);}
bo comppppp(edge &a,edge &b){return a.l<b.l;}

it minspantree(vector<edge> &e,int n){
  /*
  与えられた辺を持つグラフの最小全域木を求める
  存在する場合はその答えを　存在しないならinf
  計算量はO(MlogM+N)くらい
  */
  vector<edge> g=e;sort(all(g),comppppp);
  it ans=0;
  dsu1 uf(n);
  for(auto i:g){
    if(!uf.same(i.f,i.t)){
      uf.merge(i.f,i.t);
      ans+=i.l;
    }
  }
  if(uf.size(0)==n)return ans;
  return dai;
}

/*#include <atcoder/all>
using namespace atcoder;
using mints=modint998244353;
using mint=modint;
using minto=modint1000000007;
using vm=vector<mint>;
using vms=vector<mints>;
using vmo=vector<minto>;
using vvm=vector<vm>;
using vvms=vector<vms>;
using vvmo=vector<vmo>;
using vvvm=vector<vvm>;
using vvvms=vector<vvms>;
using vvvmo=vector<vvmo>;
using vvvvm=vector<vvvm>;
using vvvvms=vector<vvvms>;
using vvvvmo=vector<vvvmo>;
using vvvvvm=vector<vvvvm>;
using vvvvvms=vector<vvvvms>;
using vvvvvmo=vector<vvvvmo>;
using vvvvvvm=vector<vvvvvm>;
using vvvvvvms=vector<vvvvvms>;
using vvvvvvmo=vector<vvvvvmo>;
using vvvvvvvms=vector<vvvvvvms>;
using vvvvvvvmo=vector<vvvvvvmo>;*/

/*総和をもとめるセグ木
struct nod{
  it val;
  nod(it v=0):val(v){}
};

nod op(nod a,nod b){return nod(a.val+b.val);}
nod e(){return nod(0);}

struct act{
  it a;
  act(it e=0):a(e){}
};

nod mapping(act f,nod x){return nod(f.a+x.val);}
act comp(act f,act g){return act(f.a+g.a);}
act id(){return act(0);}*/
//#define endl '\n'
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

void solve(){
  int l,r;input(l,r);
  int n=r-l+1;
  vb g(32001,1);g[0]=0,g[1]=0;
  irep(i,2,32001){
    if(i*i>32000)break;
    if(!g[i])continue;
    irep2(j,i*i,32001,i)g[j]=0;
  }
  ivvi b(n);
  irep(k,2,32001){
    if(!g[k])continue;
    for(int i=(l+k-1)/k*k;i<=r;i+=k)b[i-l].emplace_back(k);
  }
  ivi d(n),p(n);
  irep(i,0,n)d[i]=l+i;
  irep(i,0,n){
    for(int j:b[i])
      while(d[i]%j==0){
        d[i]/=j;
        p[i]++;
      }
    if(d[i]!=1)p[i]++;
  }
  int ans=0;
  irep(i,0,n)ans+=g[p[i]];
  print(ans);
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t=1;//input(t);
  while(t--)solve();
}
accuracy: 1
time_ms: 200
memory_kb: 67196
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < n; ++i)

set<ll> enum_primes(const ll n) {
    vector<bool> is_prime(n + 1, true);
    set<ll> res;
    is_prime[0] = is_prime[1] = false;
    for (ll i = 2; i <= n; ++i) {
        if (!is_prime[i]) continue;
        res.insert(i);
        for (ll j = i * i; j <= n; j += i) is_prime[j] = false;
    }
    return res;
}

int main() {
    ll l, r; cin >> l >> r;

    set<ll> primes = enum_primes(1e6);
    vector<pair<ll, ll>> prime_fact(r - l + 1, {0, 0});
    for (ll i = l; i <= r; i++) {
        prime_fact[i - l] = {i, 0};
    }

    for (ll p : primes) {
        ll a = 0, b = 1e9 / p;
        while (b - a > 1) {
            ll mid = (a + b) / 2;
            if (l <= p * mid) b = mid;
            else a = mid;
        }

        for (ll i = p * b; i <= r; i += p) {
            assert(prime_fact[i - l].first % p == 0);
            while (prime_fact[i - l].first % p == 0) {
                ++prime_fact[i - l].second;
                prime_fact[i - l].first /= p;
            }
        }
    }

    ll ans = 0;
    rep(i, prime_fact.size()) {
        if (prime_fact[i].first != 1) prime_fact[i].second++;
        if (primes.count(prime_fact[i].second)) ans++;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 22504
final_rank: 10

code_snippet: #line 1 "shifted_array.test.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2858"

#include <bits/stdc++.h>
using namespace std;

#line 1 "/Users/Reito/Desktop/atcoder/library/utilities/shifted_array.hpp"



#line 6 "/Users/Reito/Desktop/atcoder/library/utilities/shifted_array.hpp"

namespace m1une {
// bool は禁止
// bool を使いたい時は char を使おう
template <typename T>
struct shifted_array {
   private:
    long long _offset;
    long long _step;
    int _size;
    std::vector<T> _data;

   public:
    // [L, R] （閉区間）の範囲の index を持つ配列を生成
    shifted_array(long long L, long long R, T init_value = T(),
                  long long step = 1)
        : _offset(L),
          _step(step),
          _size((R - L) / step + 1),
          _data(_size, init_value) {
        if (step <= 0) {
            throw std::invalid_argument("Step must be positive");
        }
        if (L > R) {
            throw std::invalid_argument(
                "Left bound must be less than or equal to right bound");
        }
    }
    T &operator[](long long i) {
        int index = (i - _offset) / _step;
        if (index < 0 || index >= _size) {
            throw std::out_of_range("Index out of range");
        }
        return _data[index];
    };
    const T &operator[](long long i) const {
        int index = (i - _offset) / _step;
        if (index < 0 || index >= _size) {
            throw std::out_of_range("Index out of range");
        }
        return _data[index];
    };
    long long index(long long i) const {
        int index = (i - _offset) / _step;
        if (index < 0 || index >= _size) {
            throw std::out_of_range("Index out of range");
        }
        return index;
    }
};

}  // namespace m1une


#line 7 "shifted_array.test.cpp"

constexpr long long MAX = 100000;

long long solve(long long l, long long r) {
    vector<char> is_prime(MAX, 1);
    is_prime[0] = is_prime[1] = 0;
    m1une::shifted_array<vector<long long>> prime_factors(l, r);
    for (long long p = 2; p * p <= r; ++p) {
        if (!is_prime[p]) continue;
        for (long long x = 2 * p; x < MAX; x += p) {
            is_prime[x] = 0;
        }
        for (long long x = (l + p - 1) / p * p; x <= r; x += p) {
            prime_factors[x].emplace_back(p);
        }
    }
    long long res = 0;
    for (long long x = l; x <= r; ++x) {
        long long factor_count = 0;
        long long y = x;
        for (long long p : prime_factors[x]) {
            while (y % p == 0) {
                y /= p;
                ++factor_count;
            }
        }
        if (y > 1) {
            ++factor_count;
        }
        if (is_prime[factor_count]) {
            ++res;
        }
    }
    return res;
}

int main() {
    long long l, r;
    cin >> l >> r;
    cout << solve(l, r) << endl;
}
accuracy: 1
time_ms: 320
memory_kb: 71976
final_rank: 13

code_snippet: //#pragma GCC optimize(3,"Ofast","inline")
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
bool is_prime[1000100];
int prime[1000100];
int cnt=0;
int num[1001000];
int arr[1001000];
void get_prime() {	
	is_prime[0]=true;
	is_prime[1]=true;
	for(int i=2;i<=100000;i++) {
		if(is_prime[i]==false) {
			int j=i+i;
			prime[++cnt]=i;
			while(j<=100000) {
				is_prime[j]=true;
				j+=i;
			}
		}
	}
}
int main() 
{
    //freopen("out.txt", "w", stdout);
    ios::sync_with_stdio(0),cin.tie(0);
    int l,r;
    get_prime();
    cin>>l>>r;
    for(int i=l;i<=r;i++) arr[i-l+1]=i;
    int n=r-l+1;
	for(int i=1;i<=cnt;i++) {
		ll nape=prime[i];
		while(nape<=r) {
			ll t=l/nape;
			if(t*nape!=l) t++;
			while(t*nape<=r) {
				num[t*nape-l+1]++;
				arr[t*nape-l+1]=arr[t*nape-l+1]/prime[i];
				t++;
			}
			nape=nape*(ll)prime[i];
		}
	}
	for(int i=1;i<=n;i++) {
		if(arr[i]>1) {
			num[i]++;
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++) {
		if(is_prime[num[i]]==false) {
			ans++;
		}
	}
	cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 13616
final_rank: 4

code_snippet: #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstring>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define rep(i,a,b) for(int i=a;i<=b;i++)
typedef long long ll;
using namespace std;
const int N=3e5+10;
const int INF=0x3f3f3f3f;
int prime[N],tot;
bool is_prime[N];
int a[N*10],num[N*10];
void init(){
    for(int i=2;i<=100000;i++){
        if(!is_prime[i])
            prime[tot++]=i;
        for(int j=0;j<tot && i*prime[j]<=100000;j++){
            is_prime[i * prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
    ll l,r;
    init();
    //    cout<<prime[tot-1]<<endl;
    scanf("%lld%lld",&l,&r);
    for(int i=l;i<=r;i++) a[i-l+1]=i;

    for(int i=0;i<tot;i++){
        ll p=prime[i];
        while(p<=r){
            ll cnt=l/p;
            if(l%p) cnt++;
            while(cnt*p<=r){
                num[cnt*p-l+1]++;
                a[cnt*p-l+1]/=prime[i];
                cnt++;
            }
            p=p*prime[i];
        }
    }

    for(int i=l;i<=r;i++) {
        if(a[i-l+1]>1){
            num[i-l+1]++;
            //            cout<<i<<" "<<a[i-l+1]<<endl;
        }
    }
    is_prime[1]=is_prime[0]=1;
    int ans=0;
    for(int i=l;i<=r;i++)
        if(!is_prime[num[i-l+1]])
            ans++;
    printf("%d\n",ans);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 15844
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
#define FAST_IO                \
  ios::sync_with_stdio(false); \
  cin.tie(0);
const i64 INF = 1001001001001001001;

pair<vector<int>, vector<bool>> getPrimes(int n) {
  vector<bool> is_prime(n + 1, true);
  vector<int> primes;
  is_prime[0] = is_prime[1] = false;

  for (int i = 2; i <= n; ++i) {
    if (is_prime[i]) {
      primes.push_back(i);
      for (int j = 2 * i; j <= n; j += i) {
        is_prime[j] = false;
      }
    }
  }
  return {primes, is_prime};
}

int primesCount(int n, const vector<int>& primes) {
  int count = 0;
  for (int prime : primes) {
    while (n % prime == 0) {
      n /= prime;
      count++;
    }
    if (prime * prime > n) {
      break;
    }
  }
  if (n > 1) {
    count++;
  }
  return count;
}


int main() {
  FAST_IO
  auto ans = 0LL;

  int l, r;
  cin >> l >> r;

  auto [primes, is_prime] = getPrimes(1000000);
  for (int i = l; i <= r; ++i) {
    int count = primesCount(i, primes);
    if (is_prime[count]) {
      ans++;
    }
  }


  cout << ans << endl;
}
accuracy: 1
time_ms: 850
memory_kb: 4192
final_rank: 14

code_snippet: #define rep(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(v) v.begin(),v.end()
typedef long long ll;

#include <bits/stdc++.h>
using namespace std;
template <class T> using V=vector<T>;
template <class T> using VV=V<V<T>>;

int main(){
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  V<int> P(32000,1);
  P[0]=0,P[1]=0;
  for(int i=2;i*i<32000;i++){
    if(P[i]){
      for(int j=2*i;j<32000;j+=i) P[j]=0;
    }
  }
  V<int> A;
  rep(i,32000) if(P[i]) A.push_back(i);
  int a=A.size();

  int l,r;
  cin>>l>>r;
  V<int> B(r-l+1),cnt(r-l+1);
  for(int j=l;j<=r;j++) B[j-l]=j;
  rep(i,a){
    for(int j=(l+A[i]-1)/A[i]*A[i];j<=r;j+=A[i]){
      while(B[j-l]>1 && B[j-l]%A[i]==0){
        B[j-l]/=A[i];
        cnt[j-l]++;
      }
    }
  }
  V<int> C(32);
  rep(i,r-l+1){
    if(B[i]>1) cnt[i]++;
    C[cnt[i]]++;
  }
  int ans=0;
  for(int i=2;i<32;i++){
    if(P[i]) ans+=C[i];
  }
  cout<<ans<<endl;
  
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11340
final_rank: 2

code_snippet: #include <iostream>
#include <cstring>
using namespace std;

const int LOG = 31623;
int l, r, cnt;
bool notPrime[LOG];
int prime[3405];

void findPrime()
{
    for (int i = 2; i < LOG; i++)
    {
        if (!notPrime[i])
        {
            prime[cnt++] = i;
        }
        for (int j = 2 * i; j < LOG; j += i)
            notPrime[j] = true;
    }
    notPrime[1] = true;
}

bool isPrimeFactor(int n)
{
    int factorCnt = 0;
    if(n==1)
        return false;
    for (int i = 0; i < cnt; i++)
    {
        int p = prime[i];
        if (p * p > n)
            break;
        while (n % p == 0)
        {
            factorCnt++;
            n /= p;
        }
    }
    if (n > 1)
        factorCnt++;
    return !notPrime[factorCnt];
}


int main()
{
    findPrime();
    cin >> l >> r;
    int ans = 0;
    for (int i = l; i <= r; i++)
    {
        if (isPrimeFactor(i))
            ans++;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 1120
memory_kb: 3488
final_rank: 16

code_snippet: #include <iostream>
using namespace std;

const int LOG = 31623;
int l, r,cnt;
bool notPrime[LOG];
int prime[3405];

void findPrime()
{
    for (int i = 2; i < LOG; i++)
    {
        if(!notPrime[i]){
            prime[++cnt]=i;
        }
        for (int j = 2 * i; j < LOG; j += i)
            notPrime[j] = true;
    }
    notPrime[1]=true;
}

bool isPrimeFactor(int n)
{
    cnt=0;
    if(n==1){
        return false;
    }
    for(int i=1;i<3405;i++){
        int p=prime[i];
        if(p*p>n)
            break;
        while(n%p==0){
            cnt++;
            n/=p;
        }
    }
    if(n>1)
        cnt++;
    return !notPrime[cnt];
}

int main()
{
    int ans=0;
    findPrime();
    cin >> l >> r;
    for(int i=l;i<=r;i++){
        if(isPrimeFactor(i))
            ans++;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 0.0847457627118644
time_ms: 20
memory_kb: 3408
final_rank: 20

code_snippet: #include <iostream>
#include <algorithm>
#include <numeric>
const int MAX{1000010};
int L, R, P[MAX], P2[MAX];
bool siv[MAX];
int main() {
    std::cin >> L >> R;
    std::fill(siv, siv + MAX, true);
    std::iota(P2, P2 + MAX, L);
    siv[0] = siv[1] = false;
    for (int i{2} ; i < MAX ; i++) if (siv[i]) {
        for (long long j{(long long)i * i} ; j < MAX ; j += i) {
            siv[j] = false;
        }
        for (long long j{(long long)i * ((L + i - 1) / i)} ; j <= R ; j += i) {
            while (P2[j - L] % i == 0) {
                P[j - L]++;
                P2[j - L] /= i;
            }
        }
    }
    int ans{};
    for (long long i{L} ; i <= R ; i++) {
        if (P2[i - L] > 1) P[i - L]++;
        ans += siv[P[i - L]];
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 12236
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
	ll L, R; cin >> L >> R;

	const int mx = 1e5;
	vector<bool> is_prime(mx, true);

	int range = R-L+1;
	vector<ll> cnt(range, 0), val(range);
	for(ll i=L; i<=R; i++) val[i-L] = i;

	is_prime[0] = is_prime[1] = false;
	for(int i=2; i<mx; i++){
		if(is_prime[i]){
			ll lo = (L+i-1)/i*i;

			for(ll j=lo; j<=R; j+=i){
				while(val[j-L]%i == 0){
					val[j-L] /= i;
					cnt[j-L]++;
				}
			}

			for(int j=2*i; j<mx; j+=i){
				is_prime[j] = false;
			}
		}
	}

	int ans = 0;
	for(ll i=L; i<=R; i++){
		if(val[i-L] > 1) cnt[i-L]++;
		if(is_prime[cnt[i-L]]) ans++;
	}

	cout << ans << endl;
}
accuracy: 1
time_ms: 100
memory_kb: 18876
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

int M = 100100;


int main(){
	int L,R; cin >> L >> R;
	vector<int> isprime(M,1);
	isprime[0] = 0;
	isprime[1] = 0;
	for(int i = 2; i < M; i++){
		if(!isprime[i])continue;
		for(int j = i*2; j < M; j += i){
			isprime[j] = 0;
		}
	}
	vector<int> A(R-L+1);
	vector<int> cnt(R-L+1);
	for(int i = 0; i < (R-L+1); i++)A[i] = L+i;
	for(int i = 0; i < M; i++){
		if(!isprime[i])continue;
		int x = (L+i-1)/i*i;
		for(int j = x; j <= R; j += i){
			while(A[j-L] % i == 0){
				A[j-L] /= i;
				cnt[j-L]++;
			}
		}
	}
	for(int i = 0; i <= R-L; i++)if(A[i] > 1)cnt[i]++;
	int ans = 0;
	for(int i = 0; i <= R-L; i++){
		if(isprime[cnt[i]])ans++;
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 11400
final_rank: 5

code_snippet: #include <bits/stdc++.h>


using namespace std;
//make -f ../makefile SRC=
/*
TODO
*/


//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;

const int MAX_V = 32000;
static bool prime[MAX_V+1];
static int SPF[MAX_V+1];

const int P = 3432;
static vector<int> primes(P);
//static vector<int> primes;
//------------------------------------------------------------------------------
void sieve()
{
    prime[0] = false;
    prime[1] = false;

    for (int i=2; i<=MAX_V; i++) prime[i] = true;

    for (int i=2; i*i<=MAX_V; i++)
    {
        if (prime[i])
        {
            for (int j=2*i; j<=MAX_V; j+=i) prime[j] = false;
        }
    }

    SPF[1] = 1;
    for (int i=2; i<=MAX_V; i++) SPF[i] = i;

    for (int i=4; i<=MAX_V; i+=2) SPF[i] = 2;

    for (int i=3; i*i<=MAX_V; i++)
    {
        if (SPF[i] != i) continue;
        for (int j=i*i; j<=MAX_V; j+=i)
            if (SPF[j] == j)
                SPF[j] = i;
    }

    int index = 0;
    for (int i=2; i<=MAX_V; i++)
        if (prime[i])
            primes[index++] = i;
            //primes.push_back(i);
    //if (DEBUG) printf("primes.size()=%ld\n", primes.size());
}


//------------------------------------------------------------------------------
bool feasible(int v)
{
    int num = 0;
    if (v <= MAX_V)
    {
        while (true)
        {
            int f = SPF[v];
            if (f == 1) break;
            num++;
            v /= f;
        }
    }
    else
    {
        for (int f: primes)
        {
            if (v < f*f) break; //<---------- speed
            while (v >= f && v%f == 0)
            {
                num++;
                v /= f;
            }
        }
    }
    if (v != 1) num++; //<---------- gotcha
    return prime[num];
}

int solve(int L, int R)
{
    int res = 0;
    for (int v=L; v<=R; ++v)
        if (feasible(v))
            res++;
    return res;
}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    sieve();
    //return 0;
    //--------------------------------------------------------------------------
    int N, L, R, num;
    num = scanf("%d %d ", &L, &R);
    int res = solve(L, R);
    printf("%d\n", res);
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 1260
memory_kb: 3728
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int MAXS = 100000;
    vector<int> Prime(MAXS,true);
    Prime[0] = Prime[1] = false;
    rep(i,2,MAXS) {
        if (Prime[i]) {
            rep(j,2,MAXS) {
                if (i*j>=MAXS) break;
                Prime[i*j] = false;
            }
        }
    }
    int L, R;
    cin >> L >> R;
    int N = R-L+1;
    vector<int> A(N), C(N,0);
    rep(i,0,N) A[i] = L+i;
    rep(i,0,MAXS) {
        if (!Prime[i]) continue;
        int l = (L+i-1)/i, r = R/i;
        rep(j,l,r+1) {
            int k = i*j-L;
            while(A[k] % i == 0) {
                C[k]++;
                A[k] /= i;
            }
        }
    }
    rep(i,0,N) {
        if (A[i] > 1) C[i]++;
    }
    int ANS = 0;
    rep(i,0,N) if (Prime[C[i]]) ANS++;
    cout << ANS << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 11416
final_rank: 6

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using ll = long long;
const int MOD = 1000000007;
const int Mod = 998244353;
const int MAX = 1000000005;
const long long INF = 1000000000000000005LL;
using namespace std;
//using namespace atcoder;

vector<bool> Eratosthenes(int n) {
    vector<bool> isprime(n+1, true);
    isprime[0] = false;
    isprime[1] = false;
    for (int p = 2; p <= n; p++) {
        if (!isprime[p]) continue;
        for (int q = p*2; q <= n; q+=p) {
            isprime[q] = false;
        }
    }
    return isprime;
}

int main() {
    ios::sync_with_stdio(0); cin.tie();
    int l, r;
    cin >> l >> r;
    auto isprime = Eratosthenes(40000);
    vector<int> num(r-l+1);
    vector<int> fact(r-l+1);
    iota(num.begin(), num.end(), l);
    for (int p = 2; p < 40000; p++) {
        if (!isprime[p]) continue;
        int tmp = p;
        while (1) {
            for (int q = (l+tmp-1)/tmp*tmp; q <= r; q+=tmp) {
                fact[q-l]++;
                num[q-l] /= p;
            }
            if ((ll)tmp*p > r) break;
            tmp *= p;
        }
    }
    int ans = 0;
    for (int i = 0; i <= r-l; i++) {
        if (num[i] != 1) fact[i]++;
        if (isprime[fact[i]]) ans++;
        //cout << i+l << " " << num[i] << " " << fact[i] << endl;
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 10948
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pi;

inline void read(int &x) {
	x = 0; int f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar())
		if(c == '-') f = -1;
	for(;  isdigit(c); c = getchar())
		x = x * 10 + (c ^ '0');
	x *= f;
}

const int M = 32000;

int ans, l, r, vis[M + 5], pr[M], cnt;
int a[1000005], b[1000005];

void init() {
	vis[1] = 1;
	for(int i = 2; i <= M; ++i) {
		if(!vis[i]) {
			pr[++cnt] = i;
			for(int j = i * i; j <= M; j += i)
				vis[j] = 1;
		}
	}
}
//inline int solve(int x) {
//	int res = 0;
//	int k = sqrt(x);
//	for(int i = 1; i <= cnt; ++i) {
//		if(pr[i] > sqrt(x)) break;
//		while(x % pr[i] == 0)
//			x /= pr[i], ++res;
//	}
//	return res + (x != 1);
//}

int main() {
	init();
	cin >> l >> r;
	for(int i = l; i <= r; ++i)
		b[i - l] = i;
	for(int i = 1; i <= cnt; ++i) {
		for(LL x = pr[i]; x <= r; x *= pr[i]) {
			LL s = l;
			if(l % x)
				s = l - (l % x) + x;
			for(; s <= r; s += x) {
				++a[s - l], b[s - l] /= pr[i];
			}
		}
	}
	for(int i = l; i <= r; ++i) {
		if(i == 1) continue;
		if(b[i - l] != 1) ++a[i - l];
		ans += !vis[a[i - l]];
	}
	printf("%d\n", ans);

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11160
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

vector<ll> PrimeEnum(ll n) {
  vector<bool> sieve(n / 3 + 1, true);
  for(ll p = 5, d = 4, i = 1, sq = sqrt(n); p <= sq; p += d = 6 - d, i++) {
    if(!sieve[i]) { continue; }
    for(ll q = p * p / 3, r = d * p / 3 + (d * p % 3 == 2), s = 2 * p, qe = ssize(sieve); q < qe; q += r = s - r) { sieve[q] = false; }
  }
  vector<ll> ret = {2, 3};
  for(ll p = 5, d = 4, i = 1; p <= n; p += d = 6 - d, i++) {
    if(sieve[i]) { ret.emplace_back(p); }
  }
  while(!ret.empty() && ret.back() > n) { ret.pop_back(); }
  return ret;
}

uint64_t Root(uint64_t a, int k = 2) {
  if(a <= 1 || k == 1) { return a; }
  if(k >= 64) { return 1; }
  auto check = [&](__uint128_t n) {
    __uint128_t x = 1, m = n;
    for(ll p = k; p; p >>= 1, m *= m) {
      if(p & 1) { x *= m; }
    }
    return x <= a;
  };
  uint64_t n = powl(a, (long double)(1.0) / k);
  while(!check(n)) { --n; }
  while(check(n + 1)) { ++n; }
  return n;
}

vector<vector<pair<ll, ll>>> PrimeRange(ll l, ll r) {
  int n = r - l + 1;
  vector<ll> v(n);
  iota(v.begin(), v.end(), l);
  vector<vector<pair<ll, ll>>> p(n);
  for(auto &i : PrimeEnum(Root(r))) {
    for(ll j = (l + i - 1) / i * i; j <= r; j += i) {
      int c = 0;
      while(v[j - l] % i == 0) {
        v[j - l] /= i;
        c++;
      }
      if(c) { p[j - l].emplace_back(i, c); }
    }
  }
  for(int i = 0; i < n; i++) {
    if(v[i] != 1) { p[i].emplace_back(v[i], 1); }
  }
  return p;
}

vector<bool> Eratosthenes(int n) {
  vector<bool> prime(n + 1, true);
  if(n >= 0) { prime[0] = false; }
  if(n >= 1) { prime[1] = false; }
  for(int i = 2; i * i <= n; i++) {
    if(!prime[i]) { continue; }
    for(int j = i + i; j <= n; j += i) { prime[j] = false; }
  }
  return prime;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  ll l, r;
  cin >> l >> r;

  auto p = Eratosthenes(50);

  ll ans = 0;
  for(auto &i : PrimeRange(l, r)) {
    ll t = 0;
    for(auto &[p, e] : i) { t += e; }
    ans += p[t];
  }

  cout << ans << "\n";
}
accuracy: 1
time_ms: 270
memory_kb: 120188
final_rank: 15

code_snippet: #line 1 "main.cpp"
#include <bits/stdc++.h>
// #include <bit>
// #include "Utils/FastIO.hpp"
#line 4 "/home/kokoro601/compro_library/Math/Sieve.hpp"


// [left, right)
void segment_sieve(unsigned long long left, unsigned long long right, 
    std::vector<unsigned long long> &primes) 
{
    int small_bound = sqrt(right);
    std::vector<bool> is_prime_small(small_bound + 1, true);
    std::vector<bool> is_prime(right - left, true);

    for (int i = 2; i <= small_bound; i++) {
        if (is_prime_small[i]) {
            for (int j = 2*i; j <= small_bound; j += i) is_prime_small[j] = false;
            for (unsigned long long j = std::max(2ULL, (left + i - 1) / i) * i; j < right; j += i) 
                is_prime[j - left] = false;
        }
    }

    for (unsigned long long j = left; j < right; j++) 
        if (is_prime[j - left]) primes.push_back(j);
}

void sieve(int bound, std::vector<int> &primes) {
    std::vector<bool> is_prime(bound + 1, true);
    for (int i = 2; i <= bound; i++) {
        if (is_prime[i]) {
            for (int j = 2*i; j <= bound; j += i) is_prime[j] = false;
            primes.push_back(i);
        }
    }
}
#line 5 "main.cpp"
// #include "Flow/MinCostFlow.hpp"

using namespace std;
using ull = unsigned long long;
using ll = long long;
using Graph = vector<vector<int>>;
using u128 = __uint128_t;   
using u64 = uint64_t;

int solve(int l, int r) {
    int small_bound = max((int)sqrt(r), 1000);
    vector<bool> is_prime_small(small_bound + 1, true);
    is_prime_small[0] = is_prime_small[1] = false;
    vector<vector<int>> prime_factors(r - l);

    for (int i = 2; i <= small_bound; i++) {
        if (is_prime_small[i]) {
            for (int j = 2*i; j <= small_bound; j += i) is_prime_small[j] = false;
            for (int j = (l + i - 1) / i * i; j < r; j += i) 
                if (j % i == 0) prime_factors[j - l].push_back(i);
        }
    }

    int ans = 0;
    for (int j = l; j < r; j++) {
        int cur = j;
        int cnt = 0;
        for (auto p: prime_factors[j - l])
            while (cur % p == 0) cur /= p, cnt++;
        if (cur > 1) cnt++;
        if (is_prime_small[cnt]) ans++;
    }
    return ans;
}


int main() {
    ll l, r; cin >> l >> r;
    cout << solve(l, r+1) << "\n";
}
accuracy: 1
time_ms: 210
memory_kb: 59368
final_rank: 11

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 2858.cc: Prime-Factor Prime
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_P = 320000;
const int MAX_M = 1000000;

/* typedef */

typedef vector<int> vi;

/* global variables */

bool primes[MAX_P + 1];

/* subroutines */

int gen_primes(int maxp, vi &pnums) {
  fill(primes, primes + maxp + 1, true);
  primes[0] = primes[1] = false;

  int p, pn = 0;
  for (p = 2; p * p <= maxp; p++)
    if (primes[p]) {
      pnums.push_back(p);
      for (int q = p * p; q <= maxp; q += p) primes[q] = false;
    }
  for (; p <= maxp; p++)
    if (primes[p]) pnums.push_back(p);
  return (int)pnums.size();
}

int prime_decomp(int n, vi &pnums) {
  int cnt = 0;

  int pn = pnums.size();
  for (int i = 0; i < pn; i++) {
    int pi = pnums[i];
    if (pi * pi > n) {
      if (n > 1) cnt++;
      return cnt;
    }

    while (n % pi == 0) n /= pi, cnt++;
  }
  return 0;
}

/* main */

int main() {
  vi pnums;
  gen_primes(MAX_P, pnums);

  int l, r;
  scanf("%d%d", &l, &r);

  int cnt = 0;
  for (int n = l; n <= r; n++) {
    if (primes[prime_decomp(n, pnums)]) cnt++;
  }

  printf("%d\n", cnt);
  return 0;
}
accuracy: 1
time_ms: 1260
memory_kb: 3404
final_rank: 17

code_snippet: #include<bits/stdc++.h>
#define PPque priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>, greater<tuple<ll, ll, ll>>>
#define Pque  priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>
#define pque priority_queue<ll, vector<ll>, greater<ll>>
#define umap unordered_map
#define uset unordered_set
#define rep(i, s, f) for(ll i = s; i <= f; i++)
#define per(i, s, f) for(ll i = s; i >= f; i--)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define vvvvl vector<vvvl>
#define vvvi vector<vector<vector<int>>>
#define vvvl vector<vector<vector<ll>>>
#define vvvc vector<vector<vector<char>>>
#define vvvd vector<vector<vector<double>>>
#define vvvm vector<vector<vector<mint>>>
#define vvi vector<vector<int>>
#define vvl vector<vector<ll>>
#define vvs vector<vector<string>>
#define vvc vector<vector<char>>
#define vvp vector<vector<pair<ll, ll>>>
#define vvb vector<vector<bool>>
#define vvd vector<vector<double>>
#define vvm vector<vector<mint>>
#define vp vector<pair<ll, ll>>
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vc vector<char>
#define vb vector<bool>
#define vd vector<double>
#define vm vector<mint>
#define P pair<ll, ll>
#define TU tuple<ll, ll, ll>
#define rrr(l, r) mt()%(r-l+1)+l
#define ENDL '\n'

#define ull unsigned long long
typedef long long ll;
using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）

template <typename T>
T or_less(vector<T> &A, T x) { //x以下で最大要素の添字 前提: sort済み 存在しない: -1
  return distance(A.begin(), upper_bound(A.begin(), A.end(), x)-1);
}
template <typename T>
T under(vector<T> &A, T x) { //x未満の最大要素の添字　前提: sort済み 存在しない: -1
  return distance(A.begin(), lower_bound(A.begin(), A.end(), x)-1);
}
template <typename T>
T or_more(vector<T> &A, T x) { //x以上で最小要素の添字　　前提: sort済み 存在しない: N .   //distanceのA.beginは添字を出すために常にA.begin() NG: A.begin() + 1
  return distance(A.begin(), lower_bound(A.begin(), A.end(), x));
}
template <typename T>
T over(vector<T> &A, T x) { //xより大きい最小要素の添字前提: sort済み 存在しない: N
  return distance(A.begin(), upper_bound(A.begin(), A.end(), x));
}
template <typename T>
vector<T> vec_shift_right(vector<T> A, ll step, ll dir = 1, ll indexed = 1) {//dir = 1 : 右シフト  dir = -1 : 左シフト
  ll N = A.size() - indexed;
  vector<T> res(N+1);
  rep(i, indexed, N) {
    ll idx = i - step * dir;
    if(idx < indexed) idx += N;
    if(idx > N) idx -= N;
    res.at(i) = A.at(idx);
  }
  return res;
}
template <typename T>
void UNIQUE(vector<T> &A) {
    sort(all0(A));
  return A.erase(unique(A.begin(), A.end()), A.end());
}
template <typename T>
void rev90(vector<vector<T>> &A, int indexed = 1) {
  reverse(A.begin() + indexed, A.end());
  int n = A.size();
  rep(i, indexed, n-1) {
   rep(j, i+1, n-1) {
      swap(A.at(i).at(j), A.at(j).at(i));
    }
  }
}
void chmin(ll &a, ll b) {
  a = min(a, b);
}
void chmax(ll &a, ll b) {
  a = max(a, b);
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll round(ll x, ll i) {return ll(x + 5 * pow(10, i-1))/ll(pow(10, i)) * ll(pow(10, i));}
vp insu_bunkai(ll N) {
  vp res;
  for (ll i = 2; i * i <= N; i++) {
    ll cnt = 0;
    while(N % i == 0) {
      cnt++;
      N /= i;
    }
    if(cnt != 0) res.push_back(P(i, cnt));
  }
  if(N != 1) res.push_back(P(N, 1));
  return res;
}
ll extgcd (ll a, ll b,  ll &x, ll &y) {
  if(b == 0) { x = 1;y = 0;return a;}
  ll d = extgcd(b, a%b, y, x);
  y -= a/b * x;
  return d;
}
template <typename T>
T ceil(T a, T b) {
  assert(b != 0);
  if(a % b == 0) return a / b;
  if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
  else return a / b;
}
template <typename T>
T floor(T a, T b) {
  assert(b != 0);
  if(a % b == 0) return a / b;
  if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
  else return a/b - 1;
}
ll modpow(ll x, ll y, ll mod) {
  if(x > mod) x %= mod;
  if(y == 0) return 1;
  ll res = modpow(x, y >> 1, mod);
  res = res * res % mod;
  if(y & 1) res *= x, res %= mod;
  return res;
}
ll sqrt_(ll a) {
    ll l = 0;
    ll r = 3000000000LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ（情報工学意識高め）
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
const ll int_max = 1001001001;
const ll ll_max = 1001001001001001001LL;
const double pi = 3.141592653589793;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // (番兵) → ↓ ← ↑  ※ 右から時計回り　
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
const ll mod = 998244353;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct sectional_primes {
  ll L, R, M;
  vb small;//small[i] := iが素数かどうか
  vvl large;//large[i] := i+L の相異なる素因数の集合
  vvp large_res;
  vvl aux;// aux[i] := large[i]の素因数の積、つまりi + Lの素因数の積（素数判定用）

  sectional_primes(ll _L, ll _R) : L(_L), R(_R) {
    assert(R >= 1);
    M = sqrt(R);
    small.resize(M + 1, true);
    small[0] = false;
    small[1] = false;
    large.resize(R - L + 1);
    large_res.resize(R - L + 1);

    for(ll i = 2; i * i <= R; i++) {
      if(!small[i]) continue;
      for(ll j = i * 2; j <= M; j += i) {
        small[j] = false;
      }
      for(ll j = (L + i - 1)/i * i; j <= R; j += i) {
        large[j - L].push_back(i);
      }
    }
  
  //√R以下の素因数は全て列挙し終えた。ここからは√R以上の素因数を列挙。ちなみに、√R以上の素因数は各数につき最大て1つ。
  //ここまでO(√Rloglog√R + (R - L)loglog(R-L))

    for(ll i = L; i <= R; i++) {
      ll num = i;
      for(ll x : large[i - L]) {
        if(num < x) break;
        ll cnt = 0;
        while(num % x == 0) num /= x, cnt++;
        large_res[i - L].emplace_back(x, cnt);
      }
      if(num != 1) large[i-L].push_back(num), large_res[i-L].emplace_back(num, 1);
    }
  //この処理にO((R - L)log(R))
  }

  vp get(ll x) {return large_res[x - L];}//O(1)


};



void solve() {
  ll L, R;
  cin >> L >> R;
  sectional_primes primes(L, R);
  ll ans = 0;
  rep(i, L, R) {
    auto ps = primes.get(i);
    ll sum = 0;
    for(auto [p, s] : ps) sum += s;
    if(primes.small[sum])ans++;
  }
  cout << ans << endl;

 

    

}
//無断で0を平方数にカウントする人もいる
//”部分文字列”と”連続部分文字列”は違うので確認すること
//一般のグラフと、有向辺かつその貼り方に制約がある(多くの場合：番号がで解放に伸びる）はだいぶ違うので確認すること
//座標を2で割った時の”切り捨て側(左側）”を求めるには 誤:(x / 2) マイナスの時！！！ 正:floor<ll>(x, 2);
//stringでの数字の下から1桁目は 正:S.at(N-1)  誤:S.at(0)
//if(S.at(i) == 1)　← charなのに1...?
// modは取りましたか...?(´・ω・｀)
//sortの比較関数は、 a == b　ならば falseを返す必要がある（そうで無いとRE(発生しない場合もある））
//unsigned ⇔ signed のキャストは、0 <= x <= max(signed) の限り安全



int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
  return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 182748
final_rank: 19