#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <bitset>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <utility>
#include <algorithm>
#include <random>
#include <cmath>
#include <cassert>
#include <climits>
#include <ctime>
#include <chrono>


/*
#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx,avx2,tune=native")
*/


#ifdef LOCAL
    #define dbg(x) cout << #x << " : " << x << endl;
#else
    #define dbg(x)
#endif

#define int long long
#define pb push_back
#define ppb pop_back()
#define mp make_pair
#define fi(a, b) for (int i = a; i < b; i++)
#define fj(a, b) for (int j = a; j < b; j++)
#define fk(a, b) for (int k = a; k < b; k++)
#define fi1(a, b) for (int i = a - 1; i >= b; i--)
#define fj1(a, b) for (int j = a - 1; j >= b; j--)
#define fk1(a, b) for (int k = a - 1; k >= b; k--)
#define fx(x, a) for (auto& x : a)
#define rep(i, a, b) for (int i = a; i < b; ++i)
#define rep1(i, a, b) for (int i = a - 1; i >= b; --i)
#define siz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define left leftkekmda
#define right rightkekmda

using namespace std;

template<typename T1, typename T2>inline void mine(T1 &x, const T2 &y) { if (y < x) x = y; }
template<typename T1, typename T2>inline void maxe(T1 &x, const T2 &y) { if (x < y) x = y; }

template<typename T> ostream& operator << (ostream &os, const vector<T> &b) {
    for (auto &k : b) os << k << ' ';
    return os;
}
template<typename T> istream& operator >> (istream &is, vector<T> &b) {
    for (auto &k : b) is >> k;
    return is;
}


typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef char ch;
typedef string str;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef vector<ch> vch;
typedef vector<vch> vvch;
typedef vector<str> vs;





mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int MOD;
//const int N = ;
namespace md {
    ll mod(ll n) {
        if (n <= -MOD || n >= MOD) n %= MOD;
        if (n < 0) return n + MOD;
        else return n;
    }

    ll add(ll a, ll b) {
        a += b;
        if (a >= MOD) return a - MOD;
        return a;
    }

    ll sub(ll a, ll b) {
        a -= b;
        if (a < 0) return a + MOD;
        return a;
    }

    ll mult(ll a, ll b) {
        return a * b % MOD;
    }

    ll powmod(ll a, ll p) {
        if (p == 0) return 1;
        if (p & 1) return mult(a, powmod(a, p - 1));
        return powmod(mult(a, a), p / 2);
    }

    ll rev(ll a) {
        return powmod(a, MOD - 2);
    }
}

struct M {
    ll x;
    M (ll _x) { x = md::mod(_x); }
    M () { x = 0; }
    M operator + (M y) const {
        return M(md::add(x, y.x));
    }
    M operator - (M y) const {
        return M(md::sub(x, y.x));
    }
    M operator * (M y) const { return M(x * y.x); }
    M operator / (M y) const { return M(x * md::rev(y.x)); }
    M operator + (ll y) { return (*this) + M(y); }
    M operator - (ll y) { return (*this) - M(y); }
    M operator * (ll y) { return (*this) * M(y); }
    M operator / (ll y) { return (*this) / M(y); }
    M operator ^ (ll y) const { return M(x ^ y); }
    void operator += (M y) { *this = *this + y; }
    void operator -= (M y) { *this = *this - y; }
    void operator *= (M y) { *this = *this * y; }
    void operator /= (M y) { *this = *this / y; }
    void operator += (ll y) { *this = *this + y; }
    void operator -= (ll y) { *this = *this - y; }
    void operator *= (ll y) { *this = *this * y; }
    void operator /= (ll y) { *this = *this / y; }
    void operator ^= (ll y) { *this = *this ^ y; }
    bool operator == (M y) const { return x == y.x; }
    bool operator < (M y) const { return x < y.x; }
};

M operator * (int x, const M &y) {return y * x;}
M operator + (int x, const M &y) {return y + x;}
M operator - (int x, const M &y) {return y - x;}
M operator / (int x, const M &y) {return y / x;}

ostream& operator << (ostream& os, const M &a) {
    os << a.x;
    return os;
}

istream& operator >> (istream& is, M &a) {
    ll x;
    is >> x;
    a = M(x);
    return is;
}

const int N = 501;



M C[N][N];
M fac[N];

void calc() {
    for (int i = 0; i < N; ++i) {
        C[i][0] = C[i][i] = 1;
    }
    fac[0] = 1;
    for (int i = 1; i < N; ++i) {
        fac[i] = fac[i - 1] * i;
        for (int j = 1; j < i; ++j) {
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
        }
    }
}
M f[N * N / 2];
M pf[N * N / 2];
M ps[N * N / 2];
M pps[N * N / 2];

int g(int x) {
    return x * (x - 1) / 2;
}
int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n >> MOD;
    if (MOD == 1) {
        cout << "0\n";
        return 0;
    }
    calc();
    
    M ans;
    f[0] = 1;
    for (int m = 2; m <= n; ++m) {
        ps[0] = 1;
        pps[0] = 0;
        for (int i = 1; i <= g(m - 1); ++i) {
            ps[i] = ps[i - 1] + f[i];
            pps[i] = pps[i - 1] + ps[i - 1];
        }

        M cur;
        M sum;
        for (int i = 2; i <= g(m - 1); ++i) {
            sum += (m - 1) * ps[i - 2];
            sum -= (pps[i - 2] - pps[max(i - m - 1, 0ll)]);
            cur += f[i] * sum;
        } 
        ans += cur * C[n][m] * fac[n - m];
        sum = 0;
        for (int i = g(m); i >= 0; --i) {
            if (i >= m - 1) {
                sum += f[i - m + 1];
            }
            M old = f[i];
            f[i] = sum;
            sum -= old;
        }
    }
    cout << ans << '\n';
}
