Problem: Test data generation is not an easy task! Often, generating big random test cases is not enough to ensure thorough testing of solutions for correctness.

For example, consider a problem from an old Codeforces round. Its input format looks roughly as follows:

The first line contains a single integer n (1 ≤ n ≤ maxn) — the size of the set. The second line contains n distinct integers a1, a2, ..., an (1 ≤ ai ≤ maxa) — the elements of the set in increasing order.

If you don't pay attention to the problem solution, it looks fairly easy to generate a good test case for this problem. Let n = maxn, take random distinct ai from 1 to maxa, sort them... Soon you understand that it's not that easy.

Here is the actual problem solution. Let g be the greatest common divisor of a1, a2, ..., an. Let x = an / g - n. Then the correct solution outputs "Alice" if x is odd, and "Bob" if x is even.

Consider two wrong solutions to this problem which differ from the correct one only in the formula for calculating x.

The first wrong solution calculates x as x = an / g (without subtracting n).

The second wrong solution calculates x as x = an - n (without dividing by g).

A test case is interesting if it makes both wrong solutions output an incorrect answer.

Given maxn, maxa and q, find the number of interesting test cases satisfying the constraints, and output it modulo q.

Input

The only line contains three integers maxn, maxa and q (1 ≤ maxn ≤ 30 000; maxn ≤ maxa ≤ 109; 104 ≤ q ≤ 105 + 129).

Output

Output a single integer — the number of test cases which satisfy the constraints and make both wrong solutions output an incorrect answer, modulo q.

Examples

Input

3 6 100000


Output

4


Input

6 21 100129


Output

154


Input

58 787788 50216


Output

46009

Note

In the first example, interesting test cases look as follows: 
    
    
      
    1              1              1              3  
    2              4              6              2 4 6  
    

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const long double PI = acos(-1);
int P;
int ad(int k1, int k2) { return k1 += k2 - P, k1 += k1 >> 31 & P; }
int su(int k1, int k2) { return k1 -= k2, k1 += k1 >> 31 & P; }
int mu(int k1, int k2) { return 1LL * k1 * k2 % P; }
void uad(int& k1, int k2) { k1 += k2 - P, k1 += k1 >> 31 & P; }
void usu(int& k1, int k2) { k1 -= k2, k1 += k1 >> 31 & P; }
template <typename... T>
int ad(int k1, T... k2) {
  return ad(k1, ad(k2...));
}
template <typename... T>
void uad(int& k1, T... k2) {
  return uad(k1, ad(k2...));
}
template <typename... T>
void usu(int& k1, T... k2) {
  return usu(k1, ad(k2...));
}
template <typename... T>
int mu(int k1, T... k2) {
  return mu(k1, mu(k2...));
}
int po(int k1, int k2) {
  int k3 = 1;
  for (; k2; k2 >>= 1, k1 = mu(k1, k1))
    if (k2 & 1) k3 = mu(k3, k1);
  return k3;
}
const int N = 100005;
struct cp {
  double x, y;
  cp operator+(const cp& k2) const { return (cp){x + k2.x, y + k2.y}; }
  cp operator-(const cp& k2) const { return (cp){x - k2.x, y - k2.y}; }
  cp operator*(const cp& k2) const {
    return (cp){x * k2.x - y * k2.y, x * k2.y + y * k2.x};
  }
  cp conj() { return (cp){x, -y}; }
} w[N * 2];
void fft(cp* a, int lim) {
  for (int i = 0, j = 0; i < lim; ++i) {
    if (i < j) swap(a[i], a[j]);
    for (int k = (lim >> 1); (j ^= k) < k; k >>= 1)
      ;
  }
  for (int i = 1; i < lim; i <<= 1) {
    for (int j = 0; j < lim; j += i << 1) {
      for (int k = 0; k < i; ++k) {
        cp x = a[j + k], y = w[i + k] * a[i + j + k];
        a[j + k] = x + y, a[i + j + k] = x - y;
      }
    }
  }
}
vector<int> pmul(const vector<int>& a, const vector<int>& b) {
  static cp A[N * 2], B[N * 2], dfta[N * 2], dftb[N * 2], dftc[N * 2],
      dftd[N * 2];
  int need = ((int)(a).size()) + ((int)(b).size()) - 1;
  int lim = 1;
  while (lim <= need) lim <<= 1;
  for (int j = lim >> 1; j < lim; ++j)
    w[j] = (cp){(double)cos(PI * 2 * (j - (lim >> 1)) / lim),
                (double)sin(PI * 2 * (j - (lim >> 1)) / lim)};
  for (int j = (lim >> 1) - 1; j >= 0; --j) w[j] = w[j << 1];
  for (int i = (0); i <= (((int)(a).size()) - 1); ++i)
    A[i] = (cp){double(a[i] & 32767), double(a[i] >> 15)};
  for (int i = (((int)(a).size())); i <= (lim - 1); ++i) A[i] = (cp){0., 0.};
  for (int i = (0); i <= (((int)(b).size()) - 1); ++i)
    B[i] = (cp){double(b[i] & 32767), double(b[i] >> 15)};
  for (int i = (((int)(b).size())); i <= (lim - 1); ++i) B[i] = (cp){0., 0.};
  fft(A, lim), fft(B, lim);
  for (int i = (0); i <= (lim - 1); ++i) {
    int j = (lim - i) & (lim - 1);
    static cp da, db, dc, dd;
    da = (A[i] + A[j].conj()) * (cp){0.5, 0.};
    db = (A[i] - A[j].conj()) * (cp){0., -0.5};
    dc = (B[i] + B[j].conj()) * (cp){0.5, 0};
    dd = (B[i] - B[j].conj()) * (cp){0., -0.5};
    dfta[j] = da * dc;
    dftb[j] = da * dd;
    dftc[j] = db * dc;
    dftd[j] = db * dd;
  }
  for (int i = (0); i <= (lim - 1); ++i)
    A[i] = dfta[i] + dftb[i] * (cp){0., 1.};
  for (int i = (0); i <= (lim - 1); ++i)
    B[i] = dftc[i] + dftd[i] * (cp){0., 1.};
  fft(A, lim), fft(B, lim);
  vector<int> c(need);
  for (int i = (0); i <= (need - 1); ++i) {
    int da = (long long)(A[i].x / lim + 0.5) % P;
    int db = (long long)(A[i].y / lim + 0.5) % P;
    int dc = (long long)(B[i].x / lim + 0.5) % P;
    int dd = (long long)(B[i].y / lim + 0.5) % P;
    c[i] = (da + ((long long)(db + dc) << 15) + ((long long)dd << 30)) % P;
  }
  return c;
}
vector<int> operator*(const vector<int>& a, const vector<int>& b) {
  if (((int)(a).size()) <= 100 && ((int)(b).size()) <= 100) {
    vector<int> c(((int)(a).size()) + ((int)(b).size()) - 1);
    for (int i = (0); i <= (((int)(a).size()) - 1); ++i)
      for (int j = (0); j <= (((int)(b).size()) - 1); ++j)
        uad(c[i + j], mu(a[i], b[j]));
    return c;
  }
  return pmul(a, b);
}
vector<int> operator+(vector<int> a, vector<int> b) {
  if (((int)(a).size()) < ((int)(b).size())) swap(a, b);
  for (int i = (0); i <= (((int)(b).size()) - 1); ++i) uad(a[i], b[i]);
  return a;
}
int n, lim, ans;
vector<int> F[40][2];
void sol(int cur, int lim) {
  if (lim == 1) {
    F[cur][0].assign(n + 1, 0), F[cur][1].assign(n + 1, 0);
    F[cur][1][1] = 1;
    uad(ans, 1);
    return;
  }
  sol(cur + 1, lim >> 1);
  F[cur][0] = F[cur + 1][0], F[cur][1] = F[cur + 1][1];
  for (int i = (0); i <= (1); ++i) {
    vector<int> tmp(F[cur + 1][0] + F[cur + 1][1]);
    assert(tmp[0] == 0);
    uad(tmp[0], 1);
    vector<int> res(tmp * F[cur + 1][((lim >> 1) + i) & 1]);
    res.resize(n + 1);
    for (int j = (0); j <= (n); ++j) uad(F[cur][i][j], res[j]);
  }
  if (lim & 1) {
    for (int i = (n); i >= (1); --i) {
      uad(F[cur][1][i], F[cur][0][i - 1], F[cur][1][i - 1]);
    }
    uad(F[cur][1][1], 1);
  }
  for (int i = 1; i <= n; i += 2) uad(ans, F[cur][1][i]);
}
int main() {
  scanf("%d%d%d", &n, &lim, &P);
  if (lim == 1) puts("0"), exit(0);
  sol(1, lim >> 1);
  printf("%d\n", ans);
  return 0;
}