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>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VI vector<int>
#define VL vector<long long>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define VPLL vector<pair<long long,long long> >
#define F first
#define S second
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;
const int SIZE = 4001;
void ADD(LL& x,LL v){
    x=(x+v)%MOD;
}
LL dp0[SIZE][SIZE];
LL CC[SIZE][SIZE];
LL C(int x,int y){
    if(x<y||y<0)return 0;
    if(!y)return 1;
    LL res=CC[x][y]-CC[x][y-1];
    if(res<0)res+=MOD;
    return res;
}
void build(){
    REP(i,SIZE){
        CC[i][0]=1;
        REPP(j,1,i+1){
            CC[i][j]=CC[i-1][j-1];
            ADD(CC[i][j],CC[i-1][j]);
        }
    }
    REPP(i,1,SIZE){
        REPP(j,1,SIZE){
            ADD(CC[i][j],CC[i][j-1]);
        }
    }
    REPP(A,1,2001){
        dp0[A][0]=dp0[0][A]=1;
        REPP(B,1,2001){
            dp0[A][B]=CC[B-1][min(B-1,A)];
        }
    }
    REPP(A,1,2001)REPP(B,1,2001){
        ADD(dp0[A][B],dp0[A-1][B]);
    }
}
int main(){
    LL an=1;
    build();
    DRII(A,B);
    REPP(AA,1,A+1){
        REPP(BB,0,min(B-1,AA)+1){
            //printf("[%d,%d]=%lld,%lld\n",AA,BB,C(B-1,BB),dp0[AA-BB][BB]);
            ADD(an,C(B-1,BB)*dp0[AA-BB][BB]);
        }
    }
    cout<<an<<endl;
    return 0;
}