//求1~n之间所有的质数
//求1~n之间所有的质数
//1.暴力求解,看1~n中每一个数是否为质数
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
int primes[N],idx;
bool isprime(int x) //1.暴力求解,看1~n中每一个数是否为质数 时间复杂度:n*sqrt(n)
{
if(x < 2) return 0;
for(int i = 2; i <= x/i; i ++) //i*i <= x 不用这种写法 sqrt
{
if(x%i == 0) return 0;
}
return 1;
}
bool vis[N];
void aiprime(int n) //2.素数筛,埃氏筛法 求1~n之间所有的素数 时间复杂度 nloglogn
{
for(int i = 2; i <= n; i ++) //用质数去把1~n中比它大的并且是它的倍数的数都标记为合数
{
if(!vis[i])
{
primes[++idx] = i;
for(int j = i+i; j <= n; j += i) vis[j] = 1;
}
}
}
void oulaprime(int n) //2.欧拉筛 保证了每一个合数用它的最小质因子去筛掉, 求1~n之间所有的素数 时间复杂度 n
{
for(int i = 2; i <= n; i ++)
{
if(!vis[i])
{
primes[idx++] = i;
}
for(int j = 0; primes[j] <= n/i; j ++)
{
vis[primes[j]*i] = true;
if(i%primes[j] == 0) break; //保证不被重复筛的关键
}
}
}
// 1 2 3 4 5 6 7 8 9 10 11 12 n=12
//prime{2} 标记 4
//prime{2 3} 标记 6 9
//i=4 prime{2 3} 标记8 【没有用3*4去标记12】
//i=5 prime{2 3 5} 标记 10
//i=6 prime{2 3 5} 标记12
//i=7 prime{2 3 5 7} 标记 14
//i=8 prime{2 3 5 7}
//i=9 prime{2 3 5 7}
//i=10 prime{2 3 5 7}
//i=11 prime{2 3 5 7 11}
//i=12 prime{2 3 5 7 11}
int main()
{
cin >> n;
/*for(int i = 2;i <= n; i ++) //这是用暴力筛看每一个数是否为质数
{
if(isprime(i)) primes[++idx] = i;
}*/
aiprime(n); //这个是调用埃氏筛求1-n中质数的个数,保存在了primes数组中,并且idx表示质数个数
cout << idx << endl;
/*
oulaprime(n); //这个是调用线性筛求1-n中质数的个数,保存在了primes数组中,并且idx表示质数个数
cout << idx << endl;
*/
}