Problem: Vasily the bear has two favorite integers n and k and a pencil. Besides, he's got k jars with different water color paints. All jars are numbered in some manner from 1 to k, inclusive. The jar number i contains the paint of the i-th color. 

Initially the bear took a pencil and drew four segments on the coordinate plane. All of them end at point (0, 0). They begin at: (0, 2n), (0, - 2n), (2n, 0), ( - 2n, 0). Then for each i = 1, 2, ..., n, the bear drew two squares. The first square has the following vertex coordinates: (2i, 0), ( - 2i, 0), (0, - 2i), (0, 2i). The second square has the following vertex coordinates: ( - 2i - 1, - 2i - 1), ( - 2i - 1, 2i - 1), (2i - 1, - 2i - 1), (2i - 1, 2i - 1). After that, the bear drew another square: (1, 0), ( - 1, 0), (0, - 1), (0, 1). All points mentioned above form the set of points A.

<image>

The sample of the final picture at n = 0

<image>

The sample of the final picture at n = 2

The bear decided to paint the resulting picture in k moves. The i-th move consists of the following stages: 

  1. The bear chooses 3 distinct points in set А so that any pair of the chosen points has a segment on the picture between them. The chosen points and segments mark the area that mustn't contain any previously painted points. 
  2. The bear paints the area bounded by the chosen points and segments the i-th color. 



Note that after the k-th move some parts of the picture can stay unpainted.

The bear asked you to calculate, how many distinct ways there are to paint his picture. A way to paint the picture is a sequence of three-element sets of points he chose on each step. Two sequences are considered distinct if there is such number i (1 ≤ i ≤ k), that the i-th members of these sequences do not coincide as sets. As the sought number can be rather large, you only need to calculate the remainder after dividing it by number 1000000007 (109 + 7).

Input

The first line contains two integers n and k, separated by a space (0 ≤ n, k ≤ 200).

Output

Print exactly one integer — the answer to the problem modulo 1000000007 (109 + 7).

Examples

Input

0 0


Output

1


Input

0 1


Output

8


Input

0 2


Output

32


Input

1 1


Output

32

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
int dp[201][201][2][2][2][2];
int t[5][2][2][2][2];
int Comb[4][4];
void Dod(int& a, int x, int kr) {
  a = (a + (long long)kr * x % MOD);
  if (a > MOD) a -= MOD;
}
bool daj(int mask, int nr) { return ((mask & (1 << nr)) > 0); }
int C(int n, int k) {
  if (k == 4) return 1;
  n = min(n, 3);
  return Comb[n][k];
}
int main() {
  ios_base::sync_with_stdio(0);
  int n, k;
  cin >> n >> k;
  t[0][0][0][0][0] = 1;
  t[1][1][0][0][0] = t[1][0][1][0][0] = t[1][0][0][1][0] = t[1][0][0][0][1] = 1;
  t[1][1][1][0][0] = t[1][0][1][1][0] = t[1][0][0][1][1] = t[1][1][0][0][1] = 1;
  t[2][1][1][1][1] = 2;
  t[2][1][1][1][0] = t[2][0][1][1][1] = t[2][1][0][1][1] = t[2][1][1][0][1] = 2;
  t[2][1][1][0][0] = t[2][1][0][1][0] = t[2][1][0][0][1] = 1;
  t[2][0][1][1][0] = t[2][0][1][0][1] = 1;
  t[2][0][0][1][1] = 1;
  t[3][1][1][1][1] = 4;
  t[3][1][1][1][0] = t[3][1][1][0][1] = t[3][1][0][1][1] = t[3][0][1][1][1] = 1;
  t[4][1][1][1][1] = 1;
  for (int il = 0; il <= 4; ++il) {
    for (int mask = 0; mask < (1 << 4); ++mask) {
      int a = daj(mask, 0), b = daj(mask, 1), c = daj(mask, 2),
          d = daj(mask, 3);
      for (int e = 0; e <= (a == 1); ++e)
        for (int f = 0; f <= (b == 1); ++f)
          for (int g = 0; g <= (c == 1); ++g)
            for (int h = 0; h <= (d == 1); ++h)
              Dod(dp[0][il][a][b][c][d], t[il][e][f][g][h], 1);
    }
  }
  int i[] = {0, 1, 2, 3, 1};
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j <= i; ++j) {
      if (i == j || j == 0)
        Comb[i][j] = 1;
      else
        Comb[i][j] = Comb[i - 1][j] + Comb[i - 1][j - 1];
    }
  }
  for (int war = 1; war <= n; ++war) {
    for (int il = 0; il <= k; ++il) {
      for (int mask = 0; mask < 16; ++mask) {
        int a = daj(mask, 0), b = daj(mask, 1), c = daj(mask, 2),
            d = daj(mask, 3);
        if (mask == 15) {
          if (il == 2) Dod(dp[war][il][a][b][c][d], 2, 1);
          for (int g = 0; g <= 4; ++g)
            for (int h = 0; h <= 4; ++h)
              if (il - 1 - i[g] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[g] - i[h]][0][0][g != 4][h != 4],
                    C(3, g) * C(3, h));
          for (int g = 0; g <= 2; ++g)
            for (int h = 0; h <= 2; ++h)
              if (il - 2 - i[g] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 2 - i[g] - i[h]][0][0][1][1],
                    C(2, g) * C(2, h));
          for (int e = 0; e <= 4; ++e)
            for (int h = 0; h <= 4; ++h)
              if (il - 1 - i[e] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[e] - i[h]][e != 4][0][0][h != 4],
                    C(3, e) * C(3, h));
          for (int e = 0; e <= 2; ++e)
            for (int h = 0; h <= 2; ++h)
              if (il - 2 - i[e] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 2 - i[e] - i[h]][1][0][0][1],
                    C(2, e) * C(2, h));
          for (int e = 0; e <= (a == 1) * 4; ++e)
            for (int f = 0; f <= (b == 1) * 4; ++f)
              if (il - 1 - i[e] - i[f] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[e] - i[f]][e != 4][f != 4][0][0],
                    C(3, e) * C(3, f));
          for (int e = 0; e <= 2; ++e)
            for (int f = 0; f <= 2; ++f)
              if (il - 2 - i[e] - i[f] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 2 - i[e] - i[f]][1][1][0][0],
                    C(2, e) * C(2, f));
          for (int f = 0; f <= 4; ++f)
            for (int g = 0; g <= 4; ++g)
              if (il - 1 - i[f] - i[g] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[f] - i[g]][0][f != 4][g != 4][0],
                    C(3, f) * C(3, g));
          for (int f = 0; f <= 2; ++f)
            for (int g = 0; g <= 2; ++g)
              if (il - 2 - i[f] - i[g] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 2 - i[f] - i[g]][0][1][1][0],
                    C(2, f) * C(2, g));
          for (int mask2 = 0; mask2 < 16; ++mask2) {
            bool x = daj(mask2, 0), y = daj(mask2, 1), z = daj(mask2, 2),
                 w = daj(mask2, 3);
            int ogrE = 4 - (x || y) - x - y;
            int ogrF = 4 - (y || z) - y - z;
            int ogrG = 4 - (z || w) - z - w;
            int ogrH = 4 - (w || x) - w - x;
            for (int e = 0; e <= ogrE; ++e) {
              for (int f = 0; f <= ogrF; ++f) {
                for (int g = 0; g <= ogrG; ++g) {
                  for (int h = 0; h <= ogrH; ++h) {
                    int il2 = il - i[e] - i[f] - i[g] - i[h] -
                              __builtin_popcount(mask2);
                    if (il2 >= 0)
                      Dod(dp[war][il][a][b][c][d],
                          dp[war - 1][il2][e != 4][f != 4][g != 4][h != 4],
                          C(ogrE, e) * C(ogrF, f) * C(ogrG, g) * C(ogrH, h));
                  }
                }
              }
            }
          }
          continue;
        }
        if (mask == 2 || mask == 4 || mask == 8) {
          dp[war][il][a][b][c][d] = dp[war][il][1][0][0][0];
          continue;
        }
        if (mask == 6 || mask == 12 || mask == 9) {
          dp[war][il][a][b][c][d] = dp[war][il][1][1][0][0];
          continue;
        }
        if (mask == 14 || mask == 13 || mask == 11) {
          dp[war][il][a][b][c][d] = dp[war][il][1][1][1][0];
          continue;
        }
        if (mask == 10) {
          dp[war][il][a][b][c][d] = dp[war][il][1][0][1][0];
          continue;
        }
        if (a == 1 && b == 1) {
          for (int g = 0; g <= (c == 1) * 4; ++g)
            for (int h = 0; h <= (d == 1) * 4; ++h)
              if (il - 1 - i[g] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[g] - i[h]][0][0][c == 1 && g != 4]
                      [d == 1 && h != 4],
                    C(3, g) * C(3, h));
          if (c == 1 && d == 1) {
            for (int g = 0; g <= 2; ++g)
              for (int h = 0; h <= 2; ++h)
                if (il - 2 - i[g] - i[h] >= 0)
                  Dod(dp[war][il][a][b][c][d],
                      dp[war - 1][il - 2 - i[g] - i[h]][0][0][1][1],
                      C(2, g) * C(2, h));
          }
        }
        if (b == 1 && c == 1) {
          for (int e = 0; e <= (a == 1) * 4; ++e)
            for (int h = 0; h <= (d == 1) * 4; ++h)
              if (il - 1 - i[e] - i[h] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[e] - i[h]][a == 1 && e != 4][0][0]
                      [d == 1 && h != 4],
                    C(3, e) * C(3, h));
          if (a == 1 && d == 1) {
            for (int e = 0; e <= 2; ++e)
              for (int h = 0; h <= 2; ++h)
                if (il - 2 - i[e] - i[h] >= 0)
                  Dod(dp[war][il][a][b][c][d],
                      dp[war - 1][il - 2 - i[e] - i[h]][1][0][0][1],
                      C(2, e) * C(2, h));
          }
        }
        if (c == 1 && d == 1) {
          for (int e = 0; e <= (a == 1) * 4; ++e)
            for (int f = 0; f <= (b == 1) * 4; ++f)
              if (il - 1 - i[e] - i[f] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[e] - i[f]][a == 1 && e != 4]
                      [b == 1 && f != 4][0][0],
                    C(3, e) * C(3, f));
          if (a == 1 && b == 1) {
            for (int e = 0; e <= 2; ++e)
              for (int f = 0; f <= 2; ++f)
                if (il - 2 - i[e] - i[f] >= 0)
                  Dod(dp[war][il][a][b][c][d],
                      dp[war - 1][il - 2 - i[e] - i[f]][1][1][0][0],
                      C(2, e) * C(2, f));
          }
        }
        if (a == 1 && d == 1) {
          for (int f = 0; f <= (b == 1) * 4; ++f)
            for (int g = 0; g <= (c == 1) * 4; ++g)
              if (il - 1 - i[f] - i[g] >= 0)
                Dod(dp[war][il][a][b][c][d],
                    dp[war - 1][il - 1 - i[f] - i[g]][0][b == 1 && f != 4]
                      [c == 1 && g != 4][0],
                    C(3, f) * C(3, g));
          if (b == 1 && c == 1) {
            for (int f = 0; f <= 2; ++f)
              for (int g = 0; g <= 2; ++g)
                if (il - 2 - i[f] - i[g] >= 0)
                  Dod(dp[war][il][a][b][c][d],
                      dp[war - 1][il - 2 - i[f] - i[g]][0][1][1][0],
                      C(2, f) * C(2, g));
          }
        }
        for (int mask2 = 0; mask2 < 16; ++mask2) {
          bool x = daj(mask2, 0), y = daj(mask2, 1), z = daj(mask2, 2),
               w = daj(mask2, 3);
          if ((a == 0 && (x || y)) || (b == 0 && (y || z)) ||
              (c == 0 && (z || w)) || (d == 0 && (w || x)))
            continue;
          int ogrE = (a == 1) * (4 - (x || y) - x - y);
          int ogrF = (b == 1) * (4 - (y || z) - y - z);
          int ogrG = (c == 1) * (4 - (z || w) - z - w);
          int ogrH = (d == 1) * (4 - (w || x) - w - x);
          for (int e = 0; e <= ogrE; ++e) {
            for (int f = 0; f <= ogrF; ++f) {
              for (int g = 0; g <= ogrG; ++g) {
                for (int h = 0; h <= ogrH; ++h) {
                  int il2 = il - i[e] - i[f] - i[g] - i[h] -
                            __builtin_popcount(mask2);
                  if (il2 >= 0)
                    Dod(dp[war][il][a][b][c][d],
                        dp[war - 1][il2][a == 1 && e != 4][b == 1 && f != 4]
                          [c == 1 && g != 4][d == 1 && h != 4],
                        C(ogrE, e) * C(ogrF, f) * C(ogrG, g) * C(ogrH, h));
                }
              }
            }
          }
        }
      }
    }
  }
  long long odp = dp[n][k][1][1][1][1];
  for (long long i = 1; i <= k; ++i) odp = (odp * i) % MOD;
  cout << odp;
  return 0;
}