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# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace AtCoder
{
	public class QuestionA
	{
		public static void Main(string[] args)
		{
			// 整数の入力
			int n = int.Parse(Console.ReadLine());
			List<int> counts = new List<int>();

			for (int i = 0; i < n; ++i) {
				// 整数配列の入力
				var inputLongArray = Console.ReadLine().Split(' ').Select(i => int.Parse(i)).ToArray();
				var l = inputLongArray[0];
				var r = inputLongArray[1];

				if(l == r) {
					if (IsPrime(l)) {
						counts.Add(1);
					} else {
						counts.Add(0);
					}
					continue;
				}

				var list = GeneratePrime(r);
				list.RemoveAll(x => x < l);

				counts.Add(list.Where(x => IsPrime(((x + 1) / 2))).Count());

				//var count = 0;
				//for (int j = l; j <= r ; ++j) {
				//	if(IsPrime(j) == false) {
				//		continue;
				//	}
				//	if(IsPrime(((j + 1) / 2)) == false) {
				//		continue;
				//	}
				//	++count;
				//}

				//counts.Add(count);
			}

			foreach(var item in counts) {
				Console.WriteLine(item);
			}
		}

		public static List<int> GeneratePrime(int max)
		{
			System.Diagnostics.Debug.Assert(max >= 2);  // maxは2以上の数

			int prime;
			double sqrtMax = Math.Sqrt(max);
			var primeList = new List<int>();

			// ■ステップ 1
			// 探索リストに2からxまでの整数を昇順で入れる。
			var searchList = Enumerable.Range(2, max - 1).ToList();

			do {
				// ■ステップ 2
				// 探索リストの先頭の数を素数リストに移動し、その倍数を探索リストから篩い落とす。
				prime = searchList.First();
				// 素数リストに追加
				primeList.Add(prime);
				// 倍数をふるい落とす
				searchList.RemoveAll(n => n % prime == 0);

				// ■ステップ 3
				// 上記の篩い落とし操作を探索リストの先頭値がxの平方根に達するまで行う。
			} while (prime < sqrtMax);

			// ■ステップ 4
			// 探索リストに残った数を素数リストに移動して処理終了。
			primeList.AddRange(searchList);

			return primeList;
		}
		//public static List<int> GeneratePrime(int min, int max)
				//{
				//	int prime;
				//	double sqrtMax = Math.Sqrt(max);
				//	var primeList = new List<int>();

		//	// ■ステップ 1
		//	// 探索リストに2からxまでの整数を昇順で入れる。
		//	var searchList = Enumerable.Range(min, max - min + 1).ToList();

		//	do {
		//		// ■ステップ 2
		//		// 探索リストの先頭の数を素数リストに移動し、その倍数を探索リストから篩い落とす。
		//		prime = searchList.First();
		//		// 素数リストに追加
		//		primeList.Add(prime);
		//		// 倍数をふるい落とす
		//		searchList.RemoveAll(n => n % prime == 0);

		//		// ■ステップ 3
		//		// 上記の篩い落とし操作を探索リストの先頭値がxの平方根に達するまで行う。
		//	} while (prime < sqrtMax);

		//	// ■ステップ 4
		//	// 探索リストに残った数を素数リストに移動して処理終了。
		//	primeList.AddRange(searchList);

		//	return primeList.Where(x => IsPrime(((x + 1) / 2))).ToList();

		//	//return primeList;
		//}

		public static bool IsPrime(int num)
		{
			if (num < 2) return false;
			else if (num == 2) return true;
			else if (num % 2 == 0) return false; // 偶数はあらかじめ除く

			double sqrtNum = Math.Sqrt(num);
			for (int i = 3; i <= sqrtNum; i += 2) {
				if (num % i == 0) {
					// 素数ではない
					return false;
				}
			}

			// 素数である
			return true;
		}
	}
}