#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <iostream>
#include <numeric>

/* debug macros */
#ifdef WAFDAYO
#define DBG_LINE() {std::cerr<<"\e[2m[L"<<__LINE__<<"]\e[m ";}
#define DBG_PRINT(s,t,u) {std::cerr<<(s)<<" \e[2m=\e[m \e[1m"<<(t)<<"\e[m"<<(u);}
#define SELECT_7TH(x1,x2,x3,x4,x5,x6,x7,...) x7
#define dbg1(x1) DBG_PRINT(#x1,x1,std::endl)
#define dbg2(x1,x2) DBG_PRINT(#x1,x1,", ")dbg1(x2)
#define dbg3(x1,x2,x3) DBG_PRINT(#x1,x1,", ")dbg2(x2,x3)
#define dbg4(x1,x2,x3,x4) DBG_PRINT(#x1,x1,", ")dbg3(x2,x3,x4)
#define dbg5(x1,x2,x3,x4,x5) DBG_PRINT(#x1,x1,", ")dbg4(x2,x3,x4,x5)
#define dbg6(x1,x2,x3,x4,x5,x6) DBG_PRINT(#x1,x1,", ")dbg5(x2,x3,x4,x5,x6)
#define dbg(...) DBG_LINE()\
SELECT_7TH(__VA_ARGS__,dbg6,dbg5,dbg4,dbg3,dbg2,dbg1)(__VA_ARGS__)
#else
#define dbg(...) {}
#endif

/* utility functions */
struct read_item{read_item(){};
template<class T>operator T(){T t;std::cin>>t;return t;}};
char splf(int i,int n){return(i+1<n)?' ':'\n';};
template<bool up>
struct _RI{int i;_RI(int a):i(a){}
int operator*(){return i;}void operator++(){i+=(up?1:-1);}
bool operator!=(const _RI& r){return up?i<r.i:i>=r.i;}};
template<bool up>
struct _RX{_RI<up> x,y;_RI<up> begin(){return x;}_RI<up> end(){return y;}
_RX(int a,int b):x(up?a:(a-1)),y(b){}_RX(int a):_RX(up?0:a,up?a:0){}};
typedef _RX<true> range;
typedef _RX<false> revrange;

/* types and constants */
typedef int64_t i64;
typedef uint64_t u64;
// const i64 inf = (i64)1.05e18;
// const int inf = (int)1.05e9;

using namespace std;

int modadd(int x, int y, int m) {
	int z = x + y;
	if(z >= m) {
		z = z - m;
	}
	return z;
}
int modsub(int x, int y, int m) {
	int z = x - y;
	if(z < 0) {
		z += m;
	}
	return z;
}

int main() {

	const int N = read_item();
	const int K = read_item();
	const int M = read_item();

	const int W = (N + 1) * N / 2 * K + 1;
	vector<int> ways((N + 1) * W);

	ways[0] = 1;

	for(int p : range(1, N + 1)) {

		int base = p * W;
		int ppp = p * (K + 1);
		int maxi = (1 + p) * p / 2 * K;

		for(int s : range(maxi + 1)) {
			auto& v = ways[base + s];
			v = ways[base + s - W];
			if(s >= p) {
				v = modadd(v, ways[base + (s - p)], M);
			}
		}
		for(int s : revrange( maxi + 1, 0)) {
			auto& v = ways[base + s];
			if(s >= ppp) {
				v = modsub(v, ways[base + (s - ppp)], M);
			}
		}
	}

	for(auto x : range(1, N + 1)) {

		int l = x - 1;
		int r = N - x;

		int lm = (1 + l) * l / 2 * K;
		int rm = (1 + r) * r / 2 * K;
		i64 v = 0;

		for(auto s : range(0, min(lm, rm) + 1)) {
			i64 vl = ways[l * W + s];
			i64 vr = ways[r * W + s];
			v = (v + vl * vr) % M;
		}

		i64 ans = ((v * (K + 1)) + (M - 1)) % M;

		printf("%lld\n", ans);
	}

	return 0;
}

/* wafdayo~~~ */

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
using vi=vector<int>;
using vvi=vector<vi>;
using vl=vector<ll>;
using vvl=vector<vl>;
using vpii=vector<pair<int,int>>;
using vpll=vector<pair<ll,ll>>;
using vs=vector<string>;
using vvc=vector<vector<char>>;

const int inf=1e9;
const ll INF=1e18;
const double eps=1e-10;
const double pi=acos(-1);
const ll mod=1e9+7;
const ll MOD=998244353;

//数学関連
int num_order(ll N){
  int res=0;
  
  while(N>0){
    N/=10;
    res++;
  }
  
  return res;
}
ll GCD(ll A,ll B){
  if(B==0) return A;
  else return GCD(B,A%B);
}
ll LCM(ll A,ll B){
  ll g=GCD(A,B);
  return A/g*B;
}
vpll prime_factorize(ll N){
  vpll res;
  
  for(ll i=2;i*i<=N;i++){
    if(N%i!=0) continue;
    
    ll ex=0;
    while(N%i==0){
      ex++;
      N/=i;
    }
    
    res.push_back({i,ex});
  }
  
  if(N!=1) res.push_back({N,1});
  
  return res;
}
ll modpow(ll a,ll n,ll p) {
  if (n == 0) return 1; // 0乗にも対応する場合
  if (n == 1) return a % p;
  if (n % 2 == 1) return (a * modpow(a, n - 1, p)) % p;
  long long t = modpow(a, n / 2, p);
  return (t * t) % p;
}
ll small_nCk(ll n,ll k){
  ll res=1,fact=1;
  
  for(int i=0;i<k;i++){
    res=res*(n-i)/fact;
    fact++;
  }
  
  return res;
}

//データ構造
struct UnionFind {
    //自身が親であれば、その集合に属する頂点数に-1を掛けたもの
    //そうでなければ親のid
    vector<int> r;
 
    UnionFind(int N){
        r=vector<int>(N,-1);
    }
 
    int root(int x){
        if (r[x]<0) return x;
        return r[x]=root(r[x]);
    }
 
    bool unite(int x,int y){
        x=root(x);
        y=root(y);
        if(x==y) return false;
        if(r[x]>r[y]) swap(x,y);
        r[x]+=r[y];
        r[y]=x;
        return true;
    }
 
    int size(int x){
        return -r[root(x)];
    }
};
struct Egde{
  int to;
  ll W;
  Egde(int to,ll W) : to(to),W(W) {}
};

using Graph=vector<vector<Egde>>;
 
int main(){
  
  int A,B;
  cin>>A>>B;
  
  int ans;
  
  if(A+B>=15&&B>=8) ans=1;
  else if(A+B>=10&&B>=3) ans=2;
  else if(A+B>=3) ans=3;
  else ans=4;
  
  cout<<ans<<endl;
}