#include <bits/stdc++.h>
using namespace std;
const int mo = 1000000007;
int n, K, tot;
int dp[2][201][16];
int tr[55][55][201];
int head[55], C[55][55];
int ok[55], way[55][5];
struct edge {
  int to, k, v, next;
} e[5005];
void add(int x, int y, int k, int v) {
  e[++tot] = (edge){y, k, v, head[x]};
  head[x] = tot;
}
int cnt(int x) {
  int ans = 0;
  for (; x; x /= 2)
    if (x & 1) ans++;
  return ans;
}
int main() {
  scanf("%d%d", &n, &K);
  for (int i = (int)(0); i <= (int)(22); i++) {
    C[i][0] = 1;
    for (int j = (int)(1); j <= (int)(i); j++)
      C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
  }
  int lim = 15;
  ok[0] = 4;
  ok[1] = ok[2] = ok[4] = ok[8] = 2;
  ok[3] = ok[6] = ok[9] = ok[12] = 1;
  way[0][0] = 1;
  way[1][1] = way[2][1] = way[3][1] = way[4][1] = 1;
  way[6][1] = way[8][1] = way[9][1] = way[12][1] = 1;
  way[3][2] = way[5][2] = way[6][2] = way[9][2] = way[10][2] = way[12][2] = 1;
  way[7][2] = way[11][2] = way[13][2] = way[14][2] = way[15][2] = 2;
  way[7][3] = way[11][3] = way[13][3] = way[14][3] = 1;
  way[15][3] = 4;
  way[15][4] = 1;
  for (int i = (int)(0); i <= (int)(15); i++)
    for (int j = (int)(0); j <= (int)(15); j++)
      if (!(i & j)) {
        int k = i | j;
        for (int p = (int)(0); p <= (int)(ok[k]); p++) {
          int tmp = (4 - cnt(k)) * 3 - p * 2;
          for (int q = (int)(0); q <= (int)(tmp); q++)
            for (int cnt = (int)(0); cnt <= (int)(4); cnt++)
              if (way[j][cnt])
                (((tr[i][k][cnt + p + q]) +=
                  (1ll * C[ok[k]][p] * C[tmp][q] * way[j][cnt] % mo)) >= mo
                     ? tr[i][k][cnt + p + q] -= mo
                     : 233);
        }
      }
  for (int i = (int)(0); i <= (int)(15); i++)
    for (int k = (int)(12); k >= (int)(0); k--)
      for (int j = (int)(0); j <= (int)(15); j++)
        if (tr[i][j][k]) add(i, j, k, tr[i][j][k]);
  dp[(n + 1) & 1][0][0] = 1;
  for (int i = (int)(n + 1); i >= (int)(2); i--) {
    int p = i & 1, q = p ^ 1;
    memset(dp[q], 0, sizeof(dp[q]));
    ;
    for (int k = (int)(0); k <= (int)(K); k++)
      for (int msk = (int)(0); msk <= (int)(15); msk++)
        if (dp[p][k][msk])
          for (int x = head[msk]; x; x = e[x].next) {
            int kk = k + e[x].k;
            if (kk > K) break;
            (((dp[q][kk][e[x].to]) += (1ll * dp[p][k][msk] * e[x].v % mo)) >= mo
                 ? dp[q][kk][e[x].to] -= mo
                 : 233);
          }
  }
  for (int i = (int)(15); i >= (int)(0); i--)
    for (int j = (int)(i + 1); j <= (int)(lim); j++)
      if ((i & j) == i)
        for (int k = (int)(0); k <= (int)(4); k++)
          (((way[j][k]) += (way[i][k])) >= mo ? way[j][k] -= mo : 233);
  int ans = 0;
  for (int k = (int)(max(K - 4, 0)); k <= (int)(K); k++)
    for (int msk = (int)(0); msk <= (int)(15); msk++)
      (((ans) += (1ll * dp[1][k][msk] * way[15 - msk][K - k] % mo)) >= mo
           ? ans -= mo
           : 233);
  for (int i = 1; i <= K; i++) ans = 1ll * ans * i % mo;
  printf("%d", ans);
}
