#include <bits/stdc++.h>
#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <boost/integer/common_factor.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>

using std::string;
using std::vector;
using std::set;
using std::multiset;
using std::unordered_set;
using std::map;
using std::multimap;
using std::unordered_map;
using std::pair;
using std::cin;
using std::cout;

using boost::multiprecision::cpp_int;
using cpp_dec_float_1000 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<1000, boost::int128_type>>;

typedef uintmax_t    ull;
typedef intmax_t     ll;
typedef uint64_t     ul;
typedef uint32_t     ui;
typedef uint8_t      uc;

constexpr char CRLF  = '\n';
constexpr char SPACE = ' ';
constexpr char VECTOR_COUT_SEPARATOR = SPACE;
constexpr ll INF = 1000'000'007;
constexpr int MOD = 1000'000'007;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> std::ostream& operator<< (std::ostream& os, const std::vector<T>& vc) { for(auto it = vc.begin(); it != vc.end(); ++it) { if (std::next(it) == vc.end()) os << *it; else os << *it << VECTOR_COUT_SEPARATOR; } return os; }
template<class T1, class T2> inline std::ostream & operator<< (std::ostream & os, const std::pair<T1, T2> & p) { return os << p.first << ' ' << p.second; }
template<class T> T modinv(T a, T m) { T b = m, u = 1, v = 0; while (b) { T t = a / b; a -= t * b; boost::swap(a, b); u -= t * v; boost::swap(u, v); } u %= m; if (u < 0) u += m; return u; }
template<class T> inline bool isSosuu(const T& n) { if (n == T(1)) { return false; } for (T i = 2; i*i <= n; ++i) { if (n % i == 0) { return false; } } return true; }
template<class T> vector<vector<T>> split (const vector<T>& S, T delim) { vector<vector<T>> ret{}; vector<T> buff{}; for (auto c : S) { if (c == delim) { if (!buff.empty()) ret.push_back(buff); buff.clear(); } else { buff.push_back(c); } } if (!buff.empty()) ret.push_back(buff); return ret; }
template<class T> inline void printYesNo(const T& t) { cout << (t ? "Yes" : "No") << CRLF; }
template<class T = int64_t> T modpow(T N, T P, T M) { T ret{1}; N %= M; while (P) { if (P & 0x01) { ret *= N; ret %= M; } P >>= 1; N *= N; N %= M; } return ret; }

/** code for assert debug begin */
int gErr = 0;
#define ASSERT(p) if(!(p)){ gErr = 1; }else{ ; }
/** code for assert debug end */

struct Tmp
{
public:
  int N;
  Tmp(int N)
  : N(N)
  {}
};

template<typename T = int64_t>
struct CombinationN
{
public:

  /** 符号付き整数を推奨 */
  using com_int = T;

  /** 特に必要はない */
  int mInf;

  /** modを取るので */
  com_int mMod;

  /** modinvするので */
  vector<com_int> inv;

  /** (k!)^-1のメモ帳 */
  vector<com_int> finv;

  /**
   * nCkに関して
   * * N <= 10^9
   * * K <= 10^5
   * 程度の制約について計算可能
   * @param N nCkで指定するnの最大
   * @param K nCkで指定するkの最大
   * @param m modを取るので
   */
  CombinationN(int N = 10^9, int K = 10^5, int m = MOD)
    : mInf(K)
    , mMod(m)
    , inv(K+1)
    , finv(K+1)
  {
    init();
  }

  /**
   * 二項係数を計算する.
   * 計算量はO(K).
   * @param n
   * @param k
   * @return nCk (mod m)
   */
  com_int operator()(int n, int k) {
    if (n < k) {
      return com_int(0);
    }
    if (n < 0 || k < 0) {
      return com_int(0);
    }
    if (k > mInf) {
      throw std::runtime_error("kが大きすぎる");
    }
    com_int ret{1};
    for (int i = n; i >= n - k + 1; --i) {
      ret *= i;
      ret %= mMod;
    }
    ret *= finv[k];
    ret %= mMod;
    return ret;
  }


private:

  /**
   * 前計算を行う.
   * 計算量はO(K).
   */
  void init() {
    finv[0] = finv[1] = com_int(1);
    inv[0] = -1; // どうでもいい
    inv[1] = com_int(1);

    for (int i = 2; i < (int)finv.size(); ++i) {
      inv[i] = mMod - (inv[mMod % i] * (mMod / i)) % mMod;
      finv[i] = (finv[i - 1] * inv[i]) % MOD;
    }
  }
};

void solve(void)
{
  int N, K; cin >> N >> K;
  // CombinationN<> comb(N+1, N+1, MOD);
  vector<ll> A(N+1);
  for (int i = 0; i < A.size(); ++i) {
    A[i] = i;
  }
  vector<ll> B(A.size());
  boost::partial_sum(A, B.begin());

  // ll min = -1;
  // ll max = -1;

  ll res{};
  for (int i = K; i <= N+1; ++i) {
    auto i_start = 0;
    auto i_end = i - 1;
    auto j_start = N - (i - 1);
    auto j_end = N;

    auto sum_min = B[i_end];
    auto sum_max = B[j_end] - (j_start > 0 ? B[j_start - 1] : (ll)0);
    // if (min == -1) {
    //   // 初項
    //   min = sum_min;
    //   max = sum_max;
    //   continue;
    // }

    // if (max < sum_min) {
    res += (sum_max - sum_min) + 1;
    res %= MOD;
    // min = sum_min;
    // max = sum_max;
    // } else {
    //   max = sum_max;
    // }
  }
  // res += (max - min) + 1;
  // res %= MOD;
  cout << res << CRLF;
  return;
}

int main(void)
{
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);

  solve();

  return 0;
}


Measured memory_bytes: 6368