// #pragma GCC target ("avx,avx2")
// #include <bits/extc++.h>
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp> // Common file
// #include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update

#define f first
#define s second

using namespace std;
// using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;

// typedef tree<pair<ll, int>, null_type, less<pair<ll, int>>, 
// rb_tree_tag, tree_order_statistics_node_update> oset;
//========================================================

const int N = 502;
int n, mod;

int dp[2][N * N][2][2];

int acc[N * N * 2];
void run_case()
{
    cin >> n >> mod;

    int z = n * (n - 1) / 2 + 1;

    auto getMod = [&](int x)
    {
        return x - (x >= mod ? mod : 0);
    };

    auto DP = [&](int i, int j, int bit)
    {
        return dp[i&1][abs(j)][j >= 0 ? 0 : 1][bit];
    };

    dp[0][0][0][1] = 1;
    int minPrev, maxPrev;

    for(int i=1; i<=n; i++)
    {
        dp[i&1][0][0][1] = 1ll * DP(i - 1, 0, 1) * (n - i + 1) %mod;

        acc[0] = 0;
        for(int j=1; j < z * 2; j++)
            acc[j] = getMod(acc[j - 1] + DP(i - 1, j - z, 0));

        int P = 0, newP = 0;
        
        for(int j = 1 - z; j < z; j++)
        {
            
            // z > j - k > -z
            // z - j > -k > -z - j
            // j - z < k < j + z
            
            int &ret = dp[i&1][abs(j)][j >= 0 ? 0 : 1][0];

            ret = 0;

            if(j < 0 && -j <= n - i)
                ret = getMod(ret + 1ll * (n - i + 1 + j) * DP(i - 1, 0, 1) %mod);

            // prev = j - k;

            minPrev = max(1 - z, j - (n - i));
            maxPrev = min(z - 1, j + (n - i));

            ret = getMod(ret + 1ll * (n - i + 1) * getMod(acc[maxPrev + z] - acc[minPrev + z - 1] + mod) %mod);

            // j=0: - 4*dp[-2] - 3*dp[-1] - 2*dp[0] - 1*dp[1] - 1*dp[3] - 2*dp[4] ...
            // j=1: - 4*dp[-1] - 3*dp[0]  - 2*dp[1] - 1*dp[2] - 1*dp[4] - 2*dp[5] ...
            /*
                dp[i][j] += dp[i][j - 1] + (n - i) * (dp[i - 1][minPrev - 1] - dp[i - 1][maxPrev + 1])
                dp[i][j] -= acc[j - 1] - acc[minPrev - 1];
                dp[i][j] += acc[maxPrev - 1] - acc[j - 1]
            */  

            newP = getMod(newP + 1ll * (n - i) * getMod(mod + DP(i - 1, minPrev - 1, 0) - DP(i - 1, maxPrev, 0)) %mod);

            newP = getMod(newP + (1ll * acc[maxPrev - 1 + z] + acc[minPrev + z - 1]
                - 2 * acc[j - 1 + z] + 2 * mod) %mod);

            ret = getMod(ret + newP);

            P = newP;
        }
    }

    int ret = 0;

    for(int j=1; j<z; j++)
        ret = getMod(ret + dp[n&1][j][0][0]);

    cout << ret << endl;
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    // freopen("input.txt", "rt", stdin);
    // freopen("output.txt", "wt", stdout);
    int T = 1;
    // cin >> T;
    while(T--)
        run_case();
}

// 1000000000 