#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pp pop_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#define UNIQUE(v) sort(all(v)); v.erase(unique(all(v)), v.end())
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()
#define PQ priority_queue
constexpr ll inf = 1e9 + 7;

template <typename T>
class TreeArray {
private:
	int n;
	vector<T> bit1, bit2;

	void add(vector<T>& bit, int idx, T val) {
		while (idx <= n) {
			bit[idx] += val;
			idx += idx & -idx;
		}
	}

	T sum(const vector<T>& bit, int idx) const {
		T s = 0;
		while (idx > 0) {
			s += bit[idx];
			idx -= idx & -idx;
		}
		return s;
	}

	T prefix(int idx) const {
		return sum(bit1, idx) * idx - sum(bit2, idx);
	}

public:
	TreeArray(int len) : n(len) {
		bit1.assign(n + 1, 0);
		bit2.assign(n + 1, 0);
	}

	void rangeUpdate(int l, int r, T val) {
		add(bit1, l, val);
		add(bit1, r + 1, -val);
		add(bit2, l, val * (l - 1));
		add(bit2, r + 1, -val * r);
	}

	T rangeQuery(int l, int r) const {
		return prefix(r) - prefix(l - 1);
	}

	T pointQuery(int idx) const {
		return rangeQuery(idx, idx);
	}
};

void solve() {
	int n = 1e6 + 10;
	TreeArray<int> tr(n + 1);
	vector<bool> primes(n + 1, true);
	for (int i = 2; i <= n; i++) {
		if (primes[i]) {
			for (int j = 2; j * i <= n; j++) {
				primes[i * j] = false;
			}
		}
	}	

	for (int i = 2; i <= n; i++) {
		if (primes[i] == true) {
			tr.rangeUpdate(i, i, 1);
		}
	}

	int T;
	cin >> T;

	for (int i = 1; i <= T; i++) {
		int l, r;
		cin >> l >> r;
		int ans = tr.rangeQuery(l, r);
		cout << ans << "\n";
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	while (t--) solve();
	return 0;
}