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: Runtime Error)

/*input
96 925309799
*/
#include <bits/stdc++.h>
#define pb push_back
#define all(a) a.begin(), a.end()
#define sz(a) (int)a.size()
#define x first
#define y second
#define debug(...) cout << "[" << #__VA_ARGS__ << ": " << __VA_ARGS__ << "]\n"
#define rd() abs((int)rng())
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<int, int>pii;
const int maxn = 5050;
const int mod = 1e9 + 7;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
int n, k, MOD, change[maxn];
void add(int &a, int b)
{
	a += b;
	if(a >= MOD)
		a -= MOD;
}
int dp[505][505][505];
int solve(int i, int ops, int bal)
{
	if(i == n + 1)
		return 1;
	int &ret = dp[i][ops][bal];
	if(ret != -1)
		return ret;
	ret = 0;
	if(!(i == n && ops < n - 1))
		add(ret, solve(i + 1, ops, bal));
	if(ops < n - 1 && bal + change[i] > 0)
		add(ret, solve(i, ops + 1, bal + change[i]));
	return ret;
}
int main()
{
	ios_base::sync_with_stdio(false), cin.tie(0);
	cin >> n >> MOD;
	
	k = (n - 1) / 2;
	change[0] = 0;
	for(int i = 1; i <= k; i++)
		change[i] = -i;
	if(n % 2 == 0)
		change[k + 1] = -k;
	int cur = -k;
	for(int i = k + (n % 2 == 0) + 1; i <= n; i++)
	{
		++cur;
		change[i] = cur;
	}

	sort(change, change + n + 1, greater<int>());

	memset(dp, -1, sizeof dp);
	cout << solve(0, 0, 1) << "\n";
	// vector<vector<int> > dp(n + 1, vector<int>(n + 1, 0));
	
	// dp[0][1] = 1;
	// for(int i = 0; i <= n; i++)
	// {
	// 	vector<vector<int> > new_dp(n, vector<int>(n + 1, 0));
	// 	for(int ops = 0; ops < n - 1; ++ops)
	// 	{
	// 		for(int bal = 0; bal <= n; bal++)
	// 		{
	// 			add(dp[ops][bal], new_dp[ops][bal]);
	// 			if(!dp[ops][bal])
	// 				continue;
	// 			if(bal + change[i] >= 0)
	// 			{
	// 				debug(ops);
	// 				debug(bal);
	// 				debug(change[i]);
	// 				debug(dp[ops][bal]);
	// 				debug(new_dp[ops + 1][bal + change[i]]);
	// 				add(new_dp[ops + 1][bal + change[i]], dp[ops][bal]);
	// 			}
	// 		}
	// 	}
	// 	for(int ops = 0; ops <= n - 1; ++ops)
	// 	{
	// 		for(int bal = 0; bal <= n; bal++)
	// 			add(new_dp[ops][bal], dp[ops][bal]);
	// 	}
	// 	dp = new_dp;
	// }

	// int ans = 0;
	// for(int i = 1; i <= n; i++)
	// {
	// 	add(ans, dp[n - 1][i]);
	// }
	// cout << ans << "\n";
	return 0;
}