void main()
{
    long x, y;
    rdVals(x, y);

    long u = ((y << 1) - x) / 3, v = ((x << 1) - y) / 3;

    if ((x + y) % 3 || u < 0 || v < 0)
    {
        0.writeln;
        return;
    }

    auto c = MComb(u+v);

    c.comb(u+v, u).writeln;
}

alias MInt = ModInt!(mod);
alias MComb = ModComb!(mod);

struct ModInt(long modulus)
{
    long value;
    this(long value) {this.value = (value + modulus) % modulus;}
    string toString() {return this.value.to!string;}
    ModInt opBinary(string op)(long rhs) if (op == "+" || op == "-" || op == "*") {return typeof(this)(mixin("(this.value "~op~" (rhs % modulus) + modulus) % modulus"));}
    ModInt opBinaryRight(string op)(long lhs) if (op == "+" || op == "-" || op == "*") {return opBinary!(op)(lhs);}
    ModInt opBinary(string op)(ModInt that) if (op == "+" || op == "-" || op == "*") {return typeof(this)(mixin("(this.value "~op~" that.value + modulus) % modulus"));}
    ModInt opBinary(string op)(long divisor) if (op == "/") {return this.value * modPow(divisort, modulus-2);}
    ModInt opBinaryRight(string op)(long dividend) if (op == "/") {return ModInt(dividend).value * modPow(this.value, modulus-2);}
    ModInt opBinary(string op)(ModInt that) if (op == "/") {return this.value * modPow(that.value, modulus-2);}
    ModInt opBinary(string op)(long exponent) if (op == "^^") {return modPow(this.value, exponent);}
    ModInt opBinaryRight(string op)(long base) if (op == "^^") {return modPow(base, this.value);}
    ModInt opBinary(string op)(ModInt that) if (op == "^^") {return modPow(this.value, that.value);}
    ModInt opOpAssign(string op)(long rhs) {return this = opBinary!(op)(rhs);}
    ModInt opOpAssign(string op)(ModInt that) {return this = opBinary!(op)(that);}
    ModInt modPow(long base, long exponent)
    {
        ModInt result = 1;
        while (exponent > 0)
        {
            if (exponent & 1) result = result * base;
            base = base * base % modulus;
            exponent >>= 1;
        }
        return result;
    }
}

struct ModComb(long modulus)
{
    private alias M = ModInt!(modulus);
    M[] fac, inv, finv;
    this(long limit)
    {
        fac.length = limit + 1;
        inv.length = limit + 1;
        finv.length = limit + 1;
        fac[0] = fac[1] = M(1L);
        finv[0] = finv[1] = M(1L);
        inv[1] = M(1L);
        foreach (i; 2 .. limit+1)
        {
            fac[i] = fac[i-1] * i;
            inv[i] = M(modulus) - inv[modulus%i] * (modulus / i);
            finv[i] = finv[i-1] * inv[i];
        }
    }
    M comb(long whole, long part)
    in
    {
        assert(whole < fac.length);
        assert(part < fac.length);
    }
    body
    {
        if (whole < part) return M(0);
        if (whole < 0 || part < 0) return M(0);
        return fac[whole] * finv[part] * finv[whole-part];
    }
    M comb(M whole, M part)
    {
        return comb(whole.value, part.value);
    }
}

enum long mod = 10L^^9 + 7;
enum long inf = 1L << 60;
enum double eps = 1.0e-9;

T rdElem(T = long)()
if (!is(T == struct))
{
    return readln.chomp.to!T;
}

alias rdStr = rdElem!string;
alias rdDchar = rdElem!(dchar[]);

T rdElem(T)()
if (is(T == struct))
{
    T result;
    string[] input = rdRow!string;
    assert(T.tupleof.length == input.length);
    foreach (i, ref x; result.tupleof)
    {
        x = input[i].to!(typeof(x));
    }
    return result;
}

T[] rdRow(T = long)()
{
    return readln.split.to!(T[]);
}

T[] rdCol(T = long)(long col)
{
    return iota(col).map!(x => rdElem!T).array;
}

T[][] rdMat(T = long)(long col)
{
    return iota(col).map!(x => rdRow!T).array;
}

void rdVals(T...)(ref T data)
{
    string[] input = rdRow!string;
    assert(data.length == input.length);
    foreach (i, ref x; data)
    {
        x = input[i].to!(typeof(x));
    }
}

void wrMat(T = long)(T[][] mat)
{
    foreach (row; mat)
    {
        foreach (j, compo; row)
        {
            compo.write;
            if (j == row.length - 1) writeln;
            else " ".write;
        }
    }
}

import std.stdio;
import std.string;
import std.array;
import std.conv;
import std.algorithm;
import std.range;
import std.math;
import std.numeric;
import std.mathspecial;
import std.traits;
import std.container;
import std.functional;
import std.typecons;
import std.ascii;
import std.uni;
import core.bitop;

Measured memory_bytes: 21116