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
#include <cstdio>
#include <vector>

using namespace std;

typedef long long LL;

int p;
inline int sum(int a, int b) {
  return (a+b)%p;
}
inline int sub(int a, int b) {
  return sum(a, p-b);
}
inline int mul(int a, int b) {
  return LL(a)*b % p;
}

int main() {
  int n, m; scanf("%d %d %d", &n, &m, &p);

  int all;
  vector<int> ends_at_most(m);
  vector<int> ends_at_most_sum(m);
  vector<int> new_ends_at(m, 0);

  vector<int> ends_at(m, 0);
  ends_at[m-1] = 1;

  for (int i=0; i<n; ++i) {
//    printf("Layer %d:\n", i);
    
    ends_at_most[0] = ends_at[0];
    for (int i=1; i<m; ++i) {
      ends_at_most[i] = sum(ends_at_most[i-1], ends_at[i]);
    }
/*
    printf("ends_at_most: \n");
    for (int i=0; i<m; ++i) {
      printf("%d ", ends_at_most[i]);
    }
    printf("\n");
*/
    ends_at_most_sum[0] = ends_at_most[0];
    for (int i=1; i<m; ++i) {
      ends_at_most_sum[i] = sum(ends_at_most_sum[i-1], ends_at_most[i]);
    }
/*
    printf("ends_at_most_sum: \n");
    for (int i=0; i<m; ++i) {
      printf("%d ", ends_at_most_sum[i]);
    }
    printf("\n");
*/  
    int all = ends_at_most[m-1];
/*
    printf("all: \n");
    printf("%d: \n", all);
*/
    new_ends_at[0] = sub(all, ends_at_most[m-2]);
    for (int i=1; i<m-1; ++i) {
      new_ends_at[i] = sub(mul(sub(all, ends_at_most[m-2-i]), i+1), ends_at_most_sum[i-1]);
    }
    new_ends_at[m-1] = sub(mul(all, m), ends_at_most_sum[m-2]);
/* 
    printf("new_ends_at: \n");
    for (int i=0; i<m; ++i) {
      printf("%d ", new_ends_at[i]);
    }
    printf("\n");
    printf("\n");
*/

    swap(ends_at, new_ends_at);
  }

  int result = 0;
  for (int i=0; i<m; ++i) {
    result = sum(result, ends_at[i]);
  }
  printf("%d\n", result);
  return 0;
}