#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>

using namespace std;

const size_t MAXK = 62;
const long long MOD = 1000000007;

size_t rang(vector<vector<bool> > a)
{
	size_t column = 0;
	size_t n = a.size();
	size_t m = a[0].size();
	bool used[n];
	size_t ans = 0;
	for (size_t i = 0; i < n; i++)
		used[i] = false;

	for (size_t column = 0; column < m; column++)
	{
		bool found = false;
		size_t row;
		for (size_t i = 0; i < n; i++)
		{
			if (a[i][column] && !used[i])
			{
				found = true;
				row = i;
				break;
			}
		}
		if (!found)
			continue;
		used[row] = true;
		for (size_t i = 0; i < n; i++)
		{
			if (!a[i][column] || i == row)
				continue;
			for (size_t j = 0; j < m; j++)
				a[i][j] = a[i][j] ^ a[row][j];
		}
		ans++;
	}
	return ans;
}

int main()
{
	ifstream in("stones.in");
	ofstream out("stones.out");
	long long k, n;
	in >> n >> k;
	vector<long long> values;
	long long mx = -1;
	for (int i = 1; i < MAXK; i++)
		for (int j = 0; i + j < MAXK; j++)
		{
			long long now = ((1LL << i) - 1) << j;
			if (now <= k && i == 1 && now > mx)
				mx = now;
			if (now <= k)
				values.push_back(now);
		}
	if (n > 2 * mx - 1)
	{
		out << "0\n";
		return 0;
	}
	size_t m = values.size();
//	cerr << m << "\n";
	vector<vector<bool> > a(m);
	for (size_t i = 0; i < m; i++)
	{
		a[i] = vector<bool>(MAXK);
		for (size_t j = 0; j < MAXK; j++)
			a[i][j] = (values[i] >> j) & 1;
	}
	size_t r = rang(a);
	long long ans = 1;
	for (size_t i = 0; i < m - r; i++)
		ans = (ans * 2) % MOD;
	out << ans << "\n";
}
