Permutation p is an ordered set of integers p1, p2, ..., pn, consisting of n distinct positive integers, each of them doesn't exceed n. We'll denote the i-th element of permutation p as pi. We'll call number n the size or the length of permutation p1, p2, ..., pn.

We'll call position i (1 ≤ i ≤ n) in permutation p1, p2, ..., pn good, if |p[i] - i| = 1. Count the number of permutations of size n with exactly k good positions. Print the answer modulo 1000000007 (109 + 7).

Input

The single line contains two space-separated integers n and k (1 ≤ n ≤ 1000, 0 ≤ k ≤ n).

Output

Print the number of permutations of length n with exactly k good positions modulo 1000000007 (109 + 7).

Examples

Input

1 0


Output

1


Input

2 1


Output

0


Input

3 2


Output

4


Input

4 1


Output

6


Input

7 4


Output

328

Note

The only permutation of size 1 has 0 good positions.

Permutation (1, 2) has 0 good positions, and permutation (2, 1) has 2 positions.

Permutations of size 3:

  1. (1, 2, 3) — 0 positions
  2. <image> — 2 positions
  3. <image> — 2 positions
  4. <image> — 2 positions
  5. <image> — 2 positions
  6. (3, 2, 1) — 0 positions
#include <bits/stdc++.h>
using namespace std;
int MODP(long long x) {
  int r = x % 1000000007;
  if (r < 0) r += 1000000007;
  return r;
}
template <class T>
class NumberTheory {
  static void extendedEuclid(T a, T b, T &x, T &y) {
    if (b == 0) {
      x = 1;
      y = 0;
      return;
    }
    T x2;
    extendedEuclid(b, a % b, x2, x);
    y = x2 - (a / b) * x;
  }

 public:
  static inline T modulo(long long a, T b) {
    T r = a % b;
    if (r < 0) r += b;
    return r;
  }
  static inline T modularInverse(T a, T m) {
    T x, y;
    extendedEuclid(a, m, x, y);
    return modulo(x, m);
  }
};
template <class T, T M>
class ModInt {
  T x = 0;
  static inline T get(ModInt x) { return x.get(); }
  static inline T get(T x) { return x; }

 public:
  ModInt() : ModInt(0) {}
  ModInt(long long y) { x = NumberTheory<T>::modulo(y, M); }
  T get() const { return x; }
  template <class Q>
  ModInt operator+(const Q &y) const {
    return ModInt(x + get(y));
  }
  template <class Q>
  ModInt &operator+=(const Q &y) {
    x = NumberTheory<T>::modulo(x + get(y), M);
    return *this;
  }
  template <class Q>
  ModInt operator-(const Q &y) const {
    return ModInt(x - get(y));
  }
  template <class Q>
  ModInt &operator-=(const Q &y) {
    x = NumberTheory<T>::modulo(x - get(y), M);
    return *this;
  }
  template <class Q>
  bool operator!=(const Q &y) const {
    return x != get(y);
  }
  template <class Q>
  ModInt operator*(const Q &y) const {
    return ModInt((long long)x * get(y));
  }
  template <class Q>
  ModInt &operator*=(const Q &y) {
    x = NumberTheory<T>::modulo((long long)x * get(y), M);
    return *this;
  }
  template <class Q>
  ModInt operator/(const Q &y) const {
    return ModInt((long long)x *
                  NumberTheory<T>::modularInverse(get(y), 1000000007));
  }
  template <class Q>
  ModInt &operator/=(const Q &y) {
    x = NumberTheory<T>::modulo(
        (long long)x * NumberTheory<T>::modularInverse(get(y), 1000000007), M);
    return *this;
  }
  ModInt &operator=(const T &y) {
    x = NumberTheory<T>::modulo(y, M);
    return *this;
  }
  ModInt &operator=(const ModInt &y) {
    x = y.x;
    return *this;
  }
  template <class Q>
  bool operator==(const Q &y) const {
    return x == get(y);
  }
  template <class Q>
  bool operator>(const Q &y) const {
    return x > get(y);
  }
  template <class Q>
  bool operator<(const Q &y) const {
    return x < get(y);
  }
  friend std::ostream &operator<<(std::ostream &stream, const ModInt &y) {
    stream << get(y);
    return stream;
  }
};
template <class T>
class ComboUtils {
  vector<T> factorial;
  int maxN;

 public:
  int getMaxN() const { return maxN; }
  ComboUtils(int n) {
    this->maxN = n;
    factorial.resize(n + 1);
    factorial[0] = 1;
    for (auto i = 1; i <= n; ++i) {
      factorial[i] = factorial[i - 1] * i;
    }
  }
  T C(int n, int k) const {
    assert(0 <= n && n <= maxN);
    if (k < 0 || k > n) return 0;
    return factorial[n] / factorial[k] / factorial[n - k];
  }
  T A(int n, int k) const {
    assert(0 <= n && n <= maxN);
    if (k < 0 || k > n) return 0;
    return factorial[n] / factorial[n - k];
  }
  T P(int n) const {
    assert(0 <= n && n <= maxN);
    return factorial[n];
  }
  T repeatC(int n, int k) const { return C(n + k - 1, k); }
  static vector<T> getCombByK(int n, int k) {
    vector<T> c(n + 1);
    c[k] = 1;
    for (auto i = k + 1; i <= n; ++i) {
      c[i] = c[i - 1] * i / (i - k);
    }
    return c;
  }
  static vector<T> getCombByN(int n) {
    vector<T> c(n + 1);
    c[0] = 1;
    for (auto i = 1; i <= n; ++i) {
      c[i] = c[i - 1] * (n - i + 1) / i;
    }
    return c;
  }
  static vector<T> getPower(int n, T a) {
    vector<T> p(n + 1);
    p[0] = 1;
    for (auto i = 1; i <= n; ++i) {
      p[i] = p[i - 1] * a;
    }
    return p;
  }
};
template <class T>
class Polynomial {
  vector<T> deg;
  int n;

 public:
  Polynomial(int n) {
    deg.resize(n + 1);
    this->n = n;
  }
  Polynomial(const vector<T> &deg) : deg(deg) { this->n = (int)deg.size() - 1; }
  void multiply(T a) {
    for (auto i = 0; i <= n; ++i) {
      deg[i] *= a;
    }
  }
  T getCoef(int k) const {
    assert(0 <= k && k <= n);
    return deg[k];
  }
  void add(const Polynomial<T> &p) {
    int newDeg = max(n, p.n);
    deg.resize(newDeg + 1);
    this->n = newDeg;
    for (auto i = 0; i <= n; ++i) {
      deg[i] += p.deg[i];
    }
  }
  void printDebug() const {
    ostringstream s;
    for (auto i = n; i >= 0; --i) {
      if (deg[i] == 1 && i > 0) {
        if (i < n) s << " + ";
      } else if (deg[i] == -1 && i > 0) {
        s << " - ";
      } else {
        if (i < n && deg[i] > 0) {
          s << " + ";
        }
        s << deg[i];
      }
      if (i >= 2) {
        s << "x^" << i;
      } else if (i == 1) {
        s << "x";
      }
    }
    if (1 <= 0) cout << s.str() << endl;
  }
  static Polynomial<T> simplePower(T a, T b, int n,
                                   const ComboUtils<T> &comboUtils) {
    assert(a != 0);
    assert(comboUtils.getMaxN() >= n);
    vector<T> aPower(n + 1);
    vector<T> bPower(n + 1);
    aPower[0] = 1;
    bPower[0] = 1;
    for (auto i = 1; i <= n; ++i) {
      aPower[i] = aPower[i - 1] * a;
      bPower[i] = bPower[i - 1] * b;
    }
    Polynomial<T> p(n);
    for (auto i = 0; i <= n; ++i) {
      p.deg[i] = bPower[n - i] * aPower[i] * comboUtils.C(n, i);
    }
    return p;
  }
  static Polynomial<T> getHitPolynomial(int n, const Polynomial<T> &rook,
                                        const ComboUtils<T> &comboUtils) {
    assert(comboUtils.getMaxN() >= n);
    Polynomial<T> hit(0);
    for (auto k = 0; k <= n; ++k) {
      auto p = Polynomial<T>::simplePower(1, -1, k, comboUtils);
      p.multiply(rook.getCoef(k) * comboUtils.P(n - k));
      hit.add(p);
    }
    return hit;
  }
};
void testGen() {
  freopen("biginput1.txt", "w", stdout);
  fclose(stdout);
}
int solveSlow(int n) {
  vector<int> a(n + 1);
  for (auto i = 1; i <= n; ++i) a[i] = i;
  int ret = 0;
  do {
    bool good = true;
    for (auto i = 1; i <= n; ++i)
      if (a[i] == i - 1 || a[i] == i + 1) {
        good = false;
        break;
      }
    if (good) ret++;
  } while (next_permutation(a.begin() + 1, a.end()));
  return ret;
}
int main() {
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  vector<vector<ModInt<int, 1000000007>>> f(n + 1);
  for (auto i = 0; i <= n; ++i) f[i].resize(n + 1);
  vector<vector<ModInt<int, 1000000007>>> g(n + 1);
  for (auto i = 0; i <= n; ++i) g[i].resize(n + 1);
  f[0][0] = 1;
  for (auto i = 1; i <= n; ++i) {
    f[i][0] = 1;
    g[i][0] = 1;
    for (auto k = 1; k <= i; ++k) {
      f[i][k] = 0;
      g[i][k] = 0;
      if (i >= 1) {
        f[i][k] += f[i - 1][k];
      }
      if (k >= 2) {
        f[i][k] += f[i - 2][k - 2];
      }
      if (k >= 1) {
        f[i][k] += g[i - 1][k - 1] * 2;
      }
      if (i >= 1) {
        g[i][k] += f[i - 1][k];
        if (k >= 1) {
          g[i][k] += g[i - 1][k - 1];
        }
      }
    }
  }
  Polynomial<ModInt<int, 1000000007>> rook(f[n]);
  ComboUtils<ModInt<int, 1000000007>> comboUtils(n);
  auto hit = Polynomial<ModInt<int, 1000000007>>::getHitPolynomial(n, rook,
                                                                   comboUtils);
  cout << hit.getCoef(k);
  return 0;
}
