#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MOD = 1000000007;
const int N = 3e5 + 5;
void add_mod (int &a, int b) {
if ((a += b) >= MOD) a -= MOD;
if (a < 0) a += MOD;
}
int fact[N];
int inv_fact[N];
int bin_pow (int a, int b) {
assert(b >= 0);
int ans = 1;
while (b > 0) {
if (b & 1)
ans = ans * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return ans;
}
void build_fact (int n) {
fact[0] = 1;
for (int i = 1; i <= n; i++) {
fact[i] = fact[i - 1] * i % MOD;
}
inv_fact[n] = bin_pow(fact[n], MOD - 2);
for (int i = n - 1; i >= 0; i--) {
inv_fact[i] = (inv_fact[i + 1] * (i + 1)) % MOD;
}
}
int C (int k, int n) {
if (n < k)
return 0;
return (fact[n] * inv_fact[k]) % MOD * inv_fact[n - k] % MOD;
}
int n, k;
void read_input() {
cin >> n >> k;
}
int ans[N];
int f[N], last_f[N];
void calc_dp() {
last_f[0] = 1;
add_mod(ans[0], 1);
for (int i = 1; i * i <= (2*k); i++) {
for (int s = i; s <= k; s++) {
add_mod(f[s], last_f[s - i]);
add_mod(f[s], f[s - i]);
if (s >= n + 1)
add_mod(f[s], -last_f[s - n - 1]);
}
for (int s = 0; s <= k; s++) {
if (i % 2 == 0)
add_mod(ans[s], f[s]);
else
add_mod(ans[s], -f[s]);
last_f[s] = f[s];
f[s] = 0;
}
}
}
void solve() {
int res = 0;
for (int s = 0; s <= k; s++) {
add_mod(res, C(n - 1, n + k - s - 1) * ans[s] % MOD);
}
cout << res;
}
int32_t main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
read_input();
build_fact(N-5);
calc_dp();
solve();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIGludCBsb25nIGxvbmcKCmNvbnN0IGludCBNT0QgPSAxMDAwMDAwMDA3Owpjb25zdCBpbnQgTiA9IDNlNSArIDU7Cgp2b2lkIGFkZF9tb2QgKGludCAmYSwgaW50IGIpIHsKICBpZiAoKGEgKz0gYikgPj0gTU9EKSBhIC09IE1PRDsKICBpZiAoYSA8IDApIGEgKz0gTU9EOwp9CgppbnQgZmFjdFtOXTsKaW50IGludl9mYWN0W05dOwoKaW50IGJpbl9wb3cgKGludCBhLCBpbnQgYikgewogIGFzc2VydChiID49IDApOwogIGludCBhbnMgPSAxOwogIHdoaWxlIChiID4gMCkgewogICAgaWYgKGIgJiAxKQogICAgICBhbnMgPSBhbnMgKiBhICUgTU9EOwogICAgYSA9IGEgKiBhICUgTU9EOwogICAgYiA+Pj0gMTsKICB9CiAgcmV0dXJuIGFuczsKfQoKdm9pZCBidWlsZF9mYWN0IChpbnQgbikgewogIGZhY3RbMF0gPSAxOwogIGZvciAoaW50IGkgPSAxOyBpIDw9IG47IGkrKykgewogICAgZmFjdFtpXSA9IGZhY3RbaSAtIDFdICogaSAlIE1PRDsKICB9CiAgaW52X2ZhY3Rbbl0gPSBiaW5fcG93KGZhY3Rbbl0sIE1PRCAtIDIpOwogIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgIGludl9mYWN0W2ldID0gKGludl9mYWN0W2kgKyAxXSAqIChpICsgMSkpICUgTU9EOwogIH0KfQoKaW50IEMgKGludCBrLCBpbnQgbikgewogIGlmIChuIDwgaykKICAgIHJldHVybiAwOwogIHJldHVybiAoZmFjdFtuXSAqIGludl9mYWN0W2tdKSAlIE1PRCAqIGludl9mYWN0W24gLSBrXSAlIE1PRDsKfQoKaW50IG4sIGs7Cgp2b2lkIHJlYWRfaW5wdXQoKSB7CiAgY2luID4+IG4gPj4gazsKfQoKaW50IGFuc1tOXTsKaW50IGZbTl0sIGxhc3RfZltOXTsKCnZvaWQgY2FsY19kcCgpIHsKICBsYXN0X2ZbMF0gPSAxOwoKICBhZGRfbW9kKGFuc1swXSwgMSk7CgogIGZvciAoaW50IGkgPSAxOyBpICogaSA8PSAoMiprKTsgaSsrKSB7CiAgICBmb3IgKGludCBzID0gaTsgcyA8PSBrOyBzKyspIHsKICAgICAgYWRkX21vZChmW3NdLCBsYXN0X2ZbcyAtIGldKTsKICAgICAgYWRkX21vZChmW3NdLCBmW3MgLSBpXSk7CiAgICAgIGlmIChzID49IG4gKyAxKQogICAgICAgIGFkZF9tb2QoZltzXSwgLWxhc3RfZltzIC0gbiAtIDFdKTsKICAgIH0KICAgIGZvciAoaW50IHMgPSAwOyBzIDw9IGs7IHMrKykgewogICAgICBpZiAoaSAlIDIgPT0gMCkKICAgICAgICBhZGRfbW9kKGFuc1tzXSwgZltzXSk7CiAgICAgIGVsc2UKICAgICAgICBhZGRfbW9kKGFuc1tzXSwgLWZbc10pOwogICAgICBsYXN0X2Zbc10gPSBmW3NdOwogICAgICBmW3NdID0gMDsKICAgIH0KICB9Cn0KCnZvaWQgc29sdmUoKSB7CiAgaW50IHJlcyA9IDA7CiAgZm9yIChpbnQgcyA9IDA7IHMgPD0gazsgcysrKSB7CiAgICBhZGRfbW9kKHJlcywgQyhuIC0gMSwgbiArIGsgLSBzIC0gMSkgKiBhbnNbc10gJSBNT0QpOwogIH0KICBjb3V0IDw8IHJlczsKfQoKaW50MzJfdCBtYWluKCkgewogIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7CiAgY2luLnRpZSgwKTsKCiAgcmVhZF9pbnB1dCgpOwogIGJ1aWxkX2ZhY3QoTi01KTsKICBjYWxjX2RwKCk7CiAgc29sdmUoKTsKCiAgcmV0dXJuIDA7Cn0K