#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define REP(i, n) for(int i = 0; i < (int)(n); ++i)
#define FOR(i, m, n) for(int i = (int)(m); i < (int)(n); ++i)

const int MOD = 1e+9 + 7;

// 箱根駅伝 dp ? {1, 2, ...} と順列を結ぶと考えると、その交点の個数が答え
// dp[i][j][k]: i 番目まで見たとき、まだ結んでいない数が j 個で
//              奇妙さが k の順列の個数
long long dp[55][55][2505] = {};


int main()
{
    int n, k;
    cin >> n >> k;
    
    dp[0][0][0] = 1;
    REP(i, n){
        REP(j, i+1){
            REP(l, k+1){
                // i 番目同士を結ぶ場合
                dp[i+1][j][l+2*j] += dp[i][j][l] % MOD;
                // i 番目の片方のみを結ぶ場合
                dp[i+1][j][l+2*j] += 2*j * dp[i][j][l] % MOD;
                // i 番目をどちらもそれより前のものと結ぶ場合
                if(j >= 1){
                    dp[i+1][j-1][l+2*(j-1)] += j*j * dp[i][j][l] % MOD;
                }
                // i 番目のどちらも結ばない場合
                dp[i+1][j+1][l+2*(j+1)] += dp[i][j][l] % MOD;
            }
        }
    }
    cout << dp[n][0][k] % MOD << endl;
    
    return 0;
}