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)

// includes {{{
#include <algorithm>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <tuple>
#include <vector>
// #include<deque>
// #include<multiset>
// #include<bitset>
// #include<cstring>
// #include<bits/stdc++.h>
// }}}
using namespace std;
using ll = long long;

const int N = 2000;
ll n, k;
const int mod = 924844033;

// WARN : use H with larger N
/// --- Modulo Factorial {{{ ///
template < int N, int mod = (int) 1e9 + 7 >
struct Factorial {
  constexpr ll extgcd(ll a, ll b, ll &x, ll &y) {
    ll d = 0;
    return b == 0 ? (x = 1, y = 0, a) : (d = extgcd(b, a % b, y, x), y -= a / b * x, d);
  }
  constexpr ll modinv(ll a) {
    ll x = 0, y = 0;
    extgcd(a, mod, x, y);
    return (x + mod) % mod;
  }
  int arr[N + 1], inv[N + 1];
  ll operator[](int i) const { return arr[i]; }
#if !defined(DEBUG)
  constexpr
#endif
      Factorial()
      : arr(), inv() {
    arr[0] = 1;
    for(int i = 1; i <= N; i++) {
      arr[i] = (ll) i * arr[i - 1] % mod;
    }
    inv[N] = modinv(arr[N]);
    for(int i = N - 1; i >= 0; i--) {
      inv[i] = (ll)(i + 1) * inv[i + 1] % mod;
    }
  }
  ll C(int n, int r) const {
    if(n < 0 || r < 0 || n < r) return 0;
    return (ll) arr[n] * inv[r] % mod * inv[n - r] % mod;
  }
  ll H(int n, int r) const { return C(n + r - 1, r); }
};
/// }}}--- ///

Factorial< N, mod > fact;

ll dp[N + 1][N + 1][2]; // [i-thまでで][j個選んだ][i-thは前向きに選んだ?]

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> n >> k;
  ll ans = 0;
  vector< int > num(n + 1);
  for(int i = 0, now = 0; i < n;
      i++, now += 2 * k, now = now >= n ? now % (2 * k) + 1 : now)
    num[i + 1] = now + 1;
  dp[0][0][0] = 1;
  for(int i = 1; i <= n; i++) for(int j = 0; j <= n; j++) {
    // 何も選ばない
    for(int t = 0; t < 2; t++) dp[i][j][0] += dp[i - 1][j][t];
    if(j >= 1) {
      if(num[i] - 2 * k >= 1) { // 前回が存在する
        // 後ろ向きに選ぶ
        if(num[i] - k >= 1) {
          dp[i][j][0] += dp[i - 1][j - 1][0];
        }
      } else {
        // 後ろ向きに選ぶ
        if(num[i] - k >= 1) {
          for(int t = 0; t < 2; t++) dp[i][j][0] += dp[i - 1][j - 1][t];
        }
      }
      // 前向きに選ぶ
      if(num[i] + k <= n) {
        for(int t = 0; t < 2; t++) dp[i][j][1] += dp[i - 1][j - 1][t];
      }
    }
    dp[i][j][0] %= mod, dp[i][j][1] %= mod;
  }
  for(int i = 0; i <= n; i++) {
    ans += (dp[n][i][0] + dp[n][i][1]) * fact[n - i] % mod * (i % 2 ? -1 : 1);
  }
  ans %= mod;
  if(ans < 0) ans += mod;
  cout << ans << endl;
  return 0;
}