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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using static Input;

public class Prog
{
    private const int INF = 1000000007;
    public static void Main()
    {
        SieveOfEratosthenes sieve = new SieveOfEratosthenes(100000);
        sieve.Run();
        int[] q = new int[100010];
        for (int i = 1; i <= 100000; i++)
        {
            if (sieve.IsPrime(i) && sieve.IsPrime((i + 1) / 2)) q[i] = q[i - 1] + 1;
            else q[i] = q[i - 1];
        }
        int Q = NextInt();
        for (int i = 0; i < Q; i++)
        {
            int a = NextInt() - 1, b = NextInt();
            Console.WriteLine(q[b]-q[a]);
        }
    }
}
public class SieveOfEratosthenes
{
    public HashSet<int> list { get; private set; } = new HashSet<int>();
    private static bool[] memo;
    private int M, root;
    public SieveOfEratosthenes(int N)
    {
        M = (int)Math.Ceiling((double)N / 2);
        root = (int)Math.Ceiling((Math.Sqrt(N) + .1)) / 2;
        memo = new bool[M];
    }
    public void Run()
    {
        memo[0] = false;
        for (int i = 1; i < M; i++) memo[i] = true;
        list.Add(2);
        for (int i = 1; i < root; i++)
        {
            if (!memo[i]) continue;
            for (int j = 2 * i * (i + 1); j < M; j += (2 * i + 1)) memo[j] = false;
        }
        for (int i = 0; i < M; i++) if (memo[i]) list.Add(i * 2 + 1);
    }
    public bool IsPrime(int N)
    {
        return list.Contains(N);
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
}