#include <cmath>
#include <deque>
#include <algorithm>
#include <iterator>
#include <list>
#include <tuple>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <functional>
#include <numeric>
#include <iomanip> 
#include <stdio.h>
#include <assert.h>
#include <cstring>
//eolibraries
#define lnf 3999999999999999999
#define inf 999999999
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ld long double
#define all(c) (c).begin(),(c).end()
#define sz(c) (int)(c).size()
#define make_unique(a) sort(all(a)),a.erase(unique(all(a)),a.end())
#define pii pair <int,int>
#define rep(i,n) for(int i = 0 ; i < n ; i++) 
#define drep(i,n) for(int i = n-1 ; i >= 0 ; i--)
#define crep(i,x,n) for(int i = x ; i < n ; i++)
#define vi vector <int> 
#define vec(...) vector<__VA_ARGS__>
#define _3f4ZxtK ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
//eodefine
using namespace std;

const int mxn=100000;
//snuke's modular int
ll mod;
struct modularint{
	ll x;
	modularint(ll x=0):x(x%mod){}
	modularint& operator+=(const modularint a){
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	modularint& operator-=(const modularint a){
		if ((x += mod-a.x) >= mod) x -= mod;
		return *this;
	}
	modularint& operator*=(const modularint a){
		(x *= a.x) %= mod;
		return *this;
	}
	modularint operator+(const modularint a)const{
		modularint res(*this);
		return res+=a;
	}
	modularint operator-(const modularint a)const{
		modularint res(*this);
		return res-=a;
	}
	modularint operator*(const modularint a)const{
		modularint res(*this);
		return res*=a;
	}
	modularint pow(int n)const{
		modularint res=1,x(*this);
		while(n){
			if(n&1)res*=x;
			x*=x;
			n>>=1;
		}
		return res;
	}
	modularint inv()const{
		return pow(mod-2);
	}
};
using mint=modularint;

struct combination{
	vec(mint) fact;
	vec(vec(mint)) tablecnk;
	combination(int nupto){
		init(nupto);
	}
	void init(int nupto){
		tablecnk.clear();
		tablecnk.resize(2000,vec(mint)(2000,0));
		fact.resize(mxn+10,0);
		fact[0]=fact[1]=1;
		crep(i,2,mxn){
			mint x=i; fact[i]=fact[i-1]*x;
		}
		rep(i,2000) tablecnk[i][0]=tablecnk[i][i]=1;
		crep(i,1,2000){
			crep(j,1,2000){
				if(j>=i) break;
				tablecnk[i][j]=tablecnk[i-1][j-1]+tablecnk[i-1][j];
			}
		}
	}
	mint cnk(ll k,ll n){
		return tablecnk[n][k].x;
	}
};

int main(){
_3f4ZxtK;
	int n;
	cin>>n>>mod;
	combination comb(mxn);
	vec(vec(mint)) f(n+3,vec(mint)(n*n+3));
	f[1][0]=1;
	crep(i,2,n+1){
		rep(x,i){
			rep(s,n*n){
				if(f[i-1][s].x==0) continue;
				f[i][s+x] += f[i-1][s];	
			}
		}
	}
 	mint ans=0;
 	rep(i,n){
 		vec(vec(mint)) dp(n+3,vec(mint)(n*n+3));
		drep(x,n-i){
			mint sum=0;
			dp[x]=dp[x+1];
			rep(s,n*n-x){
				sum+=f[n-i-1][s];
				dp[x][s+x]+=sum;
			}
		}
		rep(x,n-i){
			rep(s,n*n){
				int nows=s+x;
				if(nows>0){
					ans+=f[n-i-1][s]*dp[x+1][nows-1]*comb.cnk(i,n)*comb.fact[i];
				}
			}
		}
	}
	cout<<ans.x<<"\n";
//
	return 0;
}