Greg has a pad. The pad's screen is an n × m rectangle, each cell can be either black or white. We'll consider the pad rows to be numbered with integers from 1 to n from top to bottom. Similarly, the pad's columns are numbered with integers from 1 to m from left to right.

Greg thinks that the pad's screen displays a cave if the following conditions hold:

  * There is a segment [l, r] (1 ≤ l ≤ r ≤ n), such that each of the rows l, l + 1, ..., r has exactly two black cells and all other rows have only white cells. 
  * There is a row number t (l ≤ t ≤ r), such that for all pairs of rows with numbers i and j (l ≤ i ≤ j ≤ t) the set of columns between the black cells in row i (with the columns where is these black cells) is the subset of the set of columns between the black cells in row j (with the columns where is these black cells). Similarly, for all pairs of rows with numbers i and j (t ≤ i ≤ j ≤ r) the set of columns between the black cells in row j (with the columns where is these black cells) is the subset of the set of columns between the black cells in row i (with the columns where is these black cells). 



Greg wondered, how many ways there are to paint a cave on his pad. Two ways can be considered distinct if there is a cell that has distinct colors on the two pictures.

Help Greg.

Input

The first line contains two integers n, m — the pad's screen size (1 ≤ n, m ≤ 2000).

Output

In the single line print the remainder after dividing the answer to the problem by 1000000007 (109 + 7).

Examples

Input

1 1


Output

0


Input

4 4


Output

485


Input

3 5


Output

451
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fLL;
const long long MD = 1000000007;
long long inc[2050][2050];
long long sum[2050][2050];
int n, m;
long long inc_big[2050][2050][2];
long long cur_sum[2050], cur_sum1[2050];
int make_inc(int n, int m) {
  for (int i = (2); i < (m + 1); ++i) {
    inc[1][i] = 1LL;
    sum[1][i] = sum[1][i - 1] + inc[1][i];
  }
  for (int x = (2); x < (n + 1); ++x) {
    for (int y = (2); y < (m + 1); ++y) {
      inc[x][y] = (inc[x][y - 1] + sum[x - 1][y - 1] + inc[x - 1][y - 1]) % MD;
      if ((sum[x][y] = sum[x][y - 1] + inc[x][y]) >= MD) sum[x][y] -= MD;
    }
  }
  return 0;
}
int make_big(int n, int m) {
  for (int i = (0); i < (n + 1); ++i)
    for (int j = (0); j < (m + 1); ++j) sum[i][j] = 0;
  for (int y = (2); y < (m + 1); ++y) {
    inc_big[1][y][0] = 1LL;
    inc_big[1][y][1] = 0LL;
    sum[1][y] = (sum[1][y - 1] + inc_big[1][y][0] + inc_big[1][y][1]) % MD;
  }
  for (int x = (2); x < (n + 1); ++x) {
    for (int y = (2); y < (m + 1); ++y) {
      if ((inc_big[x][y][1] = inc_big[x - 1][y][1] + inc_big[x - 1][y][0]) >=
          MD)
        inc_big[x][y][1] -= MD;
      inc_big[x][y][0] = (inc_big[x][y - 1][0] + sum[x - 1][y - 1] +
                          inc_big[x - 1][y - 1][0] + inc_big[x - 1][y - 1][1]) %
                         MD;
      sum[x][y] = (sum[x][y - 1] + inc_big[x][y][0] + inc_big[x][y][1]) % MD;
    }
  }
  return 0;
}
long long make_shift(const int &m) {
  long long ans = 0LL;
  for (int i = (0); i < (n + 1); ++i) cur_sum[i] = cur_sum1[i] = 0LL;
  for (int i = 1; i <= n; ++i) {
    cur_sum[i] = (cur_sum[i - 1] + inc_big[i][m][0]) % MD;
    cur_sum1[i] = (cur_sum1[i - 1] + inc_big[i][m][1] + inc_big[i][m][0]) % MD;
  }
  for (int i = 1; i <= n; ++i) ans += (cur_sum[i] * cur_sum1[n - i + 1]) % MD;
  return ans % MD;
}
int main() {
  scanf("%d%d", &n, &m);
  make_inc(n, m);
  make_big(n, m);
  long long res = 0LL;
  for (int i = (2); i < (m + 1); ++i) res += (m - i + 1) * make_shift(i) % MD;
  printf(
      "%lld"
      "\n",
      res % MD);
  return 0;
}
