// eddy1021
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
#define mod9 1000000009LL
#define mod7 1000000007LL
#define INF  1023456789LL
#define INF16 10000000000000000LL
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else 
#define debug(...)
#endif
inline LL getint(){
  LL _x=0,_tmp=1; char _tc=getchar();    
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline LL add( LL _x , LL _y , LL _mod = mod7 ){
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline LL sub( LL _x , LL _y , LL _mod = mod7 ){
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline LL mul( LL _x , LL _y , LL _mod = mod7 ){
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
LL mypow( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 1LL;
  LL _ret = mypow( mul( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = mul( _ret , _a , _mod );
  return _ret;
}
LL mymul( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 0LL;
  LL _ret = mymul( add( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = add( _ret , _a , _mod );
  return _ret;
}
inline bool equal( D _x ,  D _y ){
  return _x > _y - eps && _x < _y + eps;
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/
#define N 5140
int fac[ N ] , ifac[ N ];
void build(){
  fac[ 0 ] = ifac[ 0 ] = 1;
  for( int i = 1 ; i < N ; i ++ ){
    fac[ i ] = mul( fac[ i - 1 ] , i );
    ifac[ i ] = mypow( fac[ i ] , mod7 - 2 , mod7 );
  }
}
inline int C( int a , int b ){
  if( a < b ) return 0;
  return mul( fac[ a ] , mul( ifac[ b ] , ifac[ a - b ] ) );
}
int A , B;
void init(){
  A = getint();
  B = getint();
}
int ppdp[ 2048 ][ 2048 ];
int ans , pdp[ 2048 ][ 2048 ];
inline int magic( int yy ){
  int ret = ppdp[ yy ][ yy ];
  if( yy )
    ret = sub( ret , ppdp[ yy ][ yy - 1 ] );
  return ret;
}
void solve(){
  for( int i = 0 ; i < B ; i ++ ){
    for( int j = 0 ; j <= i ; j ++ ){
      ppdp[ i ][ j ] = C( i , j );
      if( j )
        ppdp[ i ][ j ] = add( ppdp[ i ][ j ] ,
                              ppdp[ i ][ j - 1 ] );
    }
    for( int j = 1 ; j <= i ; j ++ )
      ppdp[ i ][ j ] = add( ppdp[ i ][ j ] ,
                            ppdp[ i ][ j - 1 ] );
  }
  for( int x = 0 ; x <= A ; x ++ ){
    pdp[ x ][ 0 ] = 1;
    for( int y = 1 ; y < B ; y ++ ){
      if( x <= y - 1 ){
        pdp[ x ][ y ] = ppdp[ y - 1 ][ x ];
        continue;
      }
      pdp[ x ][ y ] = ppdp[ y - 1 ][ y - 1 ];
      int mr = x - ( y - 1 );
      if( mr > 0 )
        pdp[ x ][ y ] = add( pdp[ x ][ y ] ,
                             mul( mr , magic( y - 1 ) ) );
      //for( int i = 0 ; i <= x ; i ++ ){
        //// (x - i)'R y'B
        //pdp[ x ][ y ] = add( pdp[ x ][ y ] ,
                             //ppdp[ y - 1 ][ min( x - i , y - 1 ) ] );
      //}
    }
  }
  for( int i = 0 ; i <= A ; i ++ ){
    // i * R
    // 1          t
    // (A - i)'R, B'B
    for( int j = 0 ; i + j <= A and j + 1 <= B ; j ++ ){
      int tans = C( B - 1 , j );
      // (A - i - j)' R, j'B
      ans = add( ans , mul( tans , pdp[ A - i - j ][ j ] ) );
    }
  }
  printf( "%d\n" , ans );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}


Measured memory_bytes: 33024