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 Haskell (GHC 7.10.3) (judge verdict: Accepted)

import           Control.Applicative
import           Control.DeepSeq
import           Control.Monad
import           Control.Monad.ST
import qualified Data.Array                    as A
import qualified Data.Array.IArray             as IA
import qualified Data.Array.IO                 as AI
import qualified Data.Array.MArray             as MA
import qualified Data.Array.ST                 as STA
import qualified Data.Array.Unboxed            as AU
import           Data.Bits
import qualified Data.ByteString.Char8         as BS
import           Data.Char
import qualified Data.Graph                    as G
import           Data.Int
import qualified Data.IntMap                   as IM
import qualified Data.IntSet                   as IS
import           Data.List
import qualified Data.Map.Strict               as M
import           Data.Maybe
import           Data.Ord
import qualified Data.Sequence                 as SQ
import qualified Data.Set                      as S
import           Data.Time
import qualified Data.Tree                     as T
import qualified Data.Vector                   as V
import qualified Data.Vector.Mutable           as VM
import qualified Data.Vector.Unboxed           as VU
import qualified Data.Vector.Unboxed.Mutable   as VUM

readInt :: IO Int
readInt = fst . fromJust . BS.readInt <$> BS.getLine

readInts :: IO [Int]
readInts = map (fst . fromJust . BS.readInt) . BS.words <$> BS.getLine

readIntLists :: Int -> IO [[Int]]
readIntLists n = replicateM n readInts

readInteger :: IO Integer
readInteger = fst . fromJust . BS.readInteger <$> BS.getLine

readIntegers :: IO [Integer]
readIntegers = map (fst . fromJust . BS.readInteger) . BS.words <$> BS.getLine

readIntegerLists :: Int -> IO [[Integer]]
readIntegerLists n = replicateM n readIntegers

readStrings :: IO [String]
readStrings = map BS.unpack . BS.words <$> BS.getLine

readStringLists :: Int -> IO [[String]]
readStringLists n = replicateM n <$> readStrings

toPair :: [a] -> (a, a)
toPair [x, y] = (x, y)

count :: Eq a => a -> [a] -> Int
count a as = length $ filter (== a) as

put :: Show a => a -> IO ()
put = putStr . show

putList :: Show a => [a] -> IO ()
putList [n     ] = print n
putList (n : ns) = do
  put n
  putStr " "
  putList ns

putStrList :: [String] -> IO ()
putStrList [n     ] = putStrLn n
putStrList (n : ns) = do
  putStr n
  putStr " "
  putStrList ns

yesNoUpper b | b         = putStrLn "YES"
             | otherwise = putStrLn "NO"

yesNo b | b         = putStrLn "Yes"
        | otherwise = putStrLn "No"

divCeiling x n | b == 0    = a
               | otherwise = a + 1
  where (a, b) = x `divMod` n

main = do
  q       <- readInt
  queries <- map toPair <$> readIntLists q
  mapM_ print $ solve queries

solve qs = map (\x -> g x ps) qs
 where
  primes =
    filter (\x -> isPrime $ (x + 1) `div` 2) $ sieveOfEratosthenes 100000
  ps = V.fromList $ f [2 .. 100000] primes [0]


g (l, r) pvs | l /= 1    = pvs V.! (r - 1) - pvs V.! (l - 2)
             | otherwise = pvs V.! (r - 1)

f []       _  acc        = reverse acc
f (i : is) [] (ac : acc) = f is [] (ac : ac : acc)
f (i : is) (p : ps) (ac : acc) | i == p    = f is ps (ac + 1 : ac : acc)
                               | otherwise = f is (p : ps) (ac : ac : acc)

sieveOfEratosthenes :: Int -> [Int]
sieveOfEratosthenes n | n < 2     = []
                      | n == 2    = [2]
                      | otherwise = sieve [ x | x <- [2 .. n] ] n
 where
  sieve :: [Int] -> Int -> [Int]
  sieve [] _ = []
  sieve (x : xs) n | x ^ 2 > n = x : xs
                   | otherwise = x : (sieve [ a | a <- xs, a `mod` x > 0 ] n)

-- エラトステネスのふるい
isPrime' :: Int -> Bool
isPrime' n | n < 2     = False
           | otherwise = n == last (sieveOfE [2 .. n])

 where
  sieveOfE :: [Int] -> [Int]
  sieveOfE []  = []
  sieveOfE [a] = [a]
  sieveOfE all@(x : xs)
    | x < 2           = error "`head list` must be `> 1`"
    | last xs < x ^ 2 = all
    | otherwise       = x : sieveOfE [ n | n <- all, n `mod` x /= 0 ]


-- 試し割り
isPrime :: Int -> Bool
isPrime 2 = True
isPrime n | n < 2            = False
          | (n `mod` 2) == 0 = False
          | otherwise        = testDiv 3 n
 where
  testDiv :: Int -> Int -> Bool
  testDiv i n | i * i > n      = True
              | n `mod` i == 0 = False
              | otherwise      = testDiv (i + 2) n