#include <bits/stdc++.h>
#define len(v) ((int)((v).size()))
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define chmax(x, v) x = max((x), (v))
#define chmin(x, v) x = min((x), (v))
using namespace std;
using ll = long long;

template<const int MOD>
struct ModInt
{
	//int x;
	long long x;
	ModInt() : x(0) { }
	ModInt(long long u) : x(u) { if (x >= MOD || x < 0) { x %= MOD; if (x < 0) x += MOD; } } 
	//ModInt(long long u) : x(u) { }
	ModInt(const ModInt &m) : x(m.x) { }
	ModInt& operator=(const ModInt &m) { x = m.x; return *this; }
	friend bool operator==(const ModInt& a, const ModInt& b) { return a.x == b.x; }
	friend bool operator!=(const ModInt& a, const ModInt& b) { return a.x != b.x; }
	friend bool operator<(const ModInt& a, const ModInt& b) { return a.x < b.x; }

	ModInt& operator+=(const ModInt& m) { x += m.x; if (x >= MOD) x -= MOD; return *this; }
	ModInt& operator-=(const ModInt& m) { x -= m.x; if (x < 0) x += MOD; return *this; }
	ModInt& operator*=(const ModInt& m) { x = (1ll*x*m.x)%MOD; return *this; }	

	friend ModInt operator-(const ModInt &a) { ModInt res(a); if (res.x) res.x = MOD-res.x; return res; }
	friend ModInt operator+(const ModInt& a, const ModInt &b) { return ModInt(a) += ModInt(b); }
	friend ModInt operator-(const ModInt& a, const ModInt &b) { return ModInt(a) -= ModInt(b); }
	friend ModInt operator*(const ModInt& a, const ModInt &b) { return ModInt(a) *= ModInt(b); }
	ModInt f2() { return ModInt(x) += ModInt(x); }

	static long long fp(long long u, long long k) {
		long long res = 1;
		while (k > 0) {
			if (k & 1)
				res = (res*u) % MOD;
			u = (u*u) % MOD;
			k /= 2;
		}
		return res;
	}
	ModInt fastpow(long long k) { return ModInt(fp(x, k)); }
	ModInt inv() { return ModInt(fp(x, MOD-2)); }
	static ModInt sign(long long k) { return ((k & 1) ? ModInt(MOD-1) : ModInt(1)); }
	friend ostream& operator << (ostream& out, const ModInt& a) { return out << a.x; }
};

template<int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
	static_assert(D >= 1, "Vector dimension must be greater than zero!");
	template<typename... Args>
	Vec(int n, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {}
};
template<typename T>
struct Vec<1, T> : public vector<T> {
	Vec(int n, const T& val = T()) : vector<T>(n, val) {}
};

const int MOD = 924844033;
using Num = ModInt<MOD>;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int nbElem, denyDist;
	cin >> nbElem >> denyDist;
	vector<Num> fact(nbElem+1);
	for (int i = 0; i <= nbElem; ++i) {
		fact[i] = (i ? fact[i-1]*Num(i) : 1);
	}
	int totEdges = 0;
	vector<bool> spec(2*nbElem + 5, false);
	for (int dep = 0; dep < denyDist; ++dep) {
		int nbEdges = (nbElem-1-dep) / denyDist;
		totEdges += 2*nbEdges;
		spec[totEdges-nbEdges] = spec[totEdges] = true;
	}
	Vec<2, Num> cur(nbElem+2, 2, 0);
	cur[0][0] = 1;
	for (int pos = 0; pos < totEdges; ++pos) {
		Vec<2, Num> nxt(nbElem+2, 2, 0);
		int ifTake = (spec[pos+1] ? 0 : 1);
		for (int taken = 0; taken <= min(pos, nbElem); ++taken) {
			nxt[taken][0] += (cur[taken][0] + cur[taken][1]);
			nxt[taken+1][ifTake] += cur[taken][0];
		}
		cur = nxt;
	}
	Num res = 0;
	for (int nbDeny = 0; nbDeny <= nbElem; ++nbDeny) {
		res += Num::sign(nbDeny) * cur[nbDeny][0] * fact[nbElem-nbDeny];	
	}
	cout << res << "\n";
}


Measured memory_bytes: 3844