1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define shandom_ruffle random_shuffle

using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;
const int nax=1007;
const int vax=13;
const int limit_na_k=10;
ll mod;

int n, k;

ll kom[nax][nax];

ll dp_prze[vax][nax];
ll dp_prze_s[vax][nax];
ll dp_pref[vax][nax];
ll dp_pref_s[vax][nax];

void dod(ll &a, ll b)
{
	a=(a+b)%mod;
	if (a<0)
		a+=mod;
}

void ans(ll v)
{
	printf("%lld\n", v);
	exit(0);
}

int main()
{
	scanf("%d%d%lld", &n, &k, &mod);
	if (k>limit_na_k || n==1)
		ans(0);
	
	for (int i=0; i<=n; i++)
	{
		kom[i][0]=1;
		for (int j=1; j<=i; j++)
			kom[i][j]=(kom[i-1][j]+kom[i-1][j-1])%mod;
	}
	
	dp_prze[1][2]=dp_prze_s[1][2]=1;
	for (int i=2; i<=k; i++)
	{
		for (int j=2; j<=n; j++)
		{
			for (int l=2; l<j; l++)
			{
				dod(dp_prze[i][j], dp_prze_s[i-1][l]*dp_prze[i][j-l+1]%mod*kom[j-3][l-2]*2);
				dod(dp_prze[i][j], dp_prze[i-1][l]*dp_prze[i-1][j-l+1]%mod*kom[j-3][l-2]);
			}
			dp_prze_s[i][j]=(dp_prze_s[i-1][j]+dp_prze[i][j])%mod;
		}
	}
	dp_pref[0][1]=dp_pref_s[0][1]=1;
	for (int i=1; i<=k; i++)
	{
		dp_pref_s[i][1]=1;
		for (int j=2; j<=n; j++)
		{
			for (int l=2; l<=j; l++)
				dod(dp_pref_s[i][j], dp_prze_s[i][l]*dp_pref_s[i][j-l+1]%mod*kom[j-2][l-2]);
			dp_pref[i][j]=(dp_pref_s[i][j]-dp_pref_s[i-1][j]+mod)%mod;
		}
	}
	ll wyn=0;
	for (int i=1; i<=n; i++)
		dod(wyn, (dp_pref_s[k][i]*dp_pref_s[k][n-i+1]-dp_pref_s[k-1][i]*dp_pref_s[k-1][n-i+1])%mod*kom[n-1][i-1]);
	ans(wyn);
	return 0;
}