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 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

//for
#define REP(i,n) for(int i=0,i##_len=(int)(n);i<i##_len;i++)
#define REPS(i,n) for(int i=1,i##_len=(int)(n);i<=i##_len;i++)
#define RREP(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define RREPS(i,n) for(int i=(int)(n);i>0;i--)

//printf
#define PRINTD(d) printf("%d\n",(d))
#define PRINTS(s) printf("%s\n",(s))

//memset
#define m0(s) memset(s,0,sizeof(s))
#define ml(s) memset(s,63,sizeof(s))
#define fill(s,c) memset(s,c,sizeof(s))

typedef long long ll;

int prime[50000] = { 0 };
int idx = 1;

//numまでの素数を求める
void getPrime(int num) {
	int i, j;
	int start;
	int flag;
	for (i = prime[idx] + 2; i <= num; i += 2) {
		flag = 1;
		for (j = 0; prime[j] <= (int)sqrt(i); j++) {
			if (i%prime[j] == 0) {
				flag = 0;
				break;
			}
		}
		if (flag)prime[++idx] = i;
	}
}


int main() {
	int Q;
	scanf("%d", &Q);
	int l[100000], r[100000];
	int max = 0;
	REP(i, Q) {
		scanf("%d %d", &l[i], &r[i]);
		if (r[i] > max)max = r[i];
	}
	prime[0] = 2;
	prime[1] = 3;
	getPrime(max);
	int le = 0, ri = idx;
	int mi;
	int cnt[50000];
	cnt[0] = 0;
	REPS(i, idx) {
		//PRINTD(i);
		le = 0, ri = idx;
		cnt[i] = cnt[i - 1];
		int tar = (prime[i] + 1) / 2;
		while (le <= ri) {
			mi = (le + ri) / 2;
			//printf("%d le%d mi%d ri%d\n", i, le,mi, ri);
			if (prime[mi] == tar) {
				cnt[i]++;
				break;
			}
			else if (prime[mi] < tar) {
				//目的値が中央値よりも上なら、最小値を中央値の一つ上に設定
				le = mi + 1;
			}
			else if (prime[mi] > tar)
				//目的値が中央値よりも下なら、最大値を中央値の一つ下に設定
				ri = mi - 1;
		}
		//PRINTD(cnt[i]);
	}
	REP(i, idx+1) {
//		PRINTD(cnt[i]);
	}
	REP(i, Q) {
		le = 0;
		ri = -1;
		REP(j, idx + 1) {
			//printf("%d %da\n", l[i], prime[j]);
			if (l[i] > prime[j])le = j-1;
			if (r[i] < prime[j]) {
				ri = j-1;
				break;
			}
		}
		if (r[i] <= 2)ri = 0;
		else if (ri == -1)ri = idx;
		//printf("le%d ri%d\n", le, ri);
		PRINTD(cnt[ri] - cnt[le]);
	}
}