import java.io.*;
class Main{
private static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static int nextInt() throws Exception{
in.nextToken();
return (int)in.nval;
}
//朴素法
// public static int count_prime(int x){
// boolean[] st = new boolean[x+1];
// int cnt = 0;
// for(int i=2; i<=x; i++){
// if(!st[i]){
// cnt++;
// for(int j = 2*i; j<=x; j+=i)
// st[j] = true;
// }
// }
// return cnt;
// }
//线性筛除法
public static int cnt_primes(int x){
int cnt = 0;
int[]primes = new int[x+1];
boolean[] st = new boolean[x+1];
for(int i=2; i<=x; i){
if(!st[i]) primes[cnt] = i;
for(int j=0;primes[j]i<=x;j++){//将所有以i为最大因子的数标记为非素数,这里涉及到以i为最大因子的数
//主要是iprimes[j] 其中 primes[j]一定满足小于等于i的最小质因子 这里因为 如果不是最小质因子 则两者
//的乘积的最大因子就不是i了;
st[primes[j]*i] = true;
if(i%primes[j]==0)break;//primes[j]必须小于等于i的最小质因子;
//其实确定了最大因子 就会唯一确定一批以该数为最大因子的合数 这也就解释了i的逐渐增大 合数会连续的被检测出来
//任何一个合数 x 也一定会被 i=x/min_prime 提前扫描到 所以 i可以直接根据st[i]判断出来
}
}
return cnt;
}
public static void main(String[] arg) throws Exception{
int n, a;
n = nextInt();
// while(n--!=0){
// a = nextInt();
// }
out.print(cnt_primes(n));
out.close();
}
}