/*#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
typedef long long ll;
mt19937 rnd(time(NULL));
*/
/*
template<typename T>
class node {
public:
    T val;
    int rcd;
    node *ch[2];
    node() {}
    node(T x, node *l = NULL, node *r = NULL) {
        val = x, ch[0] = l, ch[1] = r;
        rcd = rnd();
    }
};

#define Node node<T>

template <typename T>
class Treap {
private:
public:
    Node *root;
    void insert(T v) {
        Node x = new Node(v);

    }
};

template <typename T>
static Node *merge(Node *x, Node* y) {
	// x < y
    if(!x)
        return y;
    if(!y)
        return x;
    if(x->rcd < y->rcd) {
        y->ch[0] = merge(x, y->ch[0]);
        return y;
    }
    else {
        x->ch[1] = merge(x->ch[1], y);
        return x;
    }
}

template <typename T>
static void *split(Node *rt, Node *x, Node *y, T k) {
    if(!rt) {
        x = y = NULL;
        return ;
    }
    if(rt->val < k) {
        split(x->ch[1], x, y, k);
        rt->ch[1] = x;
        x = rt;
    }
    else {
        split(x->ch[0], x, y, k);
        rt->ch[0] = y;
        y = rt;
    }
}
#undef Node
Treap<int> T;


class seg {
public:
    int l, r,v;
    bool operator < (const seg&x) const {
        if(l == x.l) return r < x.r;
        return l < x.l;
    }
};

set<seg>::iterator split(set<seg> &S, int p) { //
    auto it = S.upper_bound(seg{p,int(2e9)});
    if(it == S.begin()) return it;
    --it;
    if(it->r <= p) return ++it;
    int l = it->l, r = it->r,v = it->v;
    S.erase(it), S.insert({l, p,v});
    return S.insert({p+1, r,v}).first;
}

void cal(set<seg> &S, seg c) {
    split(S, c.r);
    auto it = split(S, c.l-1);
    auto it2 = it;
    for(; it2 != S.end() && it2->r <= c.r; ++it2);
    S.erase(it, it2);
    S.insert(c);
}

class SegTree{
	#define ls (rt<<1)
	#define rs (rt<<1|1)
private:
	set<seg> tree[maxn<<2];
public:
	void build(int l,int r,int rt) {
		tree[rt].clear();
		if(l == r) return ;
		int mid = l+r>>1;
		build(l,mid,ls);
		build(mid+1,r,rs);
	}

	void insert(int l,int r,int rt,int p,seg c) {
		cal(tree[rt],c);
		if(l != r) {
			int mid = l+r>>1;
			if(p <= mid) insert(l,mid,ls,p,c);
			else insert(mid+1,r,rs,p,c);
		}
	}
	int query(int l,int r,int rt,int ql,int qr,int p) {
		if(ql > qr || tree[rt].size()==0) return 0;
		if(ql <= l&&qr >= r) {
			auto &now = tree[rt];
			auto it = now.upper_bound(seg{p,(int)2e9,0});
			if(it == now.begin()||(--it)->r < p) return 0;
			return 1;
		}else {
			int mid = l+r>>1,ret = 1;
			if(ql<=mid) ret &= query(l,mid,ls,ql,qr,p);
			if(qr>mid) ret &= query(mid+1,r,rs,ql,qr,p);
			return ret;
		}
	}
	#undef ls
	#undef rs
};

int ds[maxn],df[maxn];
    int dp[128][128][256],sum[1024];
class Solution {
public:
    int cal(int l,int r,int m) {
        if(m*2 >= r-l+1) return sum[r] - sum[l-1];
        if(dp[l][r][m] != -1) return dp[l][r][m];
        dp[l][r][m] = 0;
        for(int i = 1;i <= m*2 && l+i <= r; ++i) {
            dp[l][r][m] = max(sum[r]  - sum[l-1] - cal(l+i,r,max(i,m)),dp[l][r][m]);
            //dp[l][r] = max(sum[r] - sum[l-1] + cal(l,r-1),dp[l][r]);
        }
        return dp[l][r][m];
    }
    int stoneGameII(vector<int>& piles) {
        int n = piles.size();
        for(int i = 0;i <= n; ++i) for(int j = 0;j<= n; ++j) for(int k = 0;k <= n*2; ++k)dp[i][j][k] = -1;
        for(int i = 1;i <= piles.size(); ++i) {
            sum[i] = sum[i-1] + piles[i-1];
        }
        int mx = cal(1,n,1);
        return mx;
        return 0;
    }
};
*/
#include <bits/stdc++.h>

using namespace std;
const int maxn = 5005;
typedef long long ll;
int dp[2][maxn],sum[maxn];
int main() {
	int n,mod,rt = 0;
	cin>>n>>mod;
	dp[rt][0] = 1;
	for(int i = 1;i < n;++i) {
		rt ^= 1;
		int s = i;
		if(n%2 == 1&& s > n/2 + 1) s = (n-i+1);
		if(n%2 == 0 && s > n/2) s = (n-i+1);
		memset(dp[rt],0,(n+1)<<2);
	//	cout<<s<<'\n';
		for(int j = 0;j < n; ++j) {
			for(int k = 0;k < n&&j-k*s>=0; ++k) {
				dp[rt][j] += dp[rt^1][j-k*s];
				if(dp[rt][j] >= mod) dp[rt][j] -= mod;
			}
		}
	}
	ll ans = 0;
	for(int i = 0;i < n; ++i) {
		int j = n-i-1;
		ans += 1ll*(j+1)* dp[rt][i];
		ans %= mod;
	}
	cout<<ans<<'\n';
	return 0;
}




Measured memory_bytes: 384