#include <stdio.h>
#include <iostream>
#include <string.h>
#include <limits.h>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <math.h>

typedef unsigned long long ULLONG;
typedef long long LLONG;

template <class _T> static _T tp_abs(const _T& a) {
	return ((a < 0) ? (a * -1) : a);
}
template <class _T> static _T tp_min(_T a, _T b) {
	return a < b ? a : b;
}
template <class _T> static _T tp_max(_T a, _T b) {
	return a > b ? a : b;
}
template<class _T> static void get1int(_T& a) {
	const char* fmt = " %d";
	if (sizeof(_T) == sizeof(long long)) {
		fmt = " %lld";
	}

	if (scanf(fmt, &a) < 0) {
		printf("g1int Error\n");
	}
}
template<class _T> static void get2int(_T& a, _T& b) {
	const char* fmt = " %d %d";
	if (sizeof(_T) == sizeof(long long)) {
		fmt = " %lld %lld";
	}

	if (scanf(fmt, &a, &b) < 0) {
		printf("g2int Error\n");
	}
}
template<class _T> static void get3int(_T& a, _T& b, _T& c) {
	const char* fmt = " %d %d %d";
	if (sizeof(_T) == sizeof(long long)) {
		fmt = " %lld %lld %lld";
	}

	if (scanf(fmt, &a, &b, &c) < 0) {
		printf("g3int Error\n");
	}
}
static void getstring(char* buff) {
	if (scanf(" %s", buff) < 0) {
		printf("getstr error!\n");
	}
}
template <class _T> static _T tp_pow(int base, int exp)
{
	_T ans = 1;

	for (int i = 0; i < exp; i++) {
		ans *= base;
	}
	return ans;
}
static const long long MOD_NUM = 1000000007LL;
template <class _Ty> class PermComb
{
protected:

	_Ty _maxNum = 0;
	_Ty _use_mod = 0;
	_Ty* _fact = 0;
	_Ty* _inv = 0;
	_Ty* _finv = 0;

	PermComb() {}

public:
	PermComb(_Ty maxNum, _Ty use_mod = 0) {
		_maxNum = maxNum;
		_use_mod = use_mod;
		_fact = new _Ty[(unsigned int)maxNum + 1];
		_fact[0] = _fact[1] = 1;

		if (_use_mod) {
			_inv = new _Ty[(unsigned int)maxNum + 1];
			_finv = new _Ty[(unsigned int)maxNum + 1];
			_inv[0] = _inv[1] = 1;
			_finv[0] = _finv[1] = 1;
		}

		for (_Ty i = 2; i <= maxNum; i++) {
			_fact[i] = _fact[i - 1] * i;
			if (_use_mod) {
				_fact[i] %= _use_mod;
				_inv[i] = _use_mod - _inv[_use_mod % i] * (_use_mod / i) % _use_mod;
				_finv[i] = _finv[i - 1] * _inv[i] % _use_mod;
			}
		}
	}

	//	get permutation value
	virtual _Ty nPk(int n, int k) {
		if ((k > _maxNum) || (n > _maxNum) || (k > n) || (k < 0) || (n < 0)) {
			return 0;
		}
		return(_fact[n] / _fact[n - k]);
	}

	//	get combination value
	virtual _Ty nCk(int n, int k) {
		_Ty ans = 0;
		if ((k > _maxNum) || (n > _maxNum) || (k > n) || (k < 0) || (n < 0)) {
			ans = 0;
		}
		else if (_use_mod == 0) {
			ans = nPk(n, k);
			ans /= _fact[k];
		}
		else {
			ans = _fact[n] * (_finv[k] * _finv[n - k] % _use_mod) % _use_mod;
		}
		return ans;
	}

	//	destructor
	~PermComb() {
		delete[] _fact;
		delete[] _inv;
		delete[] _finv;
	}
};

template <class _T> _T tp_fact(_T N) {
	_T num = N;
	_T ans = 1;
	while (N) {
		ans *= N;
		N--;
	}
	return ans;
}

static void D_task();

int main()
{
	D_task();
	fflush(stdout);
	return 0;
}

static void D_task()
{
	int X, Y;
	get2int(X, Y);

	if ((X + Y) % 3) {
		printf("0\n");
		return;
	}

	int diff = tp_abs(X - Y);

	int less = (tp_min(X, Y) - diff) / 3;

	int total = less * 2 + diff;

	PermComb<LLONG> cmb(total, MOD_NUM);

	printf("%lld\n", cmb.nCk(total, less));
}


Measured memory_bytes: 15872