#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <list>
#include <limits>
#include <set>
#include <map>
#include <functional>

//#include <inttypes.h>
#include <stdint.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

using namespace std;
typedef long long ll;

#define sc _g_sc
#define pt _g_pr
#define nl _g_pt_nl
#define FORi(i,b,e) for (int i = (b), _ = (e); i < _; ++i)
#define FORe(i,b,e) for (int i = (b), _ = (e); i <= _; ++i)
#define FORre(i,b,e) for (int i = (b), _ = (e); i >= _; --i)

static int sc_ret = 0;
struct pt_nl {} _g_pt_nl;
struct _s
{
	_s& operator>>(char& v) { sc_ret = scanf(" %c", &v); return *this; }
	_s& operator>>(int& v) { sc_ret = scanf("%d", &v); return *this; }
	_s& operator>>(unsigned& v) { sc_ret = scanf("%u", &v); return *this; }
	_s& operator>>(double& v) { sc_ret = scanf("%lf", &v); return *this; }
	_s& operator>>(char* v) { sc_ret = scanf("%s", v); return *this; }
	_s& operator>>(string& v) { sc_ret = (bool)(cin >> v); return *this; }
	_s& operator>>(ll& v) { sc_ret = read(v); return *this; }
	_s& ch(char& v) { v = sc_ret = getchar(); return *this; }
	_s& gets(char* v) { sc_ret = fgets(v, INT_MAX, stdin) != 0; v[strlen(v) - 1] = 0; return *this; }
	operator bool() const { return sc_ret > 0; }
	template <typename T>
	int read(T& v)
	{
		T k = 1; v = 0;
		int c = getchar();
		while (c < '0' || c > '9')
		{
			if (c == '-') k = 0;
			c = getchar();
		}
		while (c >= '0' && c <= '9') v = (v << 3) + (v << 1) + (c - 48), c = getchar();
		if (k == 0) v = -v;
		return c;
	}
}_g_sc;
struct _p
{
	_p& ln() { putchar('\n'); return *this; }
	_p& operator<<(const pt_nl& nl) { putchar('\n'); return *this; }
	_p& operator<<(char v) { putchar(v); return *this; }
	_p& operator<<(int v) { printf("%d", v); return *this; }
	_p& operator<<(unsigned v) { printf("%u", v); return *this; }
	_p& operator<<(double v) { printf("%.2f", v); return *this; }
	_p& operator()(const char* fmt, double v) { printf(fmt, v); return *this; }
	_p& operator<<(const char* v) { printf("%s", v); return *this; }
	_p& operator<<(string v) { printf("%s", v.c_str()); return *this; }
	_p& operator<<(ll v) { write(v); return *this; }
	void flush() { fflush(stdout); }
	template <typename T>
	void write(T v)
	{
		int cnt = 0; char c[23];
		if (v == 0) { putchar('0'); return; }
		if (v < 0) putchar('-'), v = -v;
		while (v) c[++cnt] = (v % 10) + 48, v /= 10;
		while (cnt > 0) putchar(c[cnt--]);
	}
	template <typename T>
	void ln(T* arr, int size, char split = ' ')
	{
		if (size > 0)
		{
			(*this) << arr[0];
			for (int i = 1; i < size; ++i)
				putchar(split), (*this) << arr[i];
		}
		putchar('\n');
	}
}_g_pr;

const int inf = 0x3f3f3f3f;
const int mod1e9 = 1000000007;
const int mod998 = 998244353;
const int mod = mod1e9;
const int maxn = 2000000 + 10;

ll dp[52][52][2600];

void solve()
{
	int n, k;
	sc >> n >> k;

	dp[0][0][0] = 1;
	FORe (i, 1, n)
	{
		FORi(x, 0, i) FORi(y, 0, n*n) if (dp[i - 1][x][y])
		{
			ll v = dp[i - 1][x][y];
			if (x) (dp[i][x - 1][y + 2 * x] += v*(x*x)) %= mod;
			(dp[i][x + 1][y + 2 * x] += v) %= mod;
			(dp[i][x][y + 2 * x] += v*(2 * x + 1)) %= mod;
		}
	}
	pt << dp[n][0][k] << nl;
}

int main(void)
{
	int t;
	//scanf("%d", &t);
	//while (t--)
	solve();
	return 0;
}


Measured memory_bytes: 51840