Problem: A + B balls are arranged in a row. The leftmost A balls are colored red, and the rightmost B balls are colored blue.

You perform the following operation:

* First, you choose two integers s, t such that 1 \leq s, t \leq A + B.
* Then, you repeat the following step A + B times: In each step, you remove the first ball or the s-th ball (if it exists) or the t-th ball (if it exists, all indices are 1-based) from left in the row, and give it to Snuke.



In how many ways can you give the balls to Snuke? Compute the answer modulo 10^9 + 7.

Here, we consider two ways to be different if for some k, the k-th ball given to Snuke has different colors. In particular, the choice of s, t doesn't matter. Also, we don't distinguish two balls of the same color.

Constraints

* 1 \leq A, B \leq 2000

Input

Input is given from Standard Input in the following format:


A B


Output

Print the answer.

Examples

Input

3 3


Output

20


Input

4 4


Output

67


Input

7 9


Output

7772


Input

1987 1789


Output

456315553

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

namespace math {
    const int MOD = 1000 * 1000 * 1000 + 7;
    //const int N = (int)1.01e6;
    const int N = 2100;

    int fct[N], ofct[N];
    char ispr[N];
    vector<int> pr;

    void add(int &a, int b) {
        a = (a + b) % MOD;
    }

    int getC(int n, int k) {
        if (k < 0 || n < k || n < 0) return 0;
        return 1LL * fct[n] * ofct[k] % MOD * ofct[n - k] % MOD;
    }

    int bin(int a, int n) {
        int res = 1;
        while (n) {
            if (n & 1) res = 1LL * res * a % MOD;
            a = 1LL * a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    int inv(int x) {
        return bin(x, MOD - 2);
    }

    // slower, but works for non-prime modulo m
    int rev(int x, int m) {
        if (x == 1) return 1;
        return (1 - rev(m % x, x) * (ll)m) / x + m;
    }

    void init() {
        fct[0] = 1;
        for (int i = 1; i < N; i++) fct[i] = 1LL * fct[i - 1] * i % MOD;
        ofct[N - 1] = inv(fct[N - 1]);
        for (int i = N - 2; i >= 0; i--) ofct[i] = 1LL * ofct[i + 1] * (i + 1) % MOD;

        memset(ispr, 1, sizeof(ispr));
        for (int i = 2; i < N; i++) {
            if (!ispr[i]) continue;
            pr.push_back(i);
            for (int j = i + i; j < N; j += i) ispr[j] = 0;
        }
    }

    bool isPrime(int x) {
        if (x < N) return ispr[x];
        for (int i = 0; i < (int)pr.size() && 1LL * pr[i] * pr[i] <= x; i++) {
            if (x % pr[i] == 0) {
                return 0;
            }
        }
        return 1;
    }
}

using namespace math;

int c[N][N], s[N][N], s2[N][N];

int main() {
    math::init();
#ifdef HOME
    freopen("in", "r", stdin);
#endif
    c[0][0] = 1;
    for (int i = 0; i < N - 1; i++) {
        for (int j = 0; j <= i; j++) {
            add(c[i + 1][j], c[i][j]);
            add(c[i + 1][j + 1], c[i][j]);
        }
    }
    for (int i = 0; i < N; i++) {
        s[i][0] = c[i][0];
        for (int j = 1; j < N; j++) {
            s[i][j] = (s[i][j - 1] + c[i][j]) % MOD;
        }
    }
    for (int i = 0; i < N; i++) {
        s2[i][0] = s[i][0];
        for (int j = 1; j < N; j++) {
            s2[i][j] = (s2[i][j - 1] + s[i][j]) % MOD;
        }
    }

    int A, B;
    while (cin >> A >> B) {
        int ans = 0;
        for (int firstL = 0; firstL <= A; firstL++) {
            for (int firstR = 1; firstR <= B; firstR++) {
                int leftA = A - (B - firstR) - firstL;
                int leftB = B - firstR;
                if (leftA >= 0) {
                    int cways = getC(B - 1, firstR - 1);
                    /*if (leftA >= leftB) {
                        cways = 1LL * cways * bin(2, leftB) % MOD;
                    } else {
                        cways = 1LL * cways * getC(leftB, leftA) % MOD;
                    }*/
                    // C[leftB][0] + C[leftB][1] + ... + C[leftB][leftA] = C(

                    if (leftB == 0) {
                        add(ans, 1);
                        continue;
                    }

                    /*for (int secondL = 0; secondL <= leftA; secondL++) {
                        int nleftA = leftA - secondL;
                        int cways2 = s[leftB - 1][nleftA];
                        add(ans, 1LL * cways * cways2 % MOD);
                    }*/
                    add(ans, 1LL * cways * s2[leftB - 1][leftA] % MOD);
                    //int cways2 = s[leftB][leftA];
                    //cways = 1LL * cways * cways2 % MOD;
                    //add(ans, cways);
                }
            }
        }
        cout << ans << endl;
    }

#ifdef HOME
    cerr << clock() / (double)CLOCKS_PER_SEC << endl;
#endif
    return 0;
}