#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 30000;
const int MAXFFT = 1 << 16;
const double MYPI = acos(-1);
typedef struct FFT {
  int bitrev[MAXFFT];
  complex<long double> w[MAXFFT];
  void prefft(int m, int lgm) {
    for (int i = (0); i < (m); ++i)
      bitrev[i] = bitrev[i >> 1] >> 1 | ((i & 1) << (lgm - 1));
    for (int i = (0); i < (m); ++i)
      w[i] = complex<long double>(cos(2 * MYPI * i / m), sin(2 * MYPI * i / m));
  }
  void fft(complex<long double> a[MAXFFT], int m) {
    for (int i = (0); i < (m); ++i)
      if (i < bitrev[i]) swap(a[i], a[bitrev[i]]);
    for (int len = 2, step = m >> 1; len <= m; len <<= 1, step >>= 1) {
      for (int i = 0; i < m; i += len) {
        complex<long double> *l = a + i, *r = l + (len >> 1), *p = w;
        for (int off = (0); off < (len >> 1); ++off) {
          complex<long double> v = *r * *p;
          *r = *l - v;
          *l = *l + v;
          ++l, ++r, p += step;
        }
      }
    }
  }
  void mlt(int a[MAXFFT], int b[MAXFFT], int c[MAXFFT], int mx, int MOD) {
    static complex<long double> A[MAXFFT], B[MAXFFT];
    memset(A, 0, sizeof(A));
    memset(B, 0, sizeof(B));
    for (int i = (0); i <= (mx); ++i) A[i] = complex<double>(a[i], 0);
    for (int i = (0); i <= (mx); ++i) B[i] = complex<double>(b[i], 0);
    int m = 1, lgm = 0;
    while (m <= 2 * mx) m *= 2, ++lgm;
    prefft(m, lgm);
    fft(A, m);
    fft(B, m);
    for (int i = (0); i < (m); ++i) A[i] *= B[i];
    reverse(w + 1, w + m);
    fft(A, m);
    for (int i = (0); i <= (mx); ++i)
      c[i] = ((long long)floor(real(A[i]) / m + .5)) % MOD;
  }
} FFT;
FFT fft;
int maxn, maxa, MOD;
vector<int> p;
vector<vector<int> > ppp;
int ways[MAXN + 1];
int nways[MAXN + 1];
int choose[MAXN + 1];
int tmp[MAXN + 1];
int inv[MAXN + 1];
int A[MAXFFT];
int B[MAXFFT];
int C[MAXFFT];
int D[MAXFFT];
void calcchoose(int a) {
  choose[0] = tmp[0] = 1;
  vector<int> pp(((int)(p).size()), 0);
  for (int i = (0); i < (maxn); ++i) {
    int num = a - i;
    for (int j = (0); j < (((int)(p).size())); ++j)
      while (num > 0 && num % p[j] == 0) num /= p[j], ++pp[j];
    int den = num == 0 || tmp[i] == 0 ? 1 : i + 1;
    for (int j = (0); j < (((int)(p).size())); ++j)
      while (den % p[j] == 0) den /= p[j], --pp[j];
    tmp[i + 1] = (long long)tmp[i] * num % MOD * inv[den] % MOD;
    choose[i + 1] = tmp[i + 1];
    for (int j = (0); j < (((int)(p).size())); ++j)
      choose[i + 1] =
          (long long)choose[i + 1] * ppp[j][pp[j] % (MOD - 1)] % MOD;
  }
}
int egcd(int a, int b, int &x, int &y) {
  if (b == 0) {
    x = 1, y = 0;
    return a;
  }
  int ret = egcd(b, a % b, y, x);
  y -= x * (a / b);
  return ret;
}
void doublerange(int a) {
  calcchoose(a);
  memset(A, 0, sizeof(A));
  memset(B, 0, sizeof(B));
  memset(C, 0, sizeof(C));
  memset(D, 0, sizeof(D));
  if (a % 2 == 0)
    for (int i = (0); i <= (maxn); ++i) A[i] = choose[i], B[i] = ways[i];
  if (a % 2 == 1)
    for (int i = (0); i <= (maxn); ++i)
      A[i] = choose[i], B[i] = (choose[i] + MOD - ways[i]) % MOD;
  fft.mlt(A, B, C, maxn, MOD);
  for (int i = (0); i <= (maxn); ++i) C[i] = (C[i] % MOD + MOD) % MOD;
  for (int i = (0); i <= (maxn); ++i)
    ways[i] = (C[i] + MOD - (long long)A[i] * B[0] % MOD + ways[i]) % MOD;
}
void increaserange(int a) {
  calcchoose(a);
  for (int i = maxn; i >= 1; --i) ways[i] = (ways[i] + choose[i - 1]) % MOD;
}
void run() {
  scanf("%d%d%d", &maxn, &maxa, &MOD);
  p.clear();
  {
    int tmp = MOD;
    for (int i = 2; i * i <= tmp; ++i)
      if (tmp % i == 0) {
        p.push_back(i);
        while (tmp % i == 0) tmp /= i;
      }
    if (tmp != 1) p.push_back(tmp);
  }
  ppp = vector<vector<int> >(((int)(p).size()));
  for (int i = (0); i < (((int)(p).size())); ++i) {
    ppp[i].push_back(1);
    for (int j = (0); j < (MOD - 2); ++j)
      ppp[i].push_back((long long)ppp[i].back() * p[i] % MOD);
  }
  inv[1] = 1;
  for (int i = (2); i <= (maxn); ++i)
    if (gcd(i, MOD) == 1) {
      int x, y;
      egcd(i, MOD, x, y);
      inv[i] = (x % MOD + MOD) % MOD;
    }
  int q = 0;
  while ((2LL << q) <= maxa) ++q;
  assert(maxa / (1 << q) == 1);
  memset(ways, 0, sizeof(ways));
  ways[1] = 1;
  int ret = 0;
  if (q >= 1) ++ret;
  for (--q; q >= 1; --q) {
    doublerange(maxa / (2 << q));
    if ((maxa / (1 << q)) % 2 == 1) increaserange(maxa / (1 << q) - 1);
    for (int n = 1; n <= maxn; n += 2) ret = (ret + ways[n]) % MOD;
  }
  printf("%d\n", ret);
}
int main() {
  run();
  return 0;
}
