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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include "bits/stdc++.h"
using namespace std;

#define ASC(vec) vec.begin(), vec.end()		// 昇順ソート 例：sort(ASC(vec));
#define DESC(vec) vec.rbegin(), vec.rend()	// 降順ソート 例:sort(DESC(vec));
#define rep(i, n) for(int i = 0; i < (n); i++)
#define Rep(i, n) for(int i = 1; i < n; i++)

const int mod = 1000000007;
const int inf = (1 << 21);
const long long INF = 1LL << 60;

using ii = pair<int, int>;
using ll = long long;
using vi = vector<int>;
using vd = vector<double>;
using vb = vector<bool>;
using vl = vector<ll>;
using vs = vector<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<ll>>;
using vvb = vector<vector<bool>>;
using vii = vector<pair<int, int>>;

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

ll GCD(ll a, ll b) { return b ? GCD(b, a % b) : a; }
ll LCM(ll a, ll b) { return (a * b) / GCD(a, b); }
int round_int(int a, int b) { return (a + (b - 1)) / b; }

constexpr array<int, 9> dx = { 0, 1, 0, -1, -1, 1, 1, -1, 0 };
constexpr array<int, 9> dy = { 1, 0, -1, 0, 1, 1, -1, -1, 0 };

// UnionFind 解説：https://youtu.be/TdR816rqc3s?t=8424
struct UnionFind {
	vi d;
	UnionFind(int n = 0) : d(n, -1) {}

	int find(int x) {
		if (d[x] < 0) return x;
		return d[x] = find(d[x]);
	}

	bool unite(int x, int y) {
		x = find(x), y = find(y);

		if (x == y) return false;

		if (d[x] > d[x]) swap(d[x], d[x]);
		d[x] += d[y];
		d[y] = x;
		return true;
	}

	bool same(int x, int y) { return find(x) == find(y); }
	int size(int x) { return -d[find(x)]; }
};

// ──────────────────────────────────────────────────────────────────

constexpr int MAX = 100010;

int main() {
	int q;
	cin >> q;

	// エラトステネスの篩
	bitset<MAX> is_prime(0);
	for (int i = 2; i <= 100000; ++i) is_prime.set(i);
	for (int i = 2; i <= 100000; ++i) {
		if (is_prime[i]) {
			for (int j = i * 2; j <= 100000; j += i) {
				is_prime.reset(j);
			}
		}
	}

	vi rui(MAX);
	for (int i = 1; i <= MAX; i += 2) {
		if (is_prime[i] && is_prime[(i + 1) / 2])
			rui[i] = 1;
	}

	Rep(i, MAX) rui[i] += rui[i - 1];

	rep(i, q) {
		int ans = 0;
		int l, r;
		cin >> l >> r;

		cout << rui[r] - rui[l - 1] << endl;
	}
}