/*
オーダー
10**6	余裕を持って間に合う	
10**7	おそらく間に合う	余裕を持って間に合う
10**8	非常にシンプルな処理でない限り厳しい	おそらく間に合う
10**9		非常にシンプルな処理でない限り厳しい
logn	:OK
n		:10^7
nlogn	:10^6
n**2	:10^4
n**3	:300
2**n	:20
n!		:10



// 各桁の和を計算する関数
int findSumOfDigits(int n) {
  int sum = 0;
  while (n > 0) { // n が 0 になるまで
    sum += n % 10;
    n /= 10;
  }
  return sum;
}

sort(a, a + N, greater<int>());  // a[0:N] を大きい順にソート

int num[110] = {0};  // バケット
for (int i = 0; i < N; ++i) {
    num[d[i]]++;  // d[i] が 1 個増える
}

map<string, int> mp; // 連想配列 map<キー型, 値型> オブジェクト名
for (int i = 0; i < N; ++i) {
    auto itr = mp.find(s[i]);        // s[i] が設定されているか？
    if(itr != mp.end() ) {
         mp[s[i]] += 1;
    }
    else {
         mp[s[i]] += 1 ;
    }
}
stack<int> s;	//intをデータとするスタックを用意
s.push(1);		//{} -> {1}
printf("%d\n", s.top());	// 3
s.pop();

queue<int> que;	//intをデータとするキューを用意
que.push(1);		//{} -> {1}
printf("%d\n", que.front());	// 1
que.pop();
*/

#include <iostream>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <string.h>

using namespace std;

// #define for(i,a,b) for (int i=(a);i<(b);++i)
typedef long long ll;
typedef pair<ll,ll> P;
#define REP(i,n) for(long long i = 0; i < (long long)(n); i++)
#define pb push_back // vectorに要素追加
#define INF (ll)1e18
// int 
// // 各桁の和を計算する関数
// int findSumOfDigits(int n) {
//   int amari = 0;
//   int keta = 0;
//   while (n > 0) { // n が 0 になるまで
//     amari += n % 2;
//     if (keta%2==0)
//     n /= 10;
//   }
//   return sum;
// }
 
ll gcd(ll a, ll b) {
	if(b == 0) return a;
	return gcd(b, a % b);
}

// const ll MAX_N = 1e5;
// ll N;
// ll h[MAX_N];
// ll dp[MAX_N+1]; // メモ化テーブル
 
// // i番目以降の品物から重さの総和がj以下になるように選ぶ
// void rec(ll i){
// 	if (i==0) dp[i] = 0;
// 	else if (i==1) dp[i] = abs(h[1]-h[0]);
// 	else dp[i] = min(dp[i-1]+abs(h[i]-h[i-1]), dp[i-2]+abs(h[i]-h[i-2]));
// 	return;
// }
 
 
int main() {
	// 入力
	ll A,B;cin>>A>>B;
	
	// 解法
	ll B_minus_A = B-A+1;
	vector<ll> A_bit, B_bit; // 2進数を表すベクトル
	
	while(B>0){
		B_bit.pb(B%2);
		B /=2;
	}
	
	REP(i,B_bit.size()){
		A_bit.pb(A%2);
		A /=2;
	}
	// REP(i,A_bit.size())printf("%lld ", A_bit[A_bit.size()-i-1]);
	// printf("\n");
	// REP(i,B_bit.size())printf("%lld ", B_bit[B_bit.size()-i-1]);
	// printf("\n");
	
	ll ans = 0;
	REP(i,A_bit.size()){ // i桁目について
		ll freq = pow(2,i+1); // 桁が変わる周期 0桁なら2, 1桁なら4
		ll phase = 0; // 0からはじめて位相がfreq中の何番目か
		for(ll j = 0; j <= i; j++) phase += A_bit[j]*pow(2,j);
		phase = (phase+freq/2)%freq; // 位相を半分ずらして0から1になるところを始点にする
		ll count = 0; // 個の桁の値が1である数字の合計数
		ll cycle = B_minus_A/freq; // 桁の周期を何回回るか
		count += cycle * freq / 2; // 完全に含まれる周期の数からのカウント
		ll remain = B_minus_A%freq; // 不完全周期
		//不完全周期についての計算
		if (phase+1<=freq/2){
			if (phase+remain+1<=freq/2){
				count += remain;
			}
			else if (phase+remain+1<=freq){
				count += freq/2 - phase;
			}
			else if (phase+remain+1<=freq+freq/2){
				count += freq/2 - phase + (phase+remain) - freq;
			}
		}else{
			if (phase+remain+1<=freq){
				count += 0;
			}
			else if (phase+remain+1<=freq+freq/2){
				count += (phase+remain) - freq;
			}
			else if (phase+remain+1<=freq*2){
				count += freq/2;
			}
		}
		// printf("i: %lld, freq: %lld, phase: %lld, cycle: %lld, remain: %lld, count: %lld\n",
		// 		i, freq, phase, cycle, remain, count);
		ans += (count%2) * pow(2,i);
		// ll freq = pow(2,i*2); // freq数で桁が変わってまた戻る
		// ll keep = pow(2,i)-amari-1; // A+keepで値が切り替わる
		// if (shou==1){
			
		// }
	}
	
	
	
	//出力
	cout << ans << endl;
	// printf("%lld\n", ans); // lld としないとオーバーフローする
	// if (ans) printf("Yes\n");
	// else printf("No\n");
}


Measured memory_bytes: 256