//求质数线性筛法
#include<iostream>
using namespace std;
const int N = 1e6 + 9;
int n, cnt, primes[N];
bool st[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
//n只会被最小质因子筛掉
//外层从2~n迭代,因为这毕竟算的是1~n中质数的个数,
//而不是某个数是不是质数的判定
for (int i = 2; i <= n; ++i)
{
//将质数加入primes数组
if (!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j] <= n / i; ++j)
{
//标记质数的倍数,且不会被重复标记
//primes[j]是i的质因子,又因为j从小到大枚举所以primes[j]是i最小质因子
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
//当发现primes[j]是i最小质因子的时候,如果再继续进行的话,
//我们就把 prime[j + 1] * i 这个数筛掉了,虽然这个数也是合数,
//但是我们筛掉它的时候并不是用它的最小质因数筛掉的,
//而是利用 prime[j + 1] 和 i 把它删掉的
//这个数的最小质因数其实是prime[j],如果我们不在这里退出循环的话,
//我们会发现有些数是被重复删除了的。
//primes[j]一定是i的最小质因子
}
}
cout << cnt;
return 0;
}