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 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;
    let mut i = 2;
    while i*i <= n {
        if s[i] {
            for j in ((i*2)..=n).step_by(i as usize) {
                s[j] = false;
            }
        }
        i += 1;
    }
    s
}

fn solve(_q: usize, lr: &[(i32, i32)]) -> Vec<usize> {
    const N: i32 = 100000;
    let s = sieves(N);
    let r = (0..=N).map(|i| i % 2 != 0 && s[i] && s[(i + 1) / 2]).collect::<Vec<_>>().into_i32_indexed_vec(0);
    let c = r.iter().scan(0, |s, &b| {
            *s += if b { 1 } else { 0 };
            Some(*s)
    }).collect::<Vec<_>>().into_i32_indexed_vec(0);
    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);
    }
}