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.15.1) (judge verdict: Accepted)

use std::io::{BufRead, Write};
use std::io;

mod primal {
    #[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Debug)]
    struct U128 {
        hi: u64,
        lo: u64,
    }

    fn modulo(mut a: U128, m: u64) -> u64 {
        if a.hi >= m {
            a.hi -= (a.hi / m) * m;
        }
        let mut x = a.hi;
        let mut y = a.lo;
        for _ in 0..64 {
            let t = (x as i64 >> 63) as u64;
            x = (x << 1) | (y >> 63);
            y <<= 1;
            if (x | t) >= m {
                x = x.wrapping_sub(m);
                y += 1;
            }
        }
        x
    }

    fn mul128(u: u64, v: u64) -> U128 {
        let u1 = u >> 32;
        let u0 = u & (!0 >> 32);
        let v1 = v >> 32;
        let v0 = v & (!0 >> 32);

        let t = u0 * v0;
        let w0 = t & (!0 >> 32);
        let k = t >> 32;

        let t = u1 * v0 + k;
        let w1 = t & (!0 >> 32);
        let w2 = t >> 32;

        let t = u0 * v1 + w1;
        let k = t >> 32;
        U128 {
            lo: (t << 32) + w0,
            hi: u1 * v1 + w2 + k,
        }
    }

    fn mod_mul_(a: u64, b: u64, m: u64) -> u64 {
        modulo(mul128(a, b), m)
    }

    fn mod_mul(a: u64, b: u64, m: u64) -> u64 {
        match a.checked_mul(b) {
            Some(r) => if r >= m { r % m } else { r },
            None => mod_mul_(a, b, m),
        }
    }

    fn mod_sqr(a: u64, m: u64) -> u64 {
        if a < (1 << 32) {
            let r = a * a;
            if r >= m {
                r % m
            } else {
                r
            }
        } else {
            mod_mul_(a, a, m)
        }
    }

    fn mod_exp(mut x: u64, mut d: u64, n: u64) -> u64 {
        let mut ret: u64 = 1;
        while d != 0 {
            if d % 2 == 1 {
                ret = mod_mul(ret, x, n)
            }
            d /= 2;
            x = mod_sqr(x, n);
        }
        ret
    }

    /// Test if `n` is prime, using the deterministic version of the
    /// Miller-Rabin test.
    ///
    /// Doing a lot of primality tests with numbers strictly below some
    /// upper bound will be faster using the `is_prime` method of a
    /// `Sieve` instance.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate primal;
    /// assert_eq!(primal::is_prime(1), false);
    /// assert_eq!(primal::is_prime(2), true);
    /// assert_eq!(primal::is_prime(3), true);
    /// assert_eq!(primal::is_prime(4), false);
    /// assert_eq!(primal::is_prime(5), true);
    ///
    /// assert_eq!(primal::is_prime(22_801_763_487), false);
    /// assert_eq!(primal::is_prime(22_801_763_489), true);
    /// assert_eq!(primal::is_prime(22_801_763_491), false);
    /// ```
    pub fn miller_rabin(n: u64) -> bool {
        const HINT: &'static [u64] = &[2];

        // we have a strict upper bound, so we can just use the witness
        // table of Pomerance, Selfridge & Wagstaff and Jeaschke to be as
        // efficient as possible, without having to fall back to
        // randomness.
        const WITNESSES: &'static [(u64, &'static [u64])] =
            &[(2_046, HINT),
                (1_373_652, &[2, 3]),
                (9_080_190, &[31, 73]),
                (25_326_000, &[2, 3, 5]),
                (4_759_123_140, &[2, 7, 61]),
                (1_112_004_669_632, &[2, 13, 23, 1662803]),
                (2_152_302_898_746, &[2, 3, 5, 7, 11]),
                (3_474_749_660_382, &[2, 3, 5, 7, 11, 13]),
                (341_550_071_728_320, &[2, 3, 5, 7, 11, 13, 17]),
                (0xFFFF_FFFF_FFFF_FFFF, &[2, 3, 5, 7, 11, 13, 17, 19, 23])
            ];

        if n % 2 == 0 { return n == 2; }
        if n == 1 { return false; }

        let mut d = n - 1;
        let mut s = 0;
        while d % 2 == 0 {
            d /= 2;
            s += 1
        }

        let witnesses =
            WITNESSES.iter().find(|&&(hi, _)| hi >= n)
                .map(|&(_, wtnss)| wtnss).unwrap();
        'next_witness: for &a in witnesses.iter() {
            let mut power = mod_exp(a, d, n);
            assert!(power < n);
            if power == 1 || power == n - 1 { continue 'next_witness }

            for _r in 0..s {
                power = mod_sqr(power, n);
                assert!(power < n);
                if power == 1 { return false; }
                if power == n - 1 {
                    continue 'next_witness
                }
            }
            return false;
        }

        true
    }
}

fn solve<R: BufRead, W: Write>(mut input: R, mut output: W) {
    let mut buf = String::new();
    input.read_line(&mut buf).unwrap();
    let q: usize = buf.trim_right().parse().unwrap();
    let lr: Vec<(usize, usize)> = (0..q).map(|_| {
        buf.clear();
        input.read_line(&mut buf).unwrap();
        let mut split = buf.split_whitespace();
        (split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap())
    }).collect();
    let mut sums: Vec<usize> = Vec::with_capacity(50001);
    let mut acc = 0;
    for i in 0..50001 {
        sums.push(acc);
        if primal::miller_rabin(i as u64 * 2 + 1) && primal::miller_rabin(i as u64 + 1) { acc += 1; }
    }
    for q in lr {
        writeln!(output, "{}", sums[(q.1 + 1) / 2] - sums[(q.0 - 1) / 2]).unwrap();
    }
}

fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    solve(stdin.lock(), stdout.lock());
}

#[cfg(test)]
mod tests {
    fn test(input: &str, output: &str) {
        let mut v: Vec<u8> = Vec::new();
        ::solve(input.as_bytes(), &mut v);
        assert_eq!(String::from_utf8(v).unwrap(), output);
    }

    #[test]
    fn case1() {
        test(
            "1
3 7
",
            "2
",
        );
    }

    #[test]
    fn case2() {
        test(
            "4
13 13
7 11
7 11
2017 2017
",
            "1
0
0
1
",
        );
    }

    #[test]
    fn case3() {
        test(
            "6
1 53
13 91
37 55
19 51
73 91
13 49
",
            "4
4
1
1
1
2
",
        );
    }
}