// Slower C++ solution:
bool DBG = false;

#include<bits/stdc++.h>

//#include <boost/multiprecision/cpp_dec_float.hpp>

//#include <boost/multiprecision/cpp_int.hpp>

using namespace std;

using ll = long long;

using ld = long double;

//using i128 = __int128_t;

//using bint = boost::multiprecision::cpp_int;

//using d1024 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<1024>>;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define IFOR(i,a,b) for(int i=(b-1);i>=(a);--i)

#define RPT(i,a,b) for(int i=(a);i<((a)+(b));++i)

#define IRPT(i,a,b) for(int i=((a)+(b)-1);i>=(a);--i)

#define ALL(x) x.begin(),x.end()

#define fs first

#define sd second

#define couts(x) cout << (x) << (" ")

#define coutn(x) cout << (x) << ("\n")

#define endl "\n"

#define pb push_back

#define eb emplace_back

#define lb lower_bound

#define ub upper_bound

#define dcouts(x) if(DBG) couts(x)

#define dcoutn(x) if(DBG) coutn(x);

template<typename T> std::istream &operator>>(std::istream &is, std::vector<T> &vec){ for (auto &v : vec) is >> v; return is; }

template<typename T1, typename T2> std::istream &operator>>(std::istream &is, std::pair<T1,T2> &p){is >> p.first >> p.second; return is; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::deque<T> &vec){ os << "deque["; for (auto v : vec) os << v << ","; os << "]"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T1, typename T2> std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }

template<typename TK, typename TV> std::ostream &operator<<(std::ostream &os, const std::map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }

template<typename TK, typename TV> std::ostream &operator<<(std::ostream &os, const std::unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }



template<class T> using V = vector<T>;

template<class T> using V2 = V<V<T>>;

template<class T> using V3 = V<V2<T>>;





constexpr ll mod = 1000000007;



ll modpow(ll a, ll n, ll m) {

	ll res = 1;

	while (n) {

		if (n & 1)res = res * a % m;

		a = a * a%m; n >>= 1;

	}

	return res;

}



void solve(){

  int n, k; cin >> n >> k;

  ll lw = 1, up = 1, ans = 0;

  

  FOR(i,k,n+2){

    lw = ((ll)(i-1)*i%mod) * modpow(2,mod-2,mod)%mod;//couts(lw);

    up = ( (((ll)2*n%mod+mod-i+1)%mod) *(i)%mod) * modpow(2,mod-2,mod)%mod;//couts(up);

    (ans+=(up-lw+mod+1)%mod)%=mod;

  }

  coutn(ans);

}











int main(void){

  std::cout << std::fixed << std::setprecision(20);

  cin.tie(0);

  ios::sync_with_stdio(false);

  solve();

  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.6505825329373025x):
bool DBG = false;

#include<bits/stdc++.h>

//#include <boost/multiprecision/cpp_dec_float.hpp>

//#include <boost/multiprecision/cpp_int.hpp>

using namespace std;

using ll = long long;

using ld = long double;

//using i128 = __int128_t;

//using bint = boost::multiprecision::cpp_int

//using d1024 = boost::multiprecision::number<mp::cpp_dec_float<1024>>;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define IFOR(i,a,b) for(int i=(b-1);i>=(a);--i)

#define RPT(i,a,b) for(int i=(a);i<((a)+(b));++i)

#define IRPT(i,a,b) for(int i=((a)+(b)-1);i>=(a);--i)

#define ALL(x) x.begin(),x.end()

#define RALL(x) x.rbegin(),x.rend()

#define fs first

#define sd second

#define couts(x) cout << (x) << (" ")

#define coutn(x) cout << (x) << ("\n")

#define endl "\n"

#define pb push_back

#define eb emplace_back

#define lb lower_bound

#define ub upper_bound

#define dcouts(x) if(DBG) couts(x)

#define dcoutn(x) if(DBG) coutn(x)

template<typename T> std::istream &operator>>(std::istream &is, std::vector<T> &vec){ for (auto &v : vec) is >> v; return is; }

template<typename T1, typename T2> std::istream &operator>>(std::istream &is, std::pair<T1,T2> &p){is >> p.first >> p.second; return is; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::deque<T> &vec){ os << "deque["; for (auto v : vec) os << v << ","; os << "]"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T> std::ostream &operator<<(std::ostream &os, const std::unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }

template<typename T1, typename T2> std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }

template<typename TK, typename TV> std::ostream &operator<<(std::ostream &os, const std::map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }

template<typename TK, typename TV> std::ostream &operator<<(std::ostream &os, const std::unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }



template<class T> using V = vector<T>;

template<class T> using V2 = V<V<T>>;

template<class T> using V3 = V<V2<T>>;



using P = pair<ll,int>;





template<class T>

V<T> VF(V<T> v, function<T(T)> f){

  int n = (int) v.size();

  V<T> ret(n);

  for(int i=0; i<n; ++i) {

    T a = v[i];

    ret[i] = f(a);

  }

  return ret;

}

template<class T, class U>

V<U> VF2(V<T> v, function<U(T)> f){

  int n = (int) v.size();

  V<U> ret(n);

  for(int i=0; i<n; ++i) {

    T a = v[i];

    ret[i] = f(a);

  }

  return ret;

}

template<class T>

void VFS(V<T> &v, function<T(T)> f){

  int n = (int) v.size();

  for(int i=0; i<n; ++i) {

    T a = v[i];

    v[i] = f(a);

  }

  return;

}



constexpr ll mod = 1000000007;

 

ll modpow(ll a, ll n, ll m) {

	ll res = 1;

	while (n) {

		if (n & 1)res = res * a % m;

		a = a * a%m; n >>= 1;

	}

	return res;

}

 

void solve(){

  ll n, k; cin >> n >> k;

  ll ans = 0, n2=0, n3=0, k2=0, k3=0;

  n2 = (n*n)%mod;

  n3 = (n2*n) % mod;

  k2 = (k*k) % mod;

  k3 = (k2*k) % mod;

  ans = (n3 + 3*n2 + (-3*k2 + 3*k + 8+1000*mod)*n%mod  + 2*k3 - (6*k2)%mod - (2*k)%mod +12 + 1000*mod ) % mod;

  (ans *= modpow(6,mod-2,mod)) %= mod;

  coutn(ans);

}

 

 

 

 

 

int main(void){

  //std::cout << std::fixed << std::setprecision(20);

  cin.tie(0);

  ios::sync_with_stdio(false);

  solve();

  return 0;

}