#define DEB
    #include<bits/stdc++.h>
    #define REP(i,m) for(int i=0;i<(m);++i)
    #define REPN(i,m,in) for(int i=(in);i<(m);++i)
    #define ALL(t) (t).begin(),(t).end()
    #define CLR(a) memset((a),0,sizeof(a))
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
     
    using namespace std;
     
     
    #ifdef DEB
    #define dump(x)  cerr << #x << " = " << (x) << endl
    #define prl cerr<<"called:"<< __LINE__<<endl
    template<class T> void debug(T a,T b){ for(;a!=b;++a) cerr<<*a<<' ';cerr<<endl;}
    #else
    #define dump(x) ;
    #define prl ;
    template<class T> void debug(T a,T b){ ;}
    #endif
     
    template<class T> void chmin(T& a,const T& b) { if(a>b) a=b; }
    template<class T> void chmax(T& a,const T& b) { if(a<b) a=b; }
     
    typedef long long int lint;
    typedef pair<int,int> pi;
     
    namespace std{
      template<class S,class T>
      ostream &operator <<(ostream& out,const pair<S,T>& a){
        out<<'('<<a.fr<<','<<a.sc<<')';
        return out;
      }
    }
     
     
    template<lint mod>
    struct Int_{
      unsigned x;
      unsigned mpow(Int_ a,unsigned k){
        Int_ res=1;
        while(k){
          if(k&1) res=res*a;
          a=a*a;
          k>>=1;
        }
        return res.x;
      }
      unsigned inverse(Int_ a){
        return mpow(a,mod-2);
      }
      Int_(): x(0) { }
      Int_(long long sig) {
        int sigt=sig%mod;
        if(sigt<0) sigt+=mod;
        x=sigt;
      }
      unsigned get() const { return (unsigned)x; }
      
      Int_ &operator+=(Int_ that) { if((x += that.x) >= mod) x -= mod; return *this; }
      Int_ &operator-=(Int_ that) { if((x += mod - that.x) >= mod) x -= mod; return *this; }
      Int_ &operator*=(Int_ that) { x = (unsigned long long)x * that.x % mod; return *this; }
      Int_ &operator=(Int_ that) { x=that.x; return *this;}
      Int_ &operator/=(Int_ that) { x=(unsigned long long) x * inverse(that.x)%mod; return *this;}
      bool operator==(Int_ that) const { return x==that.x; }
      bool operator!=(Int_ that) const { return x!=that.x; }
     
      Int_ operator-() const { return Int_(0)-Int_(*this);}
      Int_ operator+(Int_ that) const { return Int_(*this) += that; }
      Int_ operator-(Int_ that) const { return Int_(*this) -= that; }
      Int_ operator*(Int_ that) const { return Int_(*this) *= that; }
      Int_ operator/(Int_ that) const { return Int_(*this) /= that; }
     
    };
     
    namespace std{
      template<lint mod>
      ostream &operator <<(ostream& out,const Int_<mod>& a){
        out<<a.get();
        return out;
      }
      template<lint mod>
      istream &operator >>(istream& in,Int_<mod>& a){
        in>>a.x;
        return in;
      }
    };
     
    typedef Int_<924844033> Int;
    //const int INF=5e8;
    int n,K;
     
    set<pi> done;
    int getsize(int x,int y){
      if(x>=n || y>=n) return 0;
      done.insert(mp(x,y));
      if(x<y) return getsize(y+K,y)+1;
      return getsize(x,x+K)+1;
    }
     
    Int dp2[2005][2005];
    int cur=0,nxt=1;
    Int dp[2][2005];
     
    void doit(int size){
      CLR(dp[nxt]);
      REP(i,n) REP(j,size+1){
        dp[nxt][i+j]+=dp[cur][i]*dp2[size][j];
      }
      swap(cur,nxt);
    }
     
    Int fact[2005];
    int main(){
      cin>>n>>K;
      fact[0]=1;
      REP(i,n) fact[i+1]=fact[i]*(i+1);
     
      REP(i,n) REP(j,n){
        if(j==0) dp2[i][j]=1;
        else{
          if(i==1 && j==1) dp2[i][j]=1;
          else dp2[i][j]=(i>0?dp2[i-1][j]:0)+(i>1?dp2[i-2][j-1]:0);
        }
      }
     
      dp[cur][0]=1;
      REP(i,n) REP(j,n) if(abs(i-j)==K && !done.count(mp(i,j))){
        int v=getsize(i,j);
     
        doit(v);
      }
     
      Int res=0;
     
      REP(i,n+1){
        if(i&1) res-=dp[cur][i]*fact[n-i];
        else res+=dp[cur][i]*fact[n-i];
      }
      cout<<res<<endl;
      return 0;
    }
     
     
     

Measured memory_bytes: 16256