#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

using namespace std ;
using namespace __gnu_pbds;

template <typename T> // *s.find_by_order(0), s.order_of_key(2) ;
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define reMin(a, b) a = min(a, b)
#define reMax(a, b) a = max(a, b)

#define lint long long
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define SET(x, val) memset(x, val, sizeof(x))
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)

typedef vector < int > vi ;
typedef pair < int, int > pii ;

const int N = 51 ;
const int MOD = 1e9 + 7 ;
const lint INF = 1e18 ;
const int K = 5201 ;
const int OFF = 2600 ;
const int OFF2 = 2500 ;

void _add(lint& x, lint y)
{
    x += y ; x %= MOD ;
}

int n, oddness ;
lint dp1[N][K], dp2[N][K] ;

/*
Initial idea: we have a permutation of 1..n with oddness k,
and we want to expand it to n + 1 permutations. How can we do this?
Initially we have n + 1 in position n + 1, and we can swap this with
any other position i. Let's say that we have the number j in position i.

If j >= i, then the oddness changes by 2*(n + 1 - j)
If j < i, then the oddness changes by 2*(n + 1 - i)

This is a problem, how can we keep track of the cases for each position? We can't.

Instead of swapping, it's better for an element to be final when we place it.
At each n, we either place number n in some empty slot (including position n) or leave
it unused. Similarly, we can either fill position n with one of our unused numbers or
leave it empty for now. But then in each state do we need to keep track of which
elements haven't been placed yet/which positions haven't been filled yet?

No, because we know the contribution of the position i which is left unfilled at
some point to the oddness, because it is always filled by an element greater than it.
If a position is left empty and is going to be filled later, we add -i to the oddness
now itself. Later, when some number j comes and fills it, we will add j to the oddness.
So we add j - i for a number j > i filling position i. Similarly if we are using an
unused number j from before to fill position i, then the contribution is i - j.
We subtract j at the moment we decide to keep j unused and add i to the answer when
we place some unused element at i. Now we don't need to know which element goes where
at all, we just need to know how many unused elements there are.
*/

/*
NOTE: dp[i][j][k] denotes I have just arrived at the ith position with j unused numbers
each of which are unique and somewhere between 1 and i-1, and the total oddness as of now is k.
NOTICE: The number of position unfilled till now (i-1)th state is also j.
*/

int main()
{
    fastio; cin >> n >> oddness ; SET(dp2, 0); SET(dp1, 0);
    dp2[0][OFF + oddness] = 1 ;

    for(int i = n; i > 0; i--)
    {
        for(lint j = i-1; j >= 0; j--)
        {
            for(int k = -OFF2; k <= OFF2; k++)
            {
                // I place number i on one of the j unused positions before i and
                // fill the current position with one of the j unused numbers.
                // NOTE: Since j empty positions are there, so there are j options
                // for this ith number and j unused numbers so j ways to fill ith position
                if(j) _add(dp1[j][OFF + k], j * j * dp2[j - 1][OFF + k + 2*i]);

                // I place number i on one of the j unused positions before and
                // leave current position unfilled. Note: since j empty
                // positions are there, so there are j options for this ith number
                _add(dp1[j][OFF + k], j * dp2[j][OFF + k]);

                // I leave number i for now (as in place it afterwards, ie at position > i)
                // and fill the current position with one of the j unused numbers.
                _add(dp1[j][OFF + k], j * dp2[j][OFF + k]);

                // I leave number i now and also the position i unfilled for now
                _add(dp1[j][OFF + k], dp2[j + 1][OFF + k - 2*i]);

                // I fill current position i with the ith number itself
                _add(dp1[j][OFF + k], dp2[j][OFF +k]);
            }
        }
        for(int j = 0; j < N; j++)
            for(int k = 0; k < K; k++)
                dp2[j][k] = dp1[j][k], dp1[j][k] = 0 ;
    }
    cout << dp2[0][OFF + 0] ;
}



Measured memory_bytes: 4352