public class Euler873 {

    static final long MOD = 1000000007L;

    static long modPow(long a, long e) {
        long r = 1;
        while (e > 0) {
            if ((e & 1) == 1)
                r = (r * a) % MOD;
            a = (a * a) % MOD;
            e >>= 1;
        }
        return r;
    }

    static long wordsMod(long p, long q, long r) {
        if (p > q) {
            long temp = p;
            p = q;
            q = temp;
        }
        long m = p + q;

        long[] inv = new long[(int) (m + 1)];
        if (m >= 1)
            inv[1] = 1;
        for (int i = 2; i <= (int) m; ++i) {
            inv[i] = MOD - ((MOD / i) * inv[(int) (MOD % i)]) % MOD;
        }

        long comb0 = 1;
        for (int i = 1; i <= (int) m; ++i) {
            comb0 = (comb0 * ((r + i) % MOD)) % MOD;
            comb0 = (comb0 * inv[i]) % MOD;
        }

        if (p == 0 || q == 0)
            return comb0;

        long maxTrans = (p == q) ? (2 * p - 1) : (2 * p);
        long tmax = Math.min(m - 1, Math.min(r / 2, maxTrans));
        if (tmax <= 0)
            return 0;

        int umax = (int) (tmax / 2);
        long[] cp = new long[umax + 1];
        long[] cq = new long[umax + 1];
        cp[0] = 1;
        cq[0] = 1;

        for (int u = 1; u <= umax; ++u) {
            if (u <= p - 1) {
                cp[u] = cp[u - 1] * ((p - u) % MOD) % MOD * inv[u] % MOD;
            }
            if (u <= q - 1) {
                cq[u] = cq[u - 1] * ((q - u) % MOD) % MOD * inv[u] % MOD;
            }
        }

        long n0 = r + m;
        long nEnd = n0 - 2 * tmax;
        long low = nEnd + 1;
        long high = n0;
        int len = (int) (high - low + 1);

        long[] pref = new long[len + 1];
        pref[0] = 1;
        for (int i = 0; i < len; ++i) {
            pref[i + 1] = pref[i] * ((low + i) % MOD) % MOD;
        }

        long invTotal = modPow(pref[len], MOD - 2);
        long[] invRange = new long[len];
        for (int i = len - 1; i >= 0; --i) {
            long x = low + i;
            invRange[i] = pref[i] * invTotal % MOD;
            invTotal = invTotal * (x % MOD) % MOD;
        }

        long ans = 0;
        long combT = comb0;
        long nCur = n0;

        for (long t = 1; t <= tmax; ++t) {
            long nPrev = nCur;
            combT = combT * ((nPrev - m) % MOD) % MOD;
            combT = combT * ((nPrev - m - 1) % MOD) % MOD;
            combT = combT * invRange[(int) (nPrev - low)] % MOD;
            combT = combT * invRange[(int) (nPrev - 1 - low)] % MOD;
            nCur = nPrev - 2;

            long waysAb = 0;
            if ((t & 1) == 1) {
                int u = (int) (t / 2);
                waysAb = 2L * cp[u] % MOD * cq[u] % MOD;
            } else {
                int u = (int) (t / 2);
                waysAb = (cp[u] * cq[u - 1] + cp[u - 1] * cq[u]) % MOD;
            }

            ans = (ans + waysAb * combT) % MOD;
        }

        return ans;
    }

    public static String solve() {
        return Long.toString(wordsMod(1000000L, 10000000L, 100000000L));
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
