#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbori.in");
ofstream fout("arbori.out");
int n, mod, rest, dp[110][2];
///dp[i][0] = nr de moduri de a construi un arbore cu i noduri fiecare avand grad = rest (mod mod) unde voi gasii si rasp
///dp[i][1] = nr de moduri de a construi un arbore cu i noduri fiecare avand grad = rest - 1 (mod mod) pt ca daca ma adancesc o muchie
///vine de la parinte si mai tre sa pun decat rest - 1 sa ajung la gradu bun
///practic la dp[i][1] avem radacina frunza si la dp[i][0] avem radacina interna
inline int combi(int n, int k) {
if(k > n) return 0;
if(k > n - k) k = n - k;
int rez = 1;
for(int i=0; i<k; i++) {
rez *= (n - i);
rez /= (i + 1);
}
return rez;
}
inline int combiRepet(int n, int k) { return combi(n + k - 1, k); }
inline void backTrack(int nivel, int grad, int sum, int ramas, int total) {
///arborele va avea total noduri din care mai am de pus ramas noduri
///la fiecare voi incerca sa pun arbori de dimensiune nivel folosindu ma de starile anterioare
if(ramas == 0) {
if(grad % mod == rest) dp[total][0] += sum;
if(grad % mod == (rest - 1 + mod) % mod) dp[total][1] += sum;
}
else if(nivel <= ramas) {
for(int k=0; k * nivel <= ramas; k++) {
///adaug k fii/arbori de marime nivel(cu nivel noduri) punand decat arbori din dp[nivel][1] adica formele
///posibile pe care le putem repeta => combi cu repetitie
int x = combiRepet(dp[nivel][1], k);
backTrack(nivel + 1, grad + k, sum * x, ramas - k * nivel, total);
}
}
}
int main()
{
fin >> n >> mod >> rest;
dp[1][1] = 1; ///arbore cu un nod unde am radacina frunza
for(int i=2; i<=n; i++) backTrack(1, 0, 1, i - 1, i);
fout << dp[n][0];
return 0;
}