Problem: Let's define the function f of multiset a as the multiset of number of occurences of every number, that is present in a.

E.g., f(\{5, 5, 1, 2, 5, 2, 3, 3, 9, 5\}) = \{1, 1, 2, 2, 4\}.

Let's define f^k(a), as applying f to array a k times: f^k(a) = f(f^{k-1}(a)), f^0(a) = a. 

E.g., f^2(\{5, 5, 1, 2, 5, 2, 3, 3, 9, 5\}) = \{1, 2, 2\}.

You are given integers n, k and you are asked how many different values the function f^k(a) can have, where a is arbitrary non-empty array with numbers of size no more than n. Print the answer modulo 998 244 353.

Input

The first and only line of input consists of two integers n, k (1 ≤ n, k ≤ 2020).

Output

Print one number — the number of different values of function f^k(a) on all possible non-empty arrays with no more than n elements modulo 998 244 353.

Examples

Input


3 1


Output


6


Input


5 6


Output


1


Input


10 1


Output


138


Input


10 2


Output


33

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
template <typename T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-') flag = true;
    c = getchar();
  }
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
  if (flag) x = -x;
}
using namespace std;
const int P = 998244353;
inline void ADD(int &a, int b) {
  a += b;
  if (a >= P) a -= P;
}
inline int Add(int a, int b) {
  a += b;
  if (a >= P) a -= P;
  return a;
}
inline int dec(int a, int b) {
  a -= b;
  if (a < 0) a += P;
  return a;
}
int n, k;
namespace jzpforce {
int h[2050], htot;
int lhm[2][2050], ltot[2];
inline bool check() {
  int t = 0;
  ltot[t] = 0;
  for (int i = 1; i <= htot; ++i) lhm[t][++ltot[t]] = h[i];
  for (int _ = 1; _ <= k; ++_) {
    t ^= 1;
    ltot[t] = 0;
    int sm = 0, jzp = 0;
    for (int i = ltot[t ^ 1]; i; --i) {
      int ct = lhm[t ^ 1][i];
      ++jzp;
      for (int j = 1; j <= ct; ++j) {
        lhm[t][++ltot[t]] = jzp;
        sm += jzp;
      }
    }
    if (sm > n) return false;
  }
  return true;
}
int res;
void dfs(int lst) {
  for (int i = 0;; ++i) {
    h[++htot] = lst + i;
    if (!check()) {
      --htot;
      return;
    }
    ++res;
    dfs(lst + i);
    --htot;
  }
}
inline void sol() {
  --k;
  dfs(1);
  printf("%d\n", res);
}
}  // namespace jzpforce
namespace jzp1 {
int f[2050][2050];
inline void sol() {
  f[0][0] = 1;
  int res = 0;
  for (int i = 0; i <= n; ++i) {
    for (int j = 0; j <= n; ++j)
      if (f[i][j]) {
        int tmp = f[i][j];
        ADD(res, tmp);
        if (j + i <= n) ADD(f[i][j + i], tmp);
        if (j + 1 <= n) ADD(f[i + 1][j + 1], tmp);
      }
  }
  printf("%d\n", dec(res, 1));
}
}  // namespace jzp1
namespace jzp2 {
int f[2050][2050];
inline void sol() {
  f[0][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j <= n; ++j) {
      f[i][j] = f[i - 1][j];
      int tmp = i * (i + 1) >> 1;
      if (j >= tmp) ADD(f[i][j], f[i][j - tmp]);
    }
  }
  int res = 0;
  for (int i = 1; i <= n; ++i) ADD(res, f[n][i]);
  printf("%d\n", res);
}
}  // namespace jzp2
int main() {
  read(n), read(k);
  if (k > 2) return jzpforce::sol(), 0;
  if (k == 1) return jzp1::sol(), 0;
  jzp2::sol();
  return 0;
}