import sys

input = sys.stdin.readline

sys.setrecursionlimit(10**7)

import numpy as np



N,K = list(map(int,input().split()))



# ある線を、左にまたぐ数の集合、右にまたぐ数の集合など



MOD = 10 ** 9 + 7



dp = np.zeros((N+1,N*N+1), dtype = np.int64) # ある線をまたぐ（左右）個数、これまでの合計点、場合の数

dp[0,0] = 1

for n in range(1,N+1):

    prev = dp

    dp = np.zeros_like(prev)

    for m in range(N):

        dp[m,m:] += prev[m,:N*N+1-m] # その点を不動点にしてそのまま

        dp[m,m:] += prev[m,:N*N+1-m] * m # どれかをそこに留めてのこりを右に

        dp[m+1,m+1:] += (m+1) * prev[m,:N*N-m] # その点ごと全部右に。左に流す方をどれか残す

        dp[m,m:] += prev[m,:N*N+1-m] * m # xを左に、左から来たのは全て右に

        dp[m,m:] += (m+1) * prev[m+1,:N*N+1-m] # その点ごと全部右に。左に流す方をどれか残す

    dp %= MOD



if K&1:

    answer = 0

else:

    answer = dp[0,K//2]



print(answer)
import sys

read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



import numpy as np



MOD = 10**9 + 7



N,K = list(map(int,read().split()))



# 左からの流入量、コスト

L = N*(N-1)//2+1

dp = np.zeros((N,L),dtype=np.int64)

dp[0,0] = 1



for _ in range(1,N+1):

    prev = dp

    dp = np.zeros_like(prev)

    for n in range(N):

        # 自身を不動点にしてそのまま左右に流す

        dp[n,n:] += prev[n,:L-n]

        # 左からのものを採用、自身は左に流す

        if n > 0: dp[n-1,n-1:] += prev[n,:L-n+1] * n

        # 左からのものを採用、自身は右に流す

        dp[n,n:] += prev[n,:L-n] * n

        # 右からのものを採用、自身は左に流す

        dp[n,n:] += prev[n,:L-n] * n

        # 右からのものを採用、自身は右に流す

        if n+1 < N: dp[n+1,n+1:] += prev[n,:L-n-1] * (n+1)

    dp %= MOD



x = dp[0]

if K&1:

    answer = 0

elif K//2 < L:

    answer = x[K//2]

else:

    answer = 0

print(answer)
import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)
import numpy as np

N, K = list(map(int, input().split()))
# ある線を、左にまたぐ数の集合、右にまたぐ数の集合など
MOD = 10**9 + 7
dp = np.zeros((N + 1, N * N + 1), dtype=np.int64)  # ある線をまたぐ（左右）個数、これまでの合計点、場合の数
dp[0, 0] = 1
for n in range(1, N + 1):
    prev = dp
    dp = np.zeros_like(prev)
    for m in range(N):
        dp[m, m:] += prev[m, : N * N + 1 - m]  # その点を不動点にしてそのまま
        dp[m, m:] += prev[m, : N * N + 1 - m] * m  # どれかをそこに留めてのこりを右に
        dp[m + 1, m + 1 :] += (m + 1) * prev[m, : N * N - m]  # その点ごと全部右に。左に流す方をどれか残す
        dp[m, m:] += prev[m, : N * N + 1 - m] * m  # xを左に、左から来たのは全て右に
        dp[m, m:] += (m + 1) * prev[m + 1, : N * N + 1 - m]  # その点ごと全部右に。左に流す方をどれか残す
    dp %= MOD
if K & 1:
    answer = 0
else:
    answer = dp[0, K // 2]
print(answer)

import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import numpy as np

MOD = 10**9 + 7
N, K = list(map(int, read().split()))
# 左からの流入量、コスト
L = N * (N - 1) // 2 + 1
dp = np.zeros((N, L), dtype=np.int64)
dp[0, 0] = 1
for _ in range(1, N + 1):
    prev = dp
    dp = np.zeros_like(prev)
    for n in range(N):
        # 自身を不動点にしてそのまま左右に流す
        dp[n, n:] += prev[n, : L - n]
        # 左からのものを採用、自身は左に流す
        if n > 0:
            dp[n - 1, n - 1 :] += prev[n, : L - n + 1] * n
        # 左からのものを採用、自身は右に流す
        dp[n, n:] += prev[n, : L - n] * n
        # 右からのものを採用、自身は左に流す
        dp[n, n:] += prev[n, : L - n] * n
        # 右からのものを採用、自身は右に流す
        if n + 1 < N:
            dp[n + 1, n + 1 :] += prev[n, : L - n - 1] * (n + 1)
    dp %= MOD
x = dp[0]
if K & 1:
    answer = 0
elif K // 2 < L:
    answer = x[K // 2]
else:
    answer = 0
print(answer)

-input = sys.stdin.readline -sys.setrecursionlimit(10**7) +read = sys.stdin.buffer.read +readline = sys.stdin.buffer.readline +readlines = sys.stdin.buffer.readlines -N, K = list(map(int, input().split())) -# ある線を、左にまたぐ数の集合、右にまたぐ数の集合など -dp = np.zeros((N + 1, N * N + 1), dtype=np.int64)  # ある線をまたぐ（左右）個数、これまでの合計点、場合の数 +N, K = list(map(int, read().split())) +# 左からの流入量、コスト +L = N * (N - 1) // 2 + 1 +dp = np.zeros((N, L), dtype=np.int64) -for n in range(1, N + 1): +for _ in range(1, N + 1): -    for m in range(N): -        dp[m, m:] += prev[m, : N * N + 1 - m]  # その点を不動点にしてそのまま -        dp[m, m:] += prev[m, : N * N + 1 - m] * m  # どれかをそこに留めてのこりを右に -        dp[m + 1, m + 1 :] += (m + 1) * prev[m, : N * N - m]  # その点ごと全部右に。左に流す方をどれか残す -        dp[m, m:] += prev[m, : N * N + 1 - m] * m  # xを左に、左から来たのは全て右に -        dp[m, m:] += (m + 1) * prev[m + 1, : N * N + 1 - m]  # その点ごと全部右に。左に流す方をどれか残す +    for n in range(N): +        # 自身を不動点にしてそのまま左右に流す +        dp[n, n:] += prev[n, : L - n] +        # 左からのものを採用、自身は左に流す +        if n > 0: +            dp[n - 1, n - 1 :] += prev[n, : L - n + 1] * n +        # 左からのものを採用、自身は右に流す +        dp[n, n:] += prev[n, : L - n] * n +        # 右からのものを採用、自身は左に流す +        dp[n, n:] += prev[n, : L - n] * n +        # 右からのものを採用、自身は右に流す +        if n + 1 < N: +            dp[n + 1, n + 1 :] += prev[n, : L - n - 1] * (n + 1) +x = dp[0] +elif K // 2 < L: +    answer = x[K // 2] -    answer = dp[0, K // 2] +    answer = 0