#include <bits/stdc++.h>
using namespace std;
using u128 = __uint128_t;
using ull = unsigned long long;
using i128 = __int128_t;
static inline int bitlen(unsigned long long x){
return x ? 64 - __builtin_clzll(x) : 0;
}
static inline int popcnt(unsigned long long x){
return __builtin_popcountll(x);
}
// x 이하에서 popcount를 최대화하는 수(같은 비트 길이 내에서)
// 방법: MSB에서 내려오며, 처음 0을 만나는 순간 그 아래를 전부 1로 채움.
static inline unsigned long long best_leq(unsigned long long x){
int L = bitlen(x);
if (x == ((L ? (1ULL<<L) : 0ULL) - 1)) return x; // 이미 all-ones
unsigned long long y = 0;
bool hitZero = false;
for (int i = L-1; i >= 0; --i){
ull bit = (x>>i)&1ULL;
if (hitZero){
y |= (1ULL<<i); // 아래 비트 전부 1
}else{
if (bit) y |= (1ULL<<i); // prefix 유지
else hitZero = true; // 첫 0: 여긴 0, 아래는 1로 채움
}
}
return y;
}
static inline int g_of_x(ull x){
return bitlen(x) - popcnt(x);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
if(!(cin>>T)) return 0;
while(T--){
unsigned long long a,b; cin>>a>>b;
// 1) [a,b]에 2의 거듭제곱이 있으면 답 0
ull p = 1ULL << (bitlen(b)-1); // b 이하 최댓 2의 거듭제곱
if (p >= a){
cout << 0 << '\n';
continue;
}
ull A = a-1, B = b-1;
int ans = INT_MAX;
// 후보 집합(중복 방지용)
vector<ull> cand;
auto push = [&](ull x){
if (x < A || x > B) return;
cand.push_back(x);
};
// 2) B 기반 후보
push(best_leq(B));
// 경계값도 넣어둠
push(A);
push(B);
// 3) A의 각 0비트를 올리고 아래를 1로 채운 후보들
int LA = bitlen(A);
for (int i = 0; i < LA; ++i){
if (((A>>i)&1ULL)==0ULL){
ull z = A | (1ULL<<i);
z |= ((1ULL<<i)-1); // 아래 전부 1
push(z);
}
}
// 4) 비트 길이 구간별 상단에서의 후보들
int LB = bitlen(B);
for (int L = bitlen(A); L <= LB; ++L){
ull low = max<ull>(A, (L? (1ULL<<(L-1)) : 0ULL));
ull high = min<ull>(B, (L? ((1ULL<<L)-1) : 0ULL));
if (low <= high){
push(best_leq(high));
}
}
// 평가
for (ull x: cand){
ans = min(ans, g_of_x(x));
}
cout << ans << '\n';
}
return 0;
}