/*{{{*/
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <cassert>
using namespace std;
typedef pair<int, int> PP;
typedef long long LL;
#define pb push_back
#define fr first
#define sc second
#define bitcnt __builtin_popcount
#define all(x) x.begin(), x.end()
inline int ri() {int x; scanf("%d", &x); return x;}
#define rep2(i, n, ...) for (int i = 0; i < (n); i ++) 
#define rep3(i, a, b, ...) for (int i = (a); i < (b); i ++)
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define rep(...) GET_MACRO(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define drep2(i, n, ...) for (int i = (n) - 1; i >= 0; i --)
#define drep3(i, a, b) for (int i = (a) - 1; i >= (b); i --)
#define drep(...) GET_MACRO(__VA_ARGS__, drep3, drep2)(__VA_ARGS__)
template<typename T>inline bool smax(T&a, T b){if(a<b){a=b;return true;}return false;} 
template<typename T>inline bool smin(T&a, T b){if(a>b){a=b;return true;}return false;} 
/*}}}*/
//mod int
struct mint{
  const static long long mod = 1e9 + 7;
  long long x;
  mint():x(0){}       
  mint(long long x):x(((x%mod)+mod)%mod){};
  mint operator+=(const mint&a){if((x+=a.x)>=mod) x-=mod; return *this;}
  mint operator-=(const mint&a){if((x+=mod-a.x)>=mod) x-=mod; return *this;}
  mint operator*=(const mint&a){(x*=a.x)%=mod; return *this;}
  mint operator*(const mint&a){return mint(*this)*=a;}
  mint operator-(const mint&a){return mint(*this)-=a;}
  mint operator+(const mint&a){return mint(*this)+=a;}
  template<typename T>mint operator*(const T&a){return mint(*this)*=a;}
  template<typename T>mint operator-(const T&a){return mint(*this)-=a;}
  template<typename T>mint operator+(const T&a){return mint(*this)+=a;}
  template<typename T>friend mint operator*(T x,const mint&m){return mint(x)*=m;}
  template<typename T>friend mint operator-(T x,const mint&m){return mint(x)-=m;}
  template<typename T>friend mint operator+(T x,const mint&m){return mint(x)+=m;}
  bool operator==(const mint& a)const{ return x == a.x;}
  operator long long () const {return x;}
};
mint pw(mint a, long long b){mint res(1);while(b){if(b&1)res*=a;a*=a;b>>=1;}return res;}
mint inv(mint a){return pw(a, mint::mod - 2);}
//mod int

const int maxn = 5000000;
mint fac[maxn], inv_fac[maxn];

mint p[4010][2010];
mint C(int a, int b) {
  return fac[a] * inv_fac[b] * inv_fac[a - b];
}

int main() {
  #ifdef _TEST_
  freopen("input.txt", "r", stdin);
  //freopen("out.txt", "w", stdout);
  #endif
  fac[0] = inv_fac[0] = 1;
  rep(i, 1, maxn) fac[i] = fac[i - 1] * i, inv_fac[i] = inv(fac[i]);
  int n, m;
  cin >> n >> m;
  p[0][0] = 1;
  if (m == 1) {
    cout << 1 << endl;
    return 0;
  }
  rep(i, 2 * n) 
    rep(j, (i + 1) / 2, min(i, n) + 1) {
      int k = i - j;
      if (j > k) {
        p[i + 1][j] += p[i][j] * C(2 * n - i - 1 + (n - k) * (m - 2), m - 2);
      }
      p[i + 1][j + 1] += p[i][j];
    }
  cout << p[2 * n][n] * fac[n] << endl;
  return 0;
}


Measured memory_bytes: 141312