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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

#ifdef YUCHIKIDEBUG
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x)                                         \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" \
       << " " << __FUNCTION__ << endl;
#else
#define dump(x) ;
#define debug(x) ;
#endif  // YUCHIKIDEBUG

#define int long long
#define pb push_back
#define pf push_front
#define mp make_pair
#define vi vector<int>
#define vvi vector<vi>

#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, )(__VA_ARGS__)
#define _repinc(i, n) _repiinc(i, 0, n)
#define _repiinc(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define repinc(...) _overload3(__VA_ARGS__, _repiinc, _repinc, )(__VA_ARGS__)
#define _repr(i, n) repir(i, n, 0)
#define repir(i, a, b) for (int i = (int)(a); i >= (int)(b); --i)
#define repr(...) _overload3(__VA_ARGS__, repir, _repr, )(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
#define REV(x) reverse(all(x))
#define SORT(x) sort(all(x))

template <class ARG>
inline void put(ARG x) {
  cout << x << endl;
}

inline int sqr(int x) { return x * x; }
inline vi divisors(int x) {
  vi divs = {1};
  rep(i, 2, x) {
    if (x % i == 0) divs.push_back(i);
  }
  return divs;
}
inline vector<pair<int, int>> divpairs(int x) {
  vector<pair<int, int>> divs;
  rep(i, 1, x + 1) {
    if (x % i == 0) divs.push_back(make_pair(i, x / i));
  }
  return divs;
}

/// return the first i in [lb .. ub) where pred(i) holds.
/// if none of the above i satisfies pred, ub is returned.
template <class Predicate>
inline int bin_search(
    int lb, int ub,
    Predicate pred) {  // return the first i where pred(i) holds.
  while (lb + 1 < ub) {
    int mid = (lb + ub) / 2;
    if (pred(mid)) {
      ub = mid;
    } else {
      lb = mid;
    }
  }
  return pred(lb) ? lb : ub;
}

inline vector<int> to_digits(int i) {
  vector<int> digits;
  while (i >= 10) {
    digits.push_back(i % 10);
    i /= 10;
  }
  digits.push_back(i);

  reverse(digits.begin(), digits.end());
  return digits;
}

template <class T>
using matrix = vector<vector<T>>;

template <class T>
matrix<T> make_matrix(int R, int C, T value) {
  return matrix<T>(R, vector<T>(C, value));
}

template <class T, class F>
inline vector<T> operator>>(vector<T> &v, F f) {
  return f(v);
}
template <class T, class S, class F>
inline vector<S> map(F f, const vector<T> &v) {
  vector<S> res(v.size());
  transform(v.begin(), v.end(), res.begin, f);
  return res;
}

template <class T, class F>
inline vector<T> filter(F f, const vector<T> &v) {
  vector<T> res;
  copy_if(v.begin(), v.end(), back_inserter(res), f);
  return res;
}

template <class T, class S, class F>
inline S fold(F f, S initial, const vector<T> &v) {
  return accumulate(v.begin(), v.end(), initial, f);
}

const long long INF = LLONG_MAX / 2;
const double eps    = numeric_limits<double>::min() * 10;

using address = pair<int, int>;

inline int pow(int i, int n) { return (int)pow(i + eps, n); }

template <class T>
inline T &at(matrix<T> &m, address addr) {
  return m[addr.first][addr.second];
}
template <class T>
inline pair<T, T> operator+(pair<T, T> t1, pair<T, T> t2) {
  return make_pair(t1.first + t2.first, t1.second + t2.second);
}

template <class T>
inline pair<T, T> operator-(pair<T, T> t1, pair<T, T> t2) {
  return make_pair(t1.first - t2.first, t1.second - t2.second);
}

template <class T>
inline pair<T, T> operator*(pair<T, T> t1, pair<T, T> t2) {
  return make_pair(t1.first * t2.first, t1.second * t2.second);
}

template <class T>
inline pair<T, T> operator*(T t, pair<T, T> t2) {
  return make_pair(t + t2.first, t + t2.second);
}

void sayyes() { put("Yes"); }
void sayno() { put("No"); }

void exityes() {
  sayyes();
  exit(0);
};

void exitno() {
  sayno();
  exit(0);
}

int readint() {
  int i;
  cin >> i;
  return i;
}
string readstr() {
  string s;
  cin >> s;
  return s;
}

/*********************************************************************/
const long long MAXN = 1e6;
const long long MOD  = 1e9 + 7;
/*********************************************************************/

vector<int> eratosthenes(int n) {
  vector<bool> v(n + 1, true);
  rep(i, 2, sqrt(n + 1) + 5) {
    if (!v[i]) continue;
    repinc(j, i + 1, n) v[j] = v[j] & (j % i > 0);
  }

  vector<int> ans;
  ans.reserve(sqrt(n + 1) + 5);
  repinc(i, 2, n) if (v[i]) ans.pb(i);
  return ans;
}

bool prime_candidate[MAXN];
vector<int> prime_table;
vector<int> prime_table_second;
vector<int> prime_candidates;
int zero_to_N[MAXN];

void make_table() {
  rep(i, 0, MAXN) { prime_candidate[i] = true; }
  rep(i, 2, sqrt(MAXN) + 10) {
    if (!prime_candidate[i]) continue;
    rep(j, i + 1, MAXN) {
      if (j % i == 0) prime_candidate[j] = false;
    }
  }

  rep(i, 2, MAXN) {
    if (prime_candidate[i]) prime_table.pb(i);
  }

  for (auto p : prime_table) {
    prime_table_second.pb(p * 2 - 1);
  }

  set_intersection(all(prime_table), all(prime_table_second),
                   back_inserter(prime_candidates));

  int sum = 0;
  int i   = 0;
  for (auto pc : prime_candidates) {
    dump(pc);
    dump(sum);
    rep(j, i, pc) {
      dump(j);
      zero_to_N[j] = sum;
    }
    sum++;
    zero_to_N[pc] = sum;
    i             = pc + 1;
  }
  rep(j, i, MAXN) zero_to_N[j] = sum;
}

signed main() {
  make_table();

  int Q;
  cin >> Q;
  rep(i, 0, Q) {
    int l, r;
    cin >> l >> r;
    put(zero_to_N[r] - zero_to_N[l - 1]);
  }

  return 0;
}