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
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < int(n); ++i)
#define REPE(i, a, b) for (int i = (a); i <= int(b); ++i)
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(), x.end()
#define PB push_back
#define EB emplace_back
using LL = long long;
using PII = pair<int, int>;
#define F first
#define S second
const LL mod = 1000000007;

const int maxn = 5050;
LL pow_mod(LL a, LL p, const LL m) {
  LL ret = 1;
  for (; p; p >>= 1, a = a * a % m)
    if (p & 1)
      ret = ret * a % m;
  return ret % m;
}
LL inv(LL a, LL n) {
  return a < 2 ? a : ((1 - n * 1LL * inv(n % a, a)) / a % n + n) % n;
}
LL frac[maxn], ifrac[maxn];
LL C(int a, int b) {
  return (frac[a] * ifrac[b] % mod) * ifrac[a - b] % mod;
}

int inv_t[maxn];
void inv_table(int n, int mod) {
  inv_t[1] = 1;
  for (int i = 2; i < n; ++i)
    inv_t[i] = (mod - 1LL * (mod / i) * inv_t[mod % i] % mod) % mod;
}
int n, m;

LL g(int sz, int y) {
  LL r = frac[sz - 1] * ifrac[y - 1] % mod;
  r = r * ifrac[sz - y] % mod;
  return r;
}

LL f(int x, int y) {
  if (m + m - x > n + x + y) return 0;
  LL a = g(m, x);
  LL b = g(m - x, y);
  int s = n - (m + m - x - x - y);
  LL r = frac[s + 2] * ifrac[s] % mod;
  r = r * ifrac[2] % mod;
  r = r * (a * b % mod) % mod;
  return r;
}

LL ff(int x) {
  if (m > n + x) return 0;
  LL a = g(m, x);
  int s = n - (m - x);
  LL r = frac[s + 1] * ifrac[s] % mod;
  r = r * a % mod;
  return r;
}

int main() {
  inv_table(maxn, mod);
  frac[0] = 1;
  ifrac[0] = 1;
  for (int i = 1; i < maxn; ++i) {
    frac[i] = frac[i-1] * i % mod;
    ifrac[i] = ifrac[i-1] * inv_t[i] % mod;
  }
  scanf("%d%d", &n, &m);
  LL ans = ff(m);
  for (int i = 1; i <= m; ++i) {
    for (int j = 1; i + j <= m; ++j) {
      ans += f(i, j);
      ans %= mod;
    }
  }
  printf("%lld\n", ans);
  return 0;
}

