Problem:
Score : 400 points

Problem Statement

We say that a odd number N is similar to 2017 when both N and (N+1)/2 are prime.

You are given Q queries.

In the i-th query, given two odd numbers l_i and r_i, find the number of odd numbers x similar to 2017 such that l_i ≤ x ≤ r_i.

Constraints

1≤Q≤10^5

1≤l_i≤r_i≤10^5

l_i and r_i are odd.

All input values are integers.

Input

Input is given from Standard Input in the following format:

Q
l_1 r_1
:
l_Q r_Q

Output

Print Q lines. The i-th line (1≤i≤Q) should contain the response to the i-th query.

Sample Input 1

1
3 7

Sample Output 1

2

3 is similar to 2017, since both 3 and (3+1)/2=2 are prime.

5 is similar to 2017, since both 5 and (5+1)/2=3 are prime.

7 is not similar to 2017, since (7+1)/2=4 is not prime, although 7 is prime.

Thus, the response to the first query should be 2.

Sample Input 2

4
13 13
7 11
7 11
2017 2017

Sample Output 2

1
0
0
1

Note that 2017 is also similar to 2017.

Sample Input 3

6
1 53
13 91
37 55
19 51
73 91
13 49

Sample Output 3

4
4
1
1
1
2

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.*;
public class Main {
    
    public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        int N = 100000;
        Sieve sieve = new Sieve(N);
        int[] likes = new int[N+1];
        for (int i = 0; i < likes.length; i++) {
            if(i%2==1 && sieve.isPrime(i) && sieve.isPrime((i+1)/2)){
                likes[i] = 1;
            }
        } 
        int[] sump = new int[N+1];
        for (int i = 1; i < sump.length; i++) {
            sump[i] = sump[i-1] + likes[i];
        }
        // for (int i = 0; i < 15; i++) {
        //     System.out.print(prime.get(i));
        // }
        int Q = scanner.nextInt();
        int[] ls = new int[Q];
        int[] rs = new int[Q];
        for (int i = 0; i < Q; i++) {
            ls[i] = scanner.nextInt();
            rs[i] = scanner.nextInt();
        }
        for (int i = 0; i < Q; i++) {
            int left = ls[i]-1;
            int right = rs[i];
            System.out.println(sump[right] - sump[left]);
        }
    }
    public static class Sieve {
        private int n;
        private int[] f;
        public ArrayList<Integer> primes = new ArrayList<>();
        public Sieve(int N){
            n = N;
            f = new int[n+1];
            f[0] = -1; // 0 is not prime
            f[1] = -1; // 1 is not prime
            for(int i = 2; i <= N; i++){
                if(f[i]!=0) continue;
                primes.add(i);
                f[i] = i;
                for(int j = i+i; j<=n; j+=i){
                    if(f[j]==0) f[j] = i;
                }
            }
        }
        public boolean isPrime(int i){
            return (f[i]==i);
        } 
        public ArrayList<Integer> factorList(int i){
            ArrayList<Integer> res = new ArrayList<>();
            while(i != 1){
                res.add(f[i]);
                i /= f[i];
            }
            return res;
        }
        public HashMap<Integer, Integer> factorCount(int i){
            HashMap<Integer, Integer> res = new HashMap<>();
            while(i != 1){
                res.putIfAbsent(f[i], 0);
                res.put(f[i], res.get(f[i]) + 1);
                i /= f[i];
            }
            return res;
        }
    }
}