#include <iostream>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <set>
#include <algorithm>
#include <deque>
#include <string>
#include <cmath>
#include <unordered_map>
using namespace std;

long long M;
int n;

map<int, long long> dp_lex[51], dp[51]; 
//dp_lex[i][j] = number of pairs (p,q) of permutations of length i such that 
//p is lex. smaller than q, and p has exactly j more inversions than q. 

map<int, long long> dp_presum;
long long range_sum(int l, int r){
    return (dp_presum[r] - dp_presum[l-1] + M) % M;
}


long long work(){
    dp[1][0] = 1;
    for (int i=2;i<=n;i++){
        int mn, mx;
        mn = -(i-1)*(i)/2;
        mx = (i-1)*(i)/2;

        dp_presum.clear();
        for (int l=mn-i-1;l<mn+i-1;l++) dp_presum[l] = 0;
        for (int l=mn+i-1;l<=mx-(i-1);l++){
            dp_presum[l] = dp_presum[l-1] + dp[i-1][l];
            if (dp_presum[l] > M) dp_presum[l] -= M;
        }
        for (int l=mx-(i-1)+1;l<=mx+i-1;l++)
            dp_presum[l] = dp_presum[mx-(i-1)];


        long long prv = 0;
        for (int l=mn;l<=mx;l++){
            dp[i][l] = prv + range_sum(l,l+i-1) - range_sum(l-i,l-1);
            prv = dp[i][l] = (dp[i][l]+M) %M;
        }

        //dp_lex:

        //calculate the long way for l=1
        for (int j=1;j<=i-1;j++){
            dp_lex[i][1] += dp[i-1][j+1] * (i-j);
        }

        prv = dp_lex[i][1];
        for (int l=2;l<=mx;l++){
            dp_lex[i][l] = prv + range_sum(l+1,l+i-1) - dp[i-1][l] * (i-1);
            prv = dp_lex[i][l] = ((dp_lex[i][l] + M) %M + M) %M;
        }
        //then add in the j = 0 recursive case
        for (int l=1;l<=mx;l++){
            dp_lex[i][l] += dp_lex[i-1][l] * i;
            dp_lex[i][l] %= M;
        }




      /* for (int l=mn;l<=mx;l++){
            // '1' in p is j spaces to the left of '1' in q. j>0 -> lex. smaller
            for (int j=-i+1;j<=i-1;j++){
                if ( (l+j) <= (mx-(i-1)) && (l+j) >= (mn + (i-1))){
                    //cout << "l = " << l << " j = " << j << " prv = " << l+j << endl;
                    //j < 0 -> i is lex. larger than j but more inversions
                    if (j < 0)
                        dp[i][l] += dp[i-1][l+j] * (i+j);
                    // j > 0 -> i is lex. smaller than j but fewer inversions
                    if (j >= 0)
                        dp[i][l] += dp[i-1][l+j] * (i-j);
                    dp[i][l] %= M;

                    if (l <= 0) continue;

                    if (j == 0)
                        dp_lex[i][l] += dp_lex[i-1][l] * i;

                    if (j > 0)
                        dp_lex[i][l] += dp[i-1][l+j] * (i-j);
                    dp_lex[i][l] %= M;
                
                    
                }
            }
        } */
        
    }

    long long ans = 0;
    for (int i=1;i<=n*(n-1)/2;i++){
        ans += dp_lex[n][i];
        if (ans >= M) ans -= M;
    }
    return ans%M;
}

int main(){
    cin >> n >> M;
    cout << work() << endl;

}

