Problem:
Score : 1600 points

Problem Statement

There is a blackboard on which all integers from -10^{18} through 10^{18} are written, each of them appearing once. Takahashi will repeat the following sequence of operations any number of times he likes, possibly zero:

Choose an integer between 1 and N (inclusive) that is written on the blackboard. Let x be the chosen integer, and erase x.

If x-2 is not written on the blackboard, write x-2 on the blackboard.

If x+K is not written on the blackboard, write x+K on the blackboard.

Find the number of possible sets of integers written on the blackboard after some number of operations, modulo M.
We consider two sets different when there exists an integer contained in only one of the sets.

Constraints

1 \leq K\leq N \leq 150

10^8\leq M\leq 10^9

N, K, and M are integers.

Input

Input is given from Standard Input in the following format:

N K M

Output

Print the number of possible sets of integers written on the blackboard after some number of operations, modulo M.

Sample Input 1

3 1 998244353

Sample Output 1

7

Every set containing all integers less than 1, all integers greater than 3, and at least one of the three integers 1, 2, and 3 satisfies the condition. There are seven such sets.

Sample Input 2

6 3 998244353

Sample Output 2

61

Sample Input 3

9 4 702443618

Sample Output 3

312

Sample Input 4

17 7 208992811

Sample Output 4

128832

Sample Input 5

123 45 678901234

Sample Output 5

256109226

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair <int, int>
#define iiii pair <int, pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i, x) for(int (i) = 0; (i) < (x); (i)++)
inline int getint() {
  int x = 0, p = 1; char c = getchar();	
  while (c <= 32) c = getchar();
  if (c == 45) p = -p, c = getchar();
  while (c > 32) x = x * 10 + c - 48, c = getchar();
  return x * p;
}
using namespace std;
//ruogu_alter
const int N = 158;
int n, k, mod;
int g[N][N], f[N][N][N];
//
inline void reduce(int &x) {
  x += x >> 31 & mod;
}
inline void add(int &x, int y) {
  x += y - mod;
  reduce(x);
}
inline int mul(int x, int y) {
  return 1ll * x * y % mod;
}
void solve0() {
  g[0][0] = g[1][0] = 1;
  k /= 2;
  for (int i = 1; i <= n; i++) {
    add(g[i + 1][0], g[i][0]);
    for (int j = 1; j <= min(i, k); j++) {
      add(g[i][j], g[i - 1][j - 1]);
      add(g[i + 1][0], g[i][j]);
    }
  }
  int sum = 0, res = 0;
  rep(i, k + 1) add(sum, g[n / 2][i]);
  if (n & 1) ++n;
  rep(i, k + 1) add(res, g[n / 2][i]);
  cout << mul(res, sum) << endl;
}
void solve1() {
  assert(false);
  int c0 = 0, c1 = 0, c;
  for (int i = 2; i <= n; i += 2) {
    if (i - k <= 0) ++c0;
  }
  for (int i = 1; i <= n; i += 2) {
    if (i + k > n) ++c1;
  }
  c = (n - c0 - c1) / 2;
  f[0][0][0] = 1;
  for (int i = 1; i <= c0; i++) {
    rep(j, i) add(f[i][0][0], f[i - 1][0][j]);
    for (int j = 1; j <= i; j++) {
      add(f[i][0][j], f[i - 1][0][j - 1]);
    }
  }
  for (int i = c0 + 1; i <= c0 + c + c1; i++) {
    if (i <= c0 + c) for (int j = 1; j <= k; j++) {
      for (int x = 0; x < N; x++) {
        add(f[i][0][j], f[i - 1][x][j - 1]);
      }
    }
    rep(x, N) add(f[i][0][0], f[i - 1][0][x]);
    rep(j, k + 1) rep(k, N) {
      add(f[i][0][0], f[i - 1][j][k]);
    }
    for (int j = 2; j <= k; j++) {
      for (int x = 0; x < N; x++) {
        add(f[i][j][0], f[i - 1][j - 1][x]);
      }
    }
    if (i <= c0 + c) rep(j, k) for (int x = 0; x < N - 1; x++) {
      add(f[i][max(j, x) + 1][x + 1], f[i - 1][j][x]);
    }
  }
  int res = 0;
  rep(i, k + 1) rep(j, N) add(res, f[c + c0 + c1][i][j]);
  cout << res << endl;
}
int main() {
  n = getint(); k = getint(); mod = getint();
  if (!(k & 1)) {
    solve0();
  }
  else {
    solve1();
  }
  return 0;
}