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

/*
　　　　　／＞　 フ
　　　　　| 　^　 ^|
　 　　　／`ミ _x 彡
　　 　 /　　　 　 |
　　　 /　  ヽ　　 ?
　／￣|　　 |　|　|
　| (￣ヽ＿_ヽ_)_)
　＼二つ
 */

#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

template<typename F>
inline void write(F x, char ed = '\n') {
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }

template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }

const int P = 1e9+7;
const int N = 4008;
int A, B, C[N][N];
int g[N][N], f[N][N]; 
int add(int x) { return x >= P ? x - P : x; }
int main() {
	read(A), read(B); int lim = max(A, B);
	C[0][0] = 1;
	for (int i = 1;i <= lim; C[i++][0] = 1)
		for (int j = 1;j <= i; j++)
			C[i][j] = add(C[i-1][j] + C[i-1][j-1]);
	for (int i = 0;i <= lim; i++) {
		g[i][0] = C[i][0];
		for (int j = 1;j <= lim; j++)
			g[i][j] = add(C[i][j] + g[i][j-1]);
	}
	for (int i = 0;i <= lim; i++) {
		f[i][0] = g[i][0];
		for (int j = 1;j <= lim; j++)
			f[i][j] = add(g[i][j] + f[i][j-1]);
	}
	ll ans = A + 1;
	for (int i = 1;i <= A + 1; i++) 
		for (int j = 1;j < i; j++) 
			ans = (ans + (ll)C[B-1][j] * f[j-1][i-j-1]) % P;
	write(ans);
	return 0;
}