#pragma comment(linker, "/STACK:512000000")
#define _CRT_SECURE_NO_WARNINGS
/*#if !defined(YCM) && 0
#define _FORTIFY_SOURCE 0
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("avx,tune=native")
#include <stdio.h>
#endif*/
//#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

#define all(a) a.begin(), a.end()
typedef long long li;
typedef long double ld;
void solve(bool);
void precalc();
clock_t start;
int main() {
#ifdef AIM
    freopen("/home/alexandero/ClionProjects/ACM/input.txt", "r", stdin);
    //freopen("/home/alexandero/ClionProjects/ACM/output.txt", "w", stdout);
    //freopen("out.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);
#endif
    start = clock();
    int t = 1;
    cout.sync_with_stdio(0);
    cin.tie(0);
    precalc();
    cout.precision(10);
    cout << fixed;
    //cin >> t;
    int testNum = 1;
    while (t--) {
        //cout << "Case #" << testNum++ << ": ";
        //cerr << testNum << endl;
        solve(true);
        //cerr << testNum - 1 << endl;
    }
    cout.flush();
#ifdef AIM1
    while (true) {
      solve(false);
  }
#endif

#ifdef AIM
    cerr << "\n\n time: " << (clock() - start) / 1.0 / CLOCKS_PER_SEC << "\n\n";
#endif

    return 0;
}

//BE CAREFUL: IS INT REALLY INT?

template<typename T>
T binpow(T q, T w, T mod) {
    if (!w)
        return 1 % mod;
    if (w & 1)
        return q * 1LL * binpow(q, w - 1, mod) % mod;
    return binpow(q * 1LL * q % mod, w / 2, mod);
}

template<typename T>
T gcd(T q, T w) {
    while (w) {
        q %= w;
        swap(q, w);
    }
    return q;
}
template<typename T>
T lcm(T q, T w) {
    return q / gcd(q, w) * w;
}

template <typename T>
void make_unique(vector<T>& a) {
    sort(all(a));
    a.erase(unique(all(a)), a.end());
}

template<typename T>
void relax_min(T& cur, T val) {
    cur = min(cur, val);
}

template<typename T>
void relax_max(T& cur, T val) {
    cur = max(cur, val);
}

void precalc() {}

#define int li
const int mod = 1000000007;

int dp[111][111 * 111], ways[111][111 * 111];

void solve(bool read) {
    int n, k;
    cin >> n >> k;
    dp[0][0] = 0;
    ways[0][0] = 1;
    for (int pos = 0; pos < n; ++pos) {
        int val = n - pos;
        for (int can = 0; can <= pos * k; ++can) {
            if (!ways[pos][can]) {
                continue;
            }
            for (int c = 0; c <= k; ++c) {
                int add_score = (c + can) / val;
                if (c > val) {
                    add_score = 0;
                }
                /*if (can == 0 && pos == 1)
                cout << pos << " " << can << " " << ways[pos][can] << " " << dp[pos][can] << " " << add_score << " " << c << endl;*/
                dp[pos + 1][can + add_score] += ways[pos][can] * (c - add_score) + dp[pos][can];
                dp[pos + 1][can + add_score] %= mod;
                ways[pos + 1][can + add_score] += ways[pos][can];
                ways[pos + 1][can + add_score] %= mod;
            }
        }
    }

    int res = 0;
    for (int i = 0; i <= n * k; ++i) {
        //cout << i << " " << dp[n][i] << " " << ways[n][i] << endl;
        res += dp[n][i];
        res %= mod;
    }
    if (res < 0) {
        res += mod;
    }

    cout << res << endl;

}

Measured memory_bytes: 18816