#include <bits/stdc++.h>
using namespace std;
typedef pair < int , int > pii;
typedef long long LL;
#define mpr make_pair
#define FS first
#define SC second
#define PB push_back
template < typename T > T MAX(T a,T b){return (a>b)?a:b;}
template < typename T > T MIN(T a,T b){return (a<b)?a:b;}
template < typename T > void UMAX(T &a,T b){a=(a>b?a:b);}
template < typename T > void UMIN(T &a,T b){a=(a<b?a:b);}
int readint(){
	char c=getchar();
	int ret=0;
	while(!(c>='0' && c<='9')) c=getchar();
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return ret;
}
void putint(int v){
	if(!v){
		putchar('0');
		return;
	}
	if(v>=10) putint(v/10);
	putchar('0'+(v%10));
}
int N,L,M,dp[2][10000000],xs[10000000][4];
int ptr,ind[80][80][80][80];
int F(int k){
	return (k<2)?k:(k/2+1);
}
int acc(int a,int b,int c,int d){
	int na=F(a),nb=F(b),nc=F(c),nd=F(d);
	if(ind[na][nb][nc][nd]!=-1) return ind[na][nb][nc][nd];
	xs[ptr][0]=a;xs[ptr][1]=b;xs[ptr][2]=c;xs[ptr][3]=d;
	return ind[na][nb][nc][nd]=ptr++;
}
int trs(int id,int v){
	int a=xs[id][0],b=xs[id][1],c=xs[id][2],d=xs[id][3];
	bool gb=0,gd=0;
	if(v){
		if(b==L) return -1;
		if(c>=L){
			gd=1;
			UMAX(d,((a&&c&&(abs(a-c)==1))?max(a,c):min(a,c))/2*2);
		}
	}
	else{
		a=b=0;
	}
	if(v) ++a;
	if(c) ++c;
	if(b || gb) ++b;
	if(d || gd) ++d;
	return acc(c,d,a,b);
}
int main(){
	int i,j,k;
	scanf("%d%d%d",&N,&L,&M);
	if(L==1){
		dp[0][0]=1;
		for(i=0;i<N;++i){
			int c=(i&1),t=1-c;
			for(j=0;j<3;++j){
				if(!dp[c][j]) continue;
				dp[t][0]+=dp[c][j];
				if(dp[t][0]>=M) dp[t][0]-=M;
				dp[t][j+1]+=dp[c][j];
				if(dp[t][j+1]>=M) dp[t][j+1]-=M;
				dp[c][j]=0;
			}
			dp[c][3]=0;
		}
		int res=0;
		for(i=0;i<3;++i){
			res+=dp[N&1][i];
			if(res>=M) res-=M;
		}
		printf("%d\n",res);
		return 0;
	}
	else if(!(L&1)){
		dp[0][0]=1;
		for(i=0;i<N;++i){
			int c=(i&1),t=1-c;
			for(j=0;j<N*N;++j){
				int sn=j%N,sf=j/N;
				if(!dp[c][j]) continue;
				// choose no
				dp[t][sf]+=dp[c][j];
				if(dp[t][sf]>=M) dp[t][sf]-=M;
				// choose yes
				if(sn<L/2){
					dp[t][sf+(sn+1)*N]+=dp[c][j];
					if(dp[t][sf+(sn+1)*N]>=M) dp[t][sf+(sn+1)*N]-=M;
				}
				dp[c][j]=0;
			}
		}
		int res=0;
		for(i=0;i<N*N;++i){
			res+=dp[N&1][i];
			if(res>=M) res-=M;
		}
		printf("%d\n",res);
		return 0;
	}
	ptr=0;
	memset(ind,-1,sizeof(ind));
	dp[0][acc(0,0,0,0)]=1;
	for(i=0;i<N;++i){
		int c=(i&1),t=1-c;
		for(j=0;j<ptr;++j){
			if(!dp[c][j]) continue;
			for(k=0;k<2;++k){
				int d=trs(j,k);
//				printf("trs %d %d = %d\n",j,k,d);
				if(d!=-1){
					dp[t][d]+=dp[c][j];
					if(dp[t][d]>=M) dp[t][d]-=M;
				}
			}
		}
		fill(dp[c],dp[c]+ptr,0);
	}
	int res=0;
	for(i=0;i<ptr;++i){
		res+=dp[N&1][i];
		if(res>=M) res-=M;
	}
	printf("%d\n",res);
	return 0;
}
/*
 * 代码框架
 * 0. 对于L=1：
 * 		即要求没有三连击，直接DP
 * 1. 对于偶的L：
 * 		dp[i][j][k]：已经确定前i个元素，奇数位置的延续长度为j，偶数位置的延续长度为k
 * 2. 对于奇的L：
 * 		四维数组f[i][j][k][l]：奇数位置的延续长度为i、上次距离为j；偶数位置的延续长度为k、上次距离为l
 * 			“上次距离”指奇偶性相反的中间位置
 * 			记得把坐标都/=2。=0表示不存在。
 * 			i,j,k,l都为n/2的级别
 * 			实现函数，支持access位置。维护指针
 * 		二维DP：dp[i][j]已经确定前i个元素，四维状态为j
 * 		实现函数：给定状态和下一位的取值，返回转移到的状态
 * 			将所有位置++
 * 			1. 判断是否可作为中间位置
 * 				若标记为空则更新
 * 			2. 判断是否可作为末尾位置
 * 				若打开则返回-1
 * 				若未打开则清空标记
 * 		转移：
 * 			直接做
 * 		结果取最后的总和
*/

Measured memory_bytes: 166144