//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define st first
#define nd second

using namespace __gnu_pbds;
using namespace std;
 
template <typename T>
using ordered_set =
	tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
 
#define shandom_ruffle random_shuffle
 
using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;

const int kMaxA = 6000;
const int kMaxN = 1.2e7;
const int mod = 1e9 + 7;

int fact[kMaxN];
int inv_fact[kMaxN];

int PowMod(int a, int n) {
	int r = 1;
	while (n) {
		if (n & 1) { r = (ll)r * a % mod; }
		n >>= 1;
		a = (ll)a * a % mod;
	}
	return r;
}

void Preproc() {
	fact[0] = 1;
	for (int i = 1; i < kMaxN; ++i) {
		fact[i] = (ll)fact[i-1] * i % mod;
	}
	inv_fact[kMaxN - 1] = PowMod(fact[kMaxN - 1], mod - 2);
	for (int i = kMaxN - 2; i >= 0; --i) {
		inv_fact[i] = (ll)inv_fact[i + 1] * (i + 1) % mod;
	}
}

int Binom(int n, int k) {
	if (k < 0 || k > n) { return 0; }
	int ans = (ll)fact[n] * inv_fact[k] % mod;
	return (ll)ans * inv_fact[n-k] % mod;
}

int N, A;

int some_fill_ways[kMaxA];
//~ int all_fill_ways[kMaxA];
int dpx[kMaxA][kMaxA];

inline void Add(int &x, int y) {
	x += y;
	if (x >= mod) { x -= mod; }
}
inline void Sub(int &x, int y) {
	x -= y;
	if (x < 0) { x += mod; }
}
inline void Mul(int &x, int y) {
	x = (ll)x * y % mod;
}

void MakeWays() {
	const int L = N - A;
	for (int k = 1; k <= A; ++k) {
		some_fill_ways[k] = (ll)fact[k + L - 1] * inv_fact[k - 1] % mod;
	}

	for (int s = 0; s <= A; ++s) {
		for (int m = 0; m <= s; ++m) {
			if (m == 0) {
				dpx[s][m] = some_fill_ways[s];
			} else {
				dpx[s][m] = dpx[s][m - 1];
				Sub(dpx[s][m], dpx[s - 1][m - 1]);
			}

			debug() << imie(s) << imie(m) << imie(dpx[s][m]);
		}
	}
}

int dp[kMaxA][kMaxA];
int cyc[kMaxA][kMaxA];

void MakeDP() {
	for (int rem_left = 0; rem_left <= A; ++rem_left) {
		for (int k = A; k >= 0; --k) {
			int start_coef = dpx[A - rem_left][k];
			if (rem_left >= 1) {
				Mul(start_coef, fact[rem_left - 1]);
			}
			dp[rem_left][k] = start_coef;
			if (rem_left) {
				Add(dp[rem_left][k], dp[rem_left - 1][k + 1]);
				Add(dp[rem_left][k], cyc[rem_left - 1][k]);

				Add(cyc[rem_left][k], cyc[rem_left - 1][k]);
				Add(cyc[rem_left][k], dp[rem_left - 1][k]);
				Mul(cyc[rem_left][k], rem_left);
			}

			debug() << imie(rem_left) << imie(k) << imie(dp[rem_left][k]) <<
				imie(cyc[rem_left][k]);
		}
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(11);
	cerr << fixed << setprecision(6);

	Preproc();
	cin >> N >> A;

	MakeWays();
	MakeDP();
	cout << dp[A][0] << "\n";
}


Measured memory_bytes: 400480