#include <bits/stdc++.h>
using namespace std;
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
*/

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef map<int, int> mii;
typedef unordered_map<int, int> umii;
typedef map<ll, ll> mll;
typedef unordered_map<ll, ll> umll;

/*
struct Node
{
    int node, len;
    Node() {node = len = 0;}
    Node(int node, int len) {this -> node = node, this -> len = len;}
};
typedef vector<Node> vg;
*/

#define MAX 501

#define fi first
#define se second
#define pf push_front
#define pb push_back

#define FOR(type, i, a, b) for(type i = (a); i <= (b); i++)
#define FORD(type, i, b, a) for(type i = (b); i >= (a); i--)

#define testBit(n, bit) ((n >> bit) & 1)
#define flipBit(n, bit) (n ^ (1ll << bit))
#define cntBit(n) __builtin_popcount(n)
#define cntBitll(n) __builtin_popcountll(n)
#define randomize mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());

int n, MOD;
int cnt[MAX * MAX];
int tmp[MAX * MAX];
int f[MAX];

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> MOD;
    cnt[0] = 1; int prvMaxInv = 0;
    int ans = 0;
    FOR(int, len, 2, n){
        int curMaxInv = len * (len - 1) / 2;
        int curAdd = 1ll * f[len - 1] * len % MOD;
        FOR(int, i, 0, prvMaxInv)
            tmp[i] = cnt[i];

        FOR(int, i, 1, len - 1){
            int save = 0;
            FORD(int, j, prvMaxInv, 0){
                int pos = i + j;
                curAdd += 1ll * tmp[j] * save % MOD, curAdd %= MOD;
                save += cnt[pos], save %= MOD;
                cnt[pos] += tmp[j], cnt[pos] %= MOD;
            }
        }
        f[len] = curAdd;
        prvMaxInv = curMaxInv;
    }
    cout << f[n];
}