#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2000+10,mod=1e9+7;
ll f[maxn][maxn];
ll s[maxn*maxn+10],invs[maxn*maxn+10];
int n,m;
inline void read(int &x){
	char c=getchar();
	int f=1;
	x=0;
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
	x*=f;
}
inline long long ksm(ll x,int y){
	ll sum=1;
	while(y){
		if(y&1){sum=(sum*x)%mod;}
		y/=2;
		x=(x*x)%mod;
	}
	return sum%mod;
}
inline ll cal(int x,int y){
	//cout<<s[x]<<" "<<s[y]<<endl;
	ll sum2=1,sum1=1,sum=0;
	//for(register int i=1;i<=y;i++)sum1=(sum1*i)%mod;
	//for(register int i=x-y+1;i<=x;i++)sum2=(sum2*i)%mod;
	//sum2=s[x];sum1=(s[x-y]*s[y])%mod;
	//sum=(sum2*ksm(sum1,mod-2))%mod;
	sum=((s[x]*invs[y])%mod*invs[x-y])%mod;
	//cout<<sum<<endl;
	return sum%mod;
}
int main(){
	int i,j,k;
	read(n);read(m);
	//cout<<n<<" "<<m<<endl;
	if(m==1){cout<<1<<endl;return 0;}
	f[0][0]=1;
	s[0]=1;
	//for(register int i=1;i<=n;i++)f[i][0]=1;
	for(register int i=1;i<=maxn*maxn;i++){s[i]=(s[i-1]*i)%mod;}
	invs[maxn*maxn]=ksm(s[maxn*maxn],mod-2);
	for(register int i=maxn*maxn-1;i>=0;i--)invs[i]=(invs[i+1]*(i+1))%mod;
	for(register int i=1;i<=n;i++)
		for(register int j=0;j<=i;j++){
			if(!j)f[i][j]=f[i-1][j]%mod;
			else f[i][j]=(f[i-1][j]+((f[i][j-1]*(n-j+1))%mod*cal(n*m-(j-1)*(m-1)-i-1,m-2)))%mod;
		}
	cout<<f[n][n]<<endl;
	return 0;
}
#pragma GCC optimize("Ofast,fast-math,unroll-loops")
 
#include <bits/stdc++.h>
 
#define int ll
//#define double long double
#define endl '\n'
#define all(C) (C).begin(), (C).end()
#define rall(C) (C).rbegin(), (C).rend()
#define mp make_pair 
#define pb emplace_back
#define dbg(x) cerr << #x << " : " << x << endl
//#define PI 3.141592653589
 
using namespace std;
        
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair <int, int>;
using pld = pair <ld, ld>;
        
/* 
const ll MAX_MEM = 25e7;
char MEM[MAX_MEM];
ll MEM_POS = 0;
void* operator new(size_t x)
{
    auto ret = MEM + MEM_POS;
    MEM_POS += x;
    assert(MEM_POS < MAX_MEM);
    return ret;
}
void operator delete(void*)
{}
*/
        
template <class T>
istream& operator>> (istream &in, vector <T> &a)
{
    for (auto &i : a)
        in >> i;
    return in;
}
        
template <class T> 
ostream& operator<< (ostream &out, vector <T> a)
{
    for (auto &i : a)
        out << i << ' ';
    return out;
}
        
template <class T, class U>
istream& operator>> (istream &in, pair <T, U> &p)
{
    in >> p.first >> p.second;
    return in;
}
        
template <class T, class U>
ostream& operator<< (ostream &out, pair <T, U> p)
{
    out << p.first << " " << p.second << " ";
    return out;
}
        
inline void Start()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    //freopen("lol.in", "r", stdin);
    //freopen("lol.out", "w", stdout);
}

const int P = 1e9 + 7;
int add(int a, int b)
{
    return a + b >= P ? a + b - P : a + b;
}
int mul(int a, int b)
{
    return a * b % P;
}
int bpow(int a, int n)
{
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = mul(res, a);
        a = mul(a, a);
        n >>= 1;
    }
    return res;
}
int rev(int x)
{
    return bpow(x, P - 2);
}
int sub(int a, int b)
{
    return add(a, P - b);
}
int divi(int a, int b)
{
    return mul(a, rev(b));
}
struct combinations
{
    vector <int> fact, revfact;
    combinations() {}
    combinations(int n)
    {
        fact.assign(n, 1);
        revfact.assign(n, 1);
        for (int i = 1; i < n; ++i)
            fact[i] = mul(fact[i - 1], i), revfact[i] = divi(revfact[i - 1], i);
    }
    int operator() (int n, int k)
    {
        return mul(fact[n], mul(revfact[k], revfact[n - k]));
    }
};

signed main()
{
    Start();
    int n, k;
    cin >> n >> k;
    combinations c(2001 * 2001);
    if (k == 1)
        return cout << 1, 0;
    vector <vector <int>> dp(n + 1, vector <int> (n + 1));
    dp[0][0] = 1;
    for (int i = 0; i <= n; ++i)
    {
        for (int j = (i ? 0 : 1); j <= n; ++j)
        {
            if (j < i)
                continue;
            if (i)
                dp[i][j] = add(dp[i][j], dp[i - 1][j]);
            if (j)
                dp[i][j] = add(dp[i][j], mul(dp[i][j - 1], c(i + j * (k - 1) - 1, k - 2)));

        }
    }
    cout << mul(dp[n][n], c.fact[n]);
    return 0;
}
 
