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
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    final int mod = (int) 1e9 + 7;
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.readInt();
        int k = in.readInt();
        int[][] c = Combinatorics.GetCombinations(n, n, mod);
        int[][][][] dp = new int[n + 2][n + 2][2][2];
        dp[0][0][0][1] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j <= i; ++j) {
                for (int first = 0; first < 2; ++first) {
                    for (int second = 0; second < 2; ++second) {
                        if (first == 1) {
                            if (j > 0) {
                                dp[i][j][second][1] += dp[i - 1][j - 1][first][second];
                                dp[i][j][second][1] %= mod;
                            }
                        }
                        if (i < n && j > 0) {
                            dp[i][j][second][0] += dp[i - 1][j - 1][first][second];
                            dp[i][j][second][0] %= mod;
                        }
                        dp[i][j][second][1] += dp[i - 1][j][first][second];
                        dp[i][j][second][1] %= mod;
                    }
                }
            }
        }
        long[] fact = Combinatorics.GetFactorials(n, mod);
        long[] f = new long[n + 1];
        for (int i = 0; i <= n; ++i) {
            f[i] = 0;
            for (int first = 0; first < 2; ++first) {
                for (int second = 0; second < 2; ++second) {
                    f[i] += dp[n][i][first][second];
                    f[i] %= mod;
                }
            }
            f[i] *= fact[n - i];
            f[i] %= mod;
        }

        for (int i = n; i >= 0; --i) {
            for (int j = i + 1; j <= n; ++j) {
                f[i] -= (f[j] * c[j][i]) % mod;
                f[i] += mod;
                f[i] %= mod;
            }
        }
        out.println(f[k]);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        // InputMismatchException -> UnknownError
        if (numChars == -1)
            throw new UnknownError();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new UnknownError();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        } else if (c == '+') {
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public static boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    }

class Combinatorics {
    public static int[][] GetCombinations(int n, int m, int MOD) {
        int[][] c = new int[n + 1][m + 1];
        c[0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            c[i][0] = 1;
            for (int j = 1; j < i && j <= m; ++j) {
                c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
                if (c[i][j] >= MOD) {
                    c[i][j] -= MOD;
                }
            }
            c[i][i] = 1;
        }
        return c;
    }

    public static long[] GetFactorials(int n, int m) {
        long[] fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; ++i) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= m;
        }
        return fact;
    }
}

