Problem:
Score : 1200 points

Problem Statement

N problems have been chosen by the judges, now it's time to assign scores to them!

Problem i must get an integer score A_i between 1 and N, inclusive.
The problems have already been sorted by difficulty: A_1 \le A_2 \le \ldots \le A_N must hold.
Different problems can have the same score, though.

Being an ICPC fan, you want contestants who solve more problems to be ranked higher.
That's why, for any k (1 \le k \le N-1), you want the sum of scores of any k problems to be strictly less than the sum of scores of any k+1 problems.

How many ways to assign scores do you have? Find this number modulo the given prime M.

Constraints

2 \leq N \leq 5000

9 \times 10^8 < M < 10^9

M is a prime.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N M

Output

Print the number of ways to assign scores to the problems, modulo M.

Sample Input 1

2 998244353

Sample Output 1

3

The possible assignments are (1, 1), (1, 2), (2, 2).

Sample Input 2

3 998244353

Sample Output 2

7

The possible assignments are (1, 1, 1), (1, 2, 2), (1, 3, 3), (2, 2, 2), (2, 2, 3), (2, 3, 3), (3, 3, 3).

Sample Input 3

6 966666661

Sample Output 3

66

Sample Input 4

96 925309799

Sample Output 4

83779

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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 5005;

int mod;

inline int gi()
{
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	int sum = 0;
	while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar();
	return sum;
}

inline int add(int x, int y) {return x + y >= mod ? x + y - mod : x + y;}

int n, ans, f[maxn][maxn], b[maxn];

int main()
{
	n = gi(); mod = gi();
	for (int i = 2; i <= n / 2 + 1; ++i) b[i] -= n / 2 + 2 - i;
	for (int i = 1; i <= n - n / 2; ++i) b[i] += n / 2;
	for (int i = n - n / 2 + 1; i <= n; ++i) b[i] += n - i + 1;
	for (int i = 2; i <= n; ++i) ++b[i];

	f[n + 1][0] = 1;
	for (int i = n; i >= 2; --i)
		for (int j = 0; j < n; ++j) {
			f[i][j] = f[i + 1][j];
			if (j >= b[i]) f[i][j] = add(f[i][j], f[i][j - b[i]]);
		}
	
	for (int i = 0; i < n; ++i) ans = (ans + (ll)f[2][i] * (n - i)) % mod;
	printf("%d\n", ans);
	
	return 0;
}