Problem: Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university and participate in ACM instead of finding a new job. He wants to become a member of Bamokh's team. In order to join he was given some programming tasks and one week to solve them. Mashmokh is not a very experienced programmer. Actually he is not a programmer at all. So he wasn't able to solve them. That's why he asked you to help him with these tasks. One of these tasks is the following.

A sequence of l integers b1, b2, ..., bl (1 ≤ b1 ≤ b2 ≤ ... ≤ bl ≤ n) is called good if each number divides (without a remainder) by the next number in the sequence. More formally <image> for all i (1 ≤ i ≤ l - 1).

Given n and k find the number of good sequences of length k. As the answer can be rather large print it modulo 1000000007 (109 + 7).

Input

The first line of input contains two space-separated integers n, k (1 ≤ n, k ≤ 2000).

Output

Output a single integer — the number of good sequences of length k modulo 1000000007 (109 + 7).

Examples

Input

3 2


Output

5


Input

6 4


Output

39


Input

2 1


Output

2

Note

In the first sample the good sequences are: [1, 1], [2, 2], [3, 3], [1, 2], [1, 3].

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
string toString(T n) {
  ostringstream ost;
  ost << n;
  ost.flush();
  return ost.str();
}
int toInt(string s) {
  int r = 0;
  istringstream sin(s);
  sin >> r;
  return r;
}
long long toLInt(string s) {
  long long r = 0;
  istringstream sin(s);
  sin >> r;
  return r;
}
vector<string> parse(string temp) {
  vector<string> ans;
  ans.clear();
  string s;
  istringstream iss(temp);
  while (iss >> s) ans.push_back(s);
  return ans;
}
template <typename T>
inline unsigned long long dist(T A, T B) {
  unsigned long long res =
      (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
  return res;
}
template <typename T>
inline double cosAngle(T a, T b, T c) {
  double res = a * a + b * b - c * c;
  res = res / (2 * a * b);
  res = acos(res);
  return res;
}
template <class T>
inline T gcd(T a, T b) {
  if (a < 0) return gcd(-a, b);
  if (b < 0) return gcd(a, -b);
  return (b == 0) ? a : gcd(b, a % b);
}
template <class T>
inline T lcm(T a, T b) {
  if (a < 0) return lcm(-a, b);
  if (b < 0) return lcm(a, -b);
  return a * (b / gcd(a, b));
}
template <class T>
inline T power(T b, T p) {
  if (p < 0) return -1;
  if (b <= 0) return -2;
  if (!p) return 1;
  return b * power(b, p - 1);
}
template <class T>
int bit_count(T no) {
  int cnt = 0;
  while (no) {
    no = no >> 1;
    cnt++;
  }
  return cnt;
}
void seive(int lm, int arr[]) {
  for (int i = 2; i * i <= lm; i++)
    if (arr[i] == 0)
      for (int j = 1; j * i <= lm; j++) arr[i * j] = 1;
}
template <class T>
void showBit(T N) {
  T zero = 0, one = 1;
  if (N == zero) return;
  showBit(N >> 1);
  printf("%d", N & one);
}
long long binToDec(string s) {
  int ln = s.length();
  long long sum = 0;
  for (int i = ln - 1, k = 0; i >= 0; i--, k++)
    sum = sum + (s[i] - '0') * (1 << k);
  return sum;
}
string rev(string s) {
  string rs = "";
  int l = s.length();
  for (int i = l - 1; i >= 0; i--) rs = rs + s[i];
  return rs;
}
template <typename T>
string decToBin(T n, int dg) {
  string s = "";
  int td = 0;
  while (n) {
    int cb = n & 1;
    s = s + (char)(cb + '0');
    n = n >> 1;
    td++;
  }
  string as = "";
  while (td != dg) {
    as = as + "0";
    td++;
  }
  as = as + rev(s);
  return as;
}
void combination(long long com[][1005]) {
  com[0][0] = 1;
  int sz = 1000;
  for (int i = 1; i <= sz; i++) {
    com[i][0] = 1;
    for (int j = 1; j <= i; j++) {
      com[i][j] = com[i - 1][j] + com[i - 1][j - 1];
      com[i][j] = com[i][j] % 1000000007;
    }
  }
}
template <class T>
T bigmod(T bs, T p, T mod) {
  if (mod <= 0) {
    printf("Exception");
    return 0;
  }
  T ans = 1;
  T k = bs;
  while (p) {
    if (p & 1) {
      ans = ans * k;
      ans %= mod;
    }
    k *= k;
    k %= mod;
    p = p >> 1;
  }
  return ans;
}
void insert_ind(int cs, int ci, int s, int e) {
  if (s == e) {
    return;
  }
  int mid = (s + e) / 2;
  if (ci <= mid)
    insert_ind(2 * cs, ci, s, mid);
  else
    insert_ind(2 * cs + 1, ci, mid + 1, e);
}
void update_ind(int cs, int ci, int s, int e, int val) {
  if (s == e) {
    return;
  }
  int mid = (s + e) / 2;
  if (ci <= mid)
    update_ind(2 * cs, ci, s, mid, val);
  else
    update_ind(2 * cs + 1, ci, mid + 1, e, val);
}
void update_seg(int cs, int ds, int de, int s, int e, int val) {
  if (ds == s && de == e) {
    return;
  }
  int mid = (s + e) / 2;
  if (ds <= mid) update_seg(2 * cs, ds, min(mid, de), s, mid, val);
  if (de > mid) update_seg(2 * cs + 1, max(mid + 1, ds), de, mid + 1, e, val);
}
void pattern_match(char pat[], const int len, int pi[]) {
  pi[0] = 0;
  for (int i = 1; i < len; i++) {
    int ch = pi[i - 1];
    while (pat[ch] != pat[i]) {
      if (ch == 0) {
        ch = -1;
        break;
      }
      ch = pi[ch - 1];
    }
    pi[i] = ch + 1;
  }
}
void pattern_match(char pat[], int pi[], char tar[], const int len1, int gi[]) {
  if (pat[0] == tar[0]) gi[0] = 1;
  for (int i = 1; i < len1; i++) {
    int st = gi[i - 1];
    while (pat[st] != tar[i]) {
      if (st == 0) {
        st = -1;
        break;
      }
      st = pi[st - 1];
    }
    if (st == -1)
      gi[i] = 0;
    else
      gi[i] = st + 1;
  }
}
struct myArray {
  int mat[10][10];
};
myArray matrix_mul(myArray mat1, myArray mat2, const int sz) {
  int tmp[sz][sz];
  memset((tmp), 0, sizeof((tmp)));
  for (int r = 0; r < sz; r++)
    for (int c = 0; c < sz; c++)
      for (int cr = 0; cr < sz; cr++)
        tmp[r][c] += mat1.mat[r][cr] * mat2.mat[cr][c];
  myArray res;
  for (int r = 0; r < sz; r++)
    for (int c = 0; c < sz; c++) res.mat[r][c] = tmp[r][c];
  return res;
}
myArray unit_matrix(const int sz) {
  myArray ma;
  memset((ma.mat), 0, sizeof((ma.mat)));
  for (int i = 0; i < sz; i++) ma.mat[i][i] = 1;
  return ma;
}
myArray matrix_expo(int p, myArray mat, const int sz) {
  if (p == 0) {
    return unit_matrix(sz);
  }
  if (p & 1) return matrix_mul(mat, matrix_expo(p - 1, mat, sz), sz);
  myArray tmp = matrix_expo(p >> 1, mat, sz);
  return matrix_mul(tmp, tmp, sz);
}
map<string, int> msi;
void cal_state(string s, int tran[][30]) {
  int ln = s.length();
  string s1 = s;
  for (int i = 0; i < ln; i++) {
    msi[s1] = ln - i;
    s1 = s1.substr(0, ln - i - 1);
  }
  s1 = "";
  for (int i = 0; i < ln; i++) {
    string ts = s1;
    for (int j = 0; j < 26; j++) {
      s1 = ts + (char)('a' + j);
      int tln = i + 1;
      while (msi[s1] == 0) {
        s1 = s1.substr(1);
        tln--;
        if (tln == 0) break;
      }
      if (tln == 0) s1 = "";
      tran[i][j] = msi[s1];
    }
    s1 = s.substr(0, i + 1);
  }
}
double distance(double x1, double y1, double x2, double y2) {
  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int X[] = {0, 0, 1, -1};
int Y[] = {1, -1, 0, 0};
const int dx[8] = {-1, 1, -2, 2, -1, 1, -2, 2};
const int dy[8] = {2, 2, -1, -1, -2, -2, 1, 1};
int n, k;
long long dp[2005][2005];
long long recure(int cp, int cn) {
  if (cp == k) return 1;
  if (dp[cp][cn] != -1) return dp[cp][cn];
  dp[cp][cn] = 0;
  for (int i = 1; i * cn <= n; i++) {
    dp[cp][cn] += recure(cp + 1, i * cn);
    dp[cp][cn] %= 1000000007;
  }
  return dp[cp][cn];
}
long long solve() {
  memset((dp), -1, sizeof((dp)));
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    ans += recure(1, i);
    ans %= 1000000007;
  }
  return ans;
}
int main() {
  scanf("%d%d", &n, &k);
  cout << solve() << endl;
  printf("\n");
  return 0;
}