#include <bits/stdc++.h>
using std::max;
using std::min;
const int inf = 0x3f3f3f3f, Inf = 0x7fffffff;
const long long INF = 0x3f3f3f3f3f3f3f3f;
__inline__ __attribute__((always_inline)) unsigned int rnd() {
  static unsigned int seed = 416;
  return seed += 0x71dad4bfu, seed ^= seed >> 5, seed += 0xc6f74d88u,
         seed ^= seed << 17, seed += 0x25e6561u, seed ^= seed >> 13;
}
template <typename _Tp>
_Tp gcd(const _Tp &a, const _Tp &b) {
  return (!b) ? a : gcd(b, a % b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) _Tp abs(const _Tp &a) {
  return a >= 0 ? a : -a;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void chmax(_Tp &a, const _Tp &b) {
  (a < b) && (a = b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void chmin(_Tp &a, const _Tp &b) {
  (b < a) && (a = b);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) void read(_Tp &x) {
  char ch(getchar());
  bool f(false);
  while (!isdigit(ch)) f |= ch == 45, ch = getchar();
  x = ch & 15, ch = getchar();
  while (isdigit(ch)) x = (((x << 2) + x) << 1) + (ch & 15), ch = getchar();
  f && (x = -x);
}
template <typename _Tp, typename... Args>
__inline__ __attribute__((always_inline)) void read(_Tp &t, Args &...args) {
  read(t);
  read(args...);
}
template <typename _Tp, typename... Args>
__inline__ __attribute__((always_inline)) _Tp min(const _Tp &a, const _Tp &b,
                                                  const Args &...args) {
  return a < b ? min(a, args...) : min(b, args...);
}
template <typename _Tp, typename... Args>
__inline__ __attribute__((always_inline)) _Tp max(const _Tp &a, const _Tp &b,
                                                  const Args &...args) {
  return a < b ? max(b, args...) : max(a, args...);
}
__inline__ __attribute__((always_inline)) int read_str(char *s) {
  char ch(getchar());
  while (ch == ' ' || ch == '\r' || ch == '\n') ch = getchar();
  char *tar = s;
  *tar = ch, ch = getchar();
  while (ch != ' ' && ch != '\r' && ch != '\n' && ch != EOF)
    *(++tar) = ch, ch = getchar();
  return tar - s + 1;
}
int maxn, maxa, mod;
const int max_len = 1 << 16;
const int N = max_len + 5;
template <typename _Tp1, typename _Tp2>
__inline__ __attribute__((always_inline)) void add(_Tp1 &a, _Tp2 b) {
  (a += b) >= mod && (a -= mod);
}
template <typename _Tp1, typename _Tp2>
__inline__ __attribute__((always_inline)) void sub(_Tp1 &a, _Tp2 b) {
  (a -= b) < 0 && (a += mod);
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) _Tp _sub(_Tp a, const _Tp &b) {
  (a += mod - b) >= mod && (a -= mod);
  return a;
}
long long ksm(long long a, long long b = mod - 2) {
  long long res = 1;
  while (b) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod, b >>= 1;
  }
  return res;
}
void print(const std::vector<int> &a) {
  for (auto it : a) printf("%d ", it);
  printf("\n");
}
std::vector<int> operator+=(std::vector<int> &a, const std::vector<int> &b) {
  if (((int)b.size()) > ((int)a.size())) a.resize(((int)b.size()));
  for (unsigned int i = 0; i < b.size(); ++i) add(a[i], b[i]);
  return a;
}
__inline__ __attribute__((always_inline)) std::vector<int> operator+(
    const std::vector<int> &a, const std::vector<int> &b) {
  std::vector<int> tmp(a);
  tmp += b;
  return tmp;
}
std::vector<int> operator-=(std::vector<int> &a, const std::vector<int> &b) {
  if (((int)b.size()) > ((int)a.size())) a.resize(((int)b.size()));
  for (unsigned int i = 0; i < b.size(); ++i) sub(a[i], b[i]);
  return a;
}
__inline__ __attribute__((always_inline)) std::vector<int> operator-(
    const std::vector<int> &a, const std::vector<int> &b) {
  std::vector<int> tmp(a);
  tmp -= b;
  return tmp;
}
const double PI = acos(-1);
struct comp {
  double a, b;
  __inline__ __attribute__((always_inline)) comp operator+(
      const comp &o) const {
    return (comp){a + o.a, b + o.b};
  }
  __inline__ __attribute__((always_inline)) comp operator-(
      const comp &o) const {
    return (comp){a - o.a, b - o.b};
  }
  __inline__ __attribute__((always_inline)) comp operator*(
      const comp &o) const {
    return (comp){a * o.a - b * o.b, a * o.b + b * o.a};
  }
};
comp Omgs[N];
int r[N];
int calc(int len) {
  int limit = 1;
  while (limit < len) limit <<= 1;
  for (int i = 0; i < limit; ++i)
    r[i] = (r[i >> 1] >> 1) | ((i & 1) ? (limit >> 1) : 0);
  for (int i = 0; i < limit; ++i)
    Omgs[i] =
        (comp){std::cos(2.0 * PI * i / limit), std::sin(2.0 * PI * i / limit)};
  return limit;
}
void dft(comp *a, int limit) {
  for (int i = 0; i < limit; ++i)
    if (i < r[i]) std::swap(a[i], a[r[i]]);
  for (int len = 2, qwq = (limit >> 1); len <= limit; len <<= 1, qwq >>= 1)
    for (int pos = 0; pos < limit; pos += len) {
      comp *p(Omgs), *A(a + pos), *B(a + pos + (len >> 1));
      for (int i = 0; i < len >> 1; ++i, p += qwq) {
        comp tmp(*p * *B);
        *B = *A - tmp, *A = *A + tmp;
        ++A, ++B;
      }
    }
}
__inline__ __attribute__((always_inline)) void idft(comp *a, int limit) {
  std::reverse(a + 1, a + limit);
  dft(a, limit);
}
std::vector<int> operator*(const std::vector<int> &a,
                           const std::vector<int> &b) {
  if (a.size() <= 40u || b.size() <= 40u) {
    std::vector<int> c(((int)a.size()) + ((int)b.size()) - 1);
    for (unsigned int i = 0; i < a.size(); ++i)
      for (unsigned int j = 0; j < b.size(); ++j)
        add(c[i + j], 1ull * a[i] * b[j] % mod);
    return c.resize(maxn + 1), c;
  }
  static comp A0[N], A1[N], B0[N], B1[N];
  int tmp = ((int)a.size()) + ((int)b.size()), limit = calc(tmp);
  for (int i = 0; i < ((int)a.size()); ++i)
    A0[i] = (comp){double(a[i] & 32767), 0.0},
    A1[i] = (comp){double(a[i] >> 15), 0.0};
  for (int i = 0; i < ((int)b.size()); ++i)
    B0[i] = (comp){double(b[i] & 32767), 0.0},
    B1[i] = (comp){double(b[i] >> 15), 0.0};
  for (int i = ((int)a.size()); i < limit; ++i)
    A0[i] = A1[i] = (comp){0.0, 0.0};
  for (int i = ((int)b.size()); i < limit; ++i)
    B0[i] = B1[i] = (comp){0.0, 0.0};
  dft(A0, limit), dft(A1, limit), dft(B0, limit), dft(B1, limit);
  for (int i = 0; i < limit; ++i) {
    comp a0 = A0[i], a1 = A1[i], b0 = B0[i], b1 = B1[i];
    A0[i] = a1 * b1;
    A1[i] = a1 * b0 + a0 * b1;
    B0[i] = a0 * b0;
  }
  idft(A0, limit), idft(A1, limit), idft(B0, limit);
  std::vector<int> c(tmp - 1);
  for (int i = 0; i + 1 < tmp; ++i)
    c[i] = (((long long)(A0[i].a / (double)limit + 0.5) % mod << 30) +
            ((long long)(A1[i].a / (double)limit + 0.5) << 15) +
            (long long)(B0[i].a / (double)limit + 0.5)) %
           mod;
  return c.resize(maxn + 1), c;
}
__inline__ __attribute__((always_inline)) std::vector<int> operator*=(
    std::vector<int> &a, const std::vector<int> &b) {
  return a = a * b;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator*=(
    std::vector<int> &a, const _Tp &b) {
  for (auto &&it : a) it = 1ll * it * b % mod;
  return a;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator*(
    std::vector<int> a, const _Tp &b) {
  return a *= b;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator*(
    const _Tp &b, std::vector<int> a) {
  return a *= b;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator/=(
    std::vector<int> &a, const _Tp &b) {
  long long inv = ksm(b);
  for (auto &&it : a) it = 1ll * it * inv % mod;
  return a;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator/(
    std::vector<int> a, const _Tp &b) {
  return a /= b;
}
template <typename _Tp>
__inline__ __attribute__((always_inline)) std::vector<int> operator/(
    const _Tp &b, std::vector<int> a) {
  return a /= b;
}
std::map<int, std::vector<int> > mp[2];
int calc(const std::vector<int> &o) {
  int ans = 0;
  for (int i = 1; i < ((int)o.size()); i += 2) add(ans, o[i]);
  return ans;
}
std::vector<int> solve(int a, int p) {
  if (!a) return (std::vector<int>){0};
  if (mp[p].find(a) != mp[p].end()) return mp[p][a];
  if (a & 1) {
    std::vector<int> ans(solve(a - 1, p));
    if ((a & 1) == p)
      ans += (solve(a - 1, 0) + solve(a - 1, 1) + (std::vector<int>){1}) *
             (std::vector<int>){0, 1};
    return mp[p][a] = ans;
  } else {
    std::vector<int> ans(solve(a >> 1, p));
    ans += (solve(a >> 1, 0) + solve(a >> 1, 1) + (std::vector<int>){1}) *
           solve(a >> 1, p ^ ((a >> 1) & 1));
    return mp[p][a] = ans;
  }
}
int main() {
  read(maxn, maxa, mod);
  std::vector<int> tmp(2);
  tmp[1] = 1;
  mp[1][1] = tmp;
  tmp[1] = 0;
  mp[0][1] = tmp;
  int ans = 0;
  for (int i = 1; i <= 30; ++i) add(ans, calc(solve(maxa / (1 << i), 1)));
  printf("%d\n", ans);
  return 0;
}
