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:
/*#### bits/stdc++.h */
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<iostream>
#include<string>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<deque>
#include<queue>
#include<utility>
#include<algorithm>
using namespace std;
/*####*/

/*#### modular_arithmetic */
class modular_arithmetic{
public:
	int mod, range;

	modular_arithmetic(){
		mod = 1000000007;
	}
	//No specific settings.
	void set_mod(int _mod){mod = _mod;}
	int add(int x,int y){return (x+y)%mod;}
	int sub(int x,int y){return (x-y+mod)%mod;}
	int mul(int x,int y){return (int)((long long int)x*y%mod);}
};
/*####*/
modular_arithmetic ma;

#define R 4005
int c[R][R],csum[R][R];
int c_sum(int x,int from, int to){
	if(from < 0)from = 0;
	if(to > x)to = x;
	if(from > to)return 0;
	return ma.sub(csum[x][to], from==0?0:csum[x][from-1]);
}
int calc(int red,int blue,int pos){
	int all = c[red+blue][red];
	int eat = red + blue - pos;
	int good = c_sum(eat, max(0, eat-blue), min(min(eat, blue),red));
	return ma.sub(all, good);
}
int mem[R][R];
int calc2(int red,int blue){
	int&res = mem[red][blue];
	if(res !=-1)return res;
	res = 0;
	if(red >= 1)
		res = ma.add(calc2(red-1,blue), calc(red, blue-1, red));
	return res;
}
int main(){
	memset(mem,-1,sizeof(mem));
	for(int i=0; i<R; i++)for(int j=0; j<=i; j++){
		c[i][j] = j==0||j==i?1:ma.add(c[i-1][j], c[i-1][j-1]);
		csum[i][j] = ma.add(c[i][j], j==0?0:csum[i][j-1]);
	}
	int A,B;
	scanf("%d%d",&A,&B);
	int res = 0;
	for(int i=0; i<A; i++){
		int red = A - i, blue = B - 1, pos = red;
		int eat = red + blue - pos;
		for(int j=0; j<=eat; j++){
			int red2 = j, blue2 = eat-j;
			if(red2 > red || blue2 < 0 || blue2 > blue)continue;
			int lef_red = red - red2, lef_blue = blue - blue2;
			if(lef_red <= 0 || lef_blue <= 0)continue;
			res = ma.add(res, ma.mul(c[eat][red2], calc2(lef_red, lef_blue)));
		}
	}
	printf("%d\n",ma.sub(c[A+B][A], res));
	return 0;
}