Problem:
Score : 900 points

Problem Statement

Snuke loves permutations. He is making a permutation of length N.

Since he hates the integer K, his permutation will satisfy the following:

Let the permutation be a_1, a_2, ..., a_N. For each i = 1,2,...,N, |a_i - i| \neq K.

Among the N! permutations of length N, how many satisfies this condition?

Since the answer may be extremely large, find the answer modulo 924844033(prime).

Constraints

2 ≦ N ≦ 2000

1 ≦ K ≦ N-1

Input

The input is given from Standard Input in the following format:

N K

Output

Print the answer modulo 924844033.

Sample Input 1

3 1

Sample Output 1

2

2 permutations (1, 2, 3), (3, 2, 1) satisfy the condition.

Sample Input 2

4 1

Sample Output 2

5

5 permutations (1, 2, 3, 4), (1, 4, 3, 2), (3, 2, 1, 4), (3, 4, 1, 2), (4, 2, 3, 1) satisfy the condition.

Sample Input 3

4 2

Sample Output 3

9

Sample Input 4

4 3

Sample Output 4

14

Sample Input 5

425 48

Sample Output 5

756765083

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int mod=924844033;
ll g[2005][2005][4],f[4005],t[4005],F[2005];
int n,K,m;
ll quick_pow(ll a,ll b){
	ll ans=1;
	for(;b;b>>=1,a=a*a%mod)
		if(b&1) ans=ans*a%mod;
	return ans;
}
ll add(ll a,ll b){
	return a+b>=mod?a+b-mod:a+b;
}
ll dft(ll *a,int sig){
	for(int i=0;i<m;i++){
		int p=0,g=m>>1,j=i;
		while(g) p=p<<1|(j&1),j>>=1,g>>=1;
		if(p<i) swap(a[p],a[i]);
	}
	ll w,wn;
	for(int b=2;b<=m;b<<=1){
		int half=b>>1;
		wn=quick_pow(5,sig==1?(mod-1)/b:mod-1-(mod-1)/b);
		for(int i=0;i<m;i+=b){
			w=1;
			for(int j=0;j<half;j++){
				ll u=a[i+j],v=a[i+j+half]*w%mod;
				a[i+j]=add(u,v);
				a[i+j+half]=add(u,mod-v);
				w=w*wn%mod;
			}
		}
	}
	ll inv=quick_pow(m,mod-2);
	if(sig==-1) for(int i=0;i<m;i++) a[i]=a[i]*inv%mod;
}
int main(){
	scanf("%d%d",&n,&K);
	g[0][0][1]=1;
	for(int i=1;i<=n;i++){
		for(int p=0;p<=i;p++){
			for(int j=0;j<4;j++){
				if(j&2){
					if(p) g[i][p][j]=add(g[i-1][p-1][(j&1)<<1|1],g[i-1][p-1][(j&1)<<1]);
				}else{
					g[i][p][j]=add(g[i-1][p][(j&1)<<1|1],g[i-1][p][(j&1)<<1]);
					if(p) g[i][p][j]=add(g[i][p][j],g[i-1][p-1][(j&1)<<1]);
				}
			}
		}
	}
	f[0]=1;
	m=1;
	while(m<=n) m<<=1;
	dft(f,1);
	for(int i=1;i<=K&&i<=n;i++){
		memset(t,0,sizeof(t));
		int tot=0;
		for(int p=i;p<=n;p+=K) tot++;
		t[0]=1;
		for(int p=i,pos=1;p<=n;p+=K,pos++){
			for(int j=0;j<2;j++) t[pos]=add(t[pos],g[tot][pos][j]);
		}
		dft(t,1);
		for(int p=0;p<m;p++) f[p]=f[p]*t[p]%mod;
	}
	dft(f,-1);
	ll ans=0;
	F[0]=1;
	for(int i=1;i<=n;i++) F[i]=F[i-1]*i%mod;
	for(int p=0,op=1;p<=n;p++,op=-op){
		ans=(ans+f[p]*F[n-p]*op)%mod;
	}
	printf("%lld",(ans+mod)%mod);
	return 0;
}