#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=70;
int a[N];
//设f(pos,det)f(pos,det)表示处理到pos位,当前detdet是多少的答案。
//detdet是这个二进制数0的数量减去1的数量
//当然需要注意的是,11的数量可能大于00的数量导致detdet为负,所以我们加上一个35作为基值
//如果当前前导0标记为1且本位也是0,表示当前位也是前导0,pos+1继续搜索
//如果当前前导0标记为1但本位不是0,表示当前位为该次搜索的最高位
//
int f[N][N];
int dfs(int pos,int det,bool limit,bool lead)
{
if(pos==0)
return det>=35;
// 如果不是-1,说明之前更新过了
if(!limit && !lead && f[pos][det]!=-1)
return f[pos][det];
//limit是指,上一位是不是和原始数字的相同
//也就是,是不是n的一部分
//如果limit存在,也就是说,上一位和n的上一位相同
//那么当前这一位最大只能是a[pos]
//如果limit不存在,也就是上一位比n的上一位小
//那么当前位就可以取到1
int up;
if(limit)
up=a[pos];
else
up=1;
int ans=0;
for(int i=0;i<=up;i++)
{
//当前位填0,而且又前导0
if(i==0 && lead)
//那么继续搜
// 如果上一位有限制,这一位和n的这一位相同,那么limit就会传递
// 差值还是基数
ans+=dfs(pos-1,35,limit && (i==a[pos]),true);
//如果当前位填1
else if(i)
// 差值减1 限制 前导0标记情空,表示当前位为该次搜索的最高位
ans+=dfs(pos-1,det-1,limit&&(i==a[pos]),false);
//如果当前位填0,没有前导0
else
// 差值+1 限制传递
ans+=dfs(pos-1,det+1,limit&&(i==a[pos]),false);
}
//记录,只有当没有限制的时候 而且 没有前导0的时候 才会记录
if(!limit && !lead)
f[pos][det]=ans;
return ans;
}
int solve(int x)
{
int len=0;
while(x)
{
a[++len]=x&1;
x>>=1;
}
return dfs(len,35,1,1);
}
int main()
{
memset(f,-1,sizeof f);
int l,r;
cin>>l>>r;
if(l>r)
swap(l,r);
cout<<solve(r)-solve(l-1)<<endl;
return 0;
}