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 Rust (1.42.0) (judge verdict: Accepted)

use itertools::iterate;
use proconio::input;

trait IntoIntegerIndexedVec {
    type Output;
    #[warn(dead_code)]
    fn into_i32_indexed_vec(self, offset: usize) -> IntegerIndexedVec<Self::Output>;
}
impl<T> std::ops::IndexMut<i32> for IntegerIndexedVec<T> {
    #[warn(dead_code)]
    fn index_mut(&mut self, index: i32) -> &mut T {
        let actual_index = index + (self.offset as i32);
        &mut self.v[actual_index as usize]
    }
}
impl<T> std::ops::Index<i32> for IntegerIndexedVec<T> {
    type Output = T;
    #[warn(dead_code)]
    fn index(&self, index: i32) -> &Self::Output {
        let actual_index = index + (self.offset as i32);
        &self.v[actual_index as usize]
    }
}
impl<T> IntoIterator for IntegerIndexedVec<T> {
    type Item = T;
    type IntoIter = std::vec::IntoIter<T>;
    #[warn(dead_code)]
    fn into_iter(self) -> std::vec::IntoIter<T> {
        self.v.into_iter()
    }
}
impl<T> IntegerIndexedVec<T> {
    fn new(v: Vec<T>, offset: usize) -> Self {
        IntegerIndexedVec { v, offset }
    }
    #[allow(dead_code)]
    fn iter(&self) -> std::slice::Iter<T> {
        self.v.iter()
    }
}
#[derive(Debug, Clone)]
struct IntegerIndexedVec<T> {
    v: Vec<T>,
    offset: usize,
}
impl<T> IntoIntegerIndexedVec for Vec<T> {
    type Output = T;
    #[warn(dead_code)]
    fn into_i32_indexed_vec(self, offset: usize) -> IntegerIndexedVec<T> {
        IntegerIndexedVec::new(self, offset)
    }
}

fn sieves(n: i32) -> IntegerIndexedVec<bool> {
    let mut s = vec![true; (n + 1) as usize].into_i32_indexed_vec(0);
    s[0] = false;
    s[1] = false;
    for i in iterate(2, |&i| i + 1).take_while(|&i| i * i <= n) {
        if s[i] {
            for j in ((i * 2)..=n).step_by(i as usize) {
                s[j] = false;
            }
        }
    }
    s
}

fn solve(_q: usize, lr: &[(i32, i32)]) -> Vec<usize> {
    const N: i32 = 100000;
    let s = sieves(N);
    let mut r = vec![false; (N + 1) as usize].into_i32_indexed_vec(0);
    for i in 0..=N {
        if i % 2 != 0 && s[i] && s[(i + 1) / 2] {
            r[i] = true;
        }
    }
    let mut c = vec![0; (N + 1) as usize].into_i32_indexed_vec(0);
    for i in 1..=N {
        c[i] = c[i - 1] + r[i] as usize;
    }
    lr.iter().map(|&(l, r)| c[r] - c[l - 1]).collect::<Vec<_>>()
}

fn main() {
    input! {
        q: usize,
        lr: [(i32, i32); q],
    }
    let r = solve(q, &lr);
    for x in r {
        println!("{}", x);
    }
}