
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
using namespace std;


#define LETS_GET_SCHWIFTY ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);  
#define ff              first
#define ss              second
#define int             long long
#define ll              long long
#define pb              push_back
#define pii             pair<int,int>
#define vi              vector<int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zerobits(x)      __builtin_ctzll(x)
#define mod             998244353
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define vpii            vector<pair<int,int> >
#define all(x)          x.begin(),x.end()
#define matrixprint(arr,a,b,c,d) for(int i=a;i<=c;i++){for(int j=b;j<=d;j++){cout<<arr[i][j]<<" ";}cout<<"\n";}
#define show(arr,x,y)   for(int i=x;i<=y;i++){cout<<arr[i]<<" ";}cout<<"\n"
#define sz(x)           (int)x.size()
#define db(x)           cout<<x<<"\n";

typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;

//insert,find_by_order,order_of_key,lower_bound,upper_bound;

#define TRACE
#ifdef TRACE
#define deb(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
    cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}
#else
#define deb(...)
#endif

  
//////////////////////////////code//////////////////////////////

const int N = 74;

int a,b;
int n;
vector<int> primes;

int dp[N][(1<<20)];


void solve()
{

		cin >> a >> b;

		for(int i = 2; i <= 72 ;i++)
		{
			int ok = 1;

				for(int j = 2; j < i ;j++)
				{
						if(i % j == 0)
							ok = 0;
				}

			if(ok)
				primes.pb(i);
		}

		n = sz(primes);

	    memset(dp,0,sizeof(dp));

	    dp[0][0] = 1;

	    for(int i = 1;i <= (b - a + 1) ;i++)
	    {
	    	   int mask1 = 0,bit = 1;

	    		for(int j = 0;j < n ; j++)
	    		{
	    				if((a + i - 1)%primes[j] == 0)
	    				 mask1 |= bit;

	    				bit<<=1;
	    		}

               for(int mask = 0;mask < (1 << n); mask++)
               {
               			if( ((mask)&(mask1)) == 0)
               			{
               					dp[i][(mask | mask1)] += dp[i-1][mask];
               			}
               			
               			dp[i][mask] += dp[i - 1][mask];
               }
	    }

	    int ans = 0;

	    for(int mask = 0; mask < (1 << n); mask++)
	    {
	    		ans += dp[(b-a+1)][mask];
	    }


	    db(ans)
			

}

int32_t main()
{   

    LETS_GET_SCHWIFTY;

     #ifndef ONLINE_JUDGE
     freopen("INP.txt", "r", stdin);
     freopen("out.txt", "w", stdout);
     #endif  


    int t = 1;
  // cin >> t;

    while (t--)
        solve();

}

// check out for following mistakes-
// if using pb operation on vector and then trying to access index..check if sizeof that vec could remain 0 only
// is using prime sieve make sure it fits
// when using factorial template or combinatorics make sure that you edit fillfac fun values and array values


#include <iostream>
#include <numeric>
#include <vector>

using namespace std;

using Mask = int;

bool IsPrime(int n) {
    if (n < 2) {
        return false;
    }

    for (int64_t i = 2; i * i <= n; i += 1) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

vector<int> Primes(int limit) {
    vector<int> primes;
    for (int i = 2; i <= limit; i += 1) {
        if (IsPrime(i)) {
            primes.push_back(i);
        }
    }
    return primes;
}

Mask GetMask(int64_t num) {
    Mask mask = 0;

    static const auto kPrimes = Primes(72);
    for (size_t i = 0; i < kPrimes.size(); i += 1) {
        if (num % kPrimes[i] == 0) {
            mask |= (1 << i);
        }
    }
    return mask;
}

int64_t Solve(int64_t l, int64_t r) {
    vector<int64_t> sets(1 << 20, 0);
    sets[0] = 1;

    vector<Mask> masks;
    for (auto i = l; i <= r; i += 1) {
        masks.push_back(GetMask(i));
    }

    for (const auto& mask : masks) {
        for (Mask primes = mask; primes < (1 << 20); primes += 1) {
            if ((primes & mask) == mask) {
                sets[primes] += sets[primes & (~mask)];
            }
        }
    }
    return accumulate(sets.begin(), sets.end(), 0);
}

int main() {
    int64_t l, r;
    cin >> l >> r;

    auto res = Solve(l, r);
    cout << res << "\n";
    return 0;
}
