package main
import "fmt"
func main(){
var n int
fmt.Scan(&n)
// 质数线性筛算法
var primes []int
st:=make([]bool, n+1)
for i:=2;i<=n;i++{
if !st[i]{
// 至少 2*i 范围的数都被筛除过了(第一个数除外)
// 当前没有被筛掉的数,就是质数
primes = append(primes, i)
}
// 因为筛法是对 pj*i 的数进行筛除,保证pj*i<=n即可,也就是pj<=n/i
for j:=0;primes[j] <= n/i;j++{
// 每个质数筛掉其整数被的数
// 质数 2: 2*2,2*3, 2*4, 2*5, 2*6, ...
// 质数 3: 3*3,3*4, 3*5, 3*6, ...
// 质数 5: 5*5,5*6, 5*7, ...
// 质数 j: j*i, j*i+1, ...
// 这里 i是固定的,每次只筛掉已经找到的质数的i倍的数
st[primes[j]*i] = true
// p1 是 i 的第一个质因子即 i = p1*m,加上以下这个条件,a = p1*i = p1*m 这个数只会被px筛掉,且只会筛掉一次
// 两个问题?
// 1. 一个合数为什么只会被筛掉一次?
// 假设 a 这个数会被除最小的质因数p1之外的p2筛掉, p2 > p1, 设 a == p1*i = p2*j, 且 j<i
// 如果 要让 a 提前被 p2 筛掉, 必须满足 j % p1 != 0
// 由于 p1,p2 都是a的质因数,必然存在 a = p1*p2*n
// 则,i=p2*n, j=p1*n, 可得 j%p1 = (p1*n)%p1 = 0, 这与假设矛盾,故a只会被最小质因数筛掉一次。
//
// 比如 12=2*2*3, 存在两个质因子2和3
// p1=2, i=6, 12只会被2筛掉
// p2=3, j=4=p1*2, p1也是j的质因子, 故会跳过
//
// 2. 一个合数为什么必然会被筛掉?
// 两层嵌套循环会筛掉所有质数的倍数,只是避免重复筛除。
//
// 以下列出前几个质数筛掉的数
// i | 2 3 4 5 6 7 8 9 10 11
// -------------------------------------
// pj 2 | 4 6 8 10 12 14 16 18 20 22
// pj 3 | x 9 x 15 x 21 x 27 x 33
// pj 5 | x x x 25 x 35 x x x 55
// pj 7 | x x x x x 29 x x x 77
// pj11 | x x x x x x x x x 121
if i % primes[j] == 0 {
break
}
}
}
fmt.Println(len(primes))
}