Problem p02862 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

//	英語は 26 文字

//	common
namespace {
#define XINT_MAX LLONG_MAX
#define CAST(T, val) ((T)(val))
#define CASE(lb)                                                               \
  break;                                                                       \
  case lb:
#define CASE_CONT(lb) case lb:
#define CASE_DEF                                                               \
  break;                                                                       \
  default:
#define For(i, s) for (int i = 0, forEnd##i = CAST(int, s); i < forEnd##i; ++i)
#define ForA(i, a, s)                                                          \
  for (int i = CAST(int, a), forEnd##i = CAST(int, s); i < forEnd##i; ++i)
#define ForR(i, s) for (int i = s; i >= 0; i--)
#define ForRA(i, s, e) for (int i = s; i >= e; i--)
#define ForItr(itr, con)                                                       \
  for (auto itr = con.begin(), forEnd##itr = con.end(); itr != forEnd##itr;    \
       ++itr)
#define ForRItr(itr, con)                                                      \
  for (auto itr = con.rbegin(), forEnd##itr = con.rend(); itr != forEnd##itr;  \
       ++itr)
#define ForStr(i, str) for (int i = 0; str[i]; ++i)
#define GOTO(lb) goto lb
#define LABEL(lb)                                                              \
  lb:
#define ALL(con) (con).begin(), (con).end()

template <typename T, typename K> struct Pair {
  T fst;
  K snd;
  bool operator<(const Pair &p) const {
    if (fst != p.fst)
      return fst < p.fst;
    return snd < p.snd;
  }
  Pair() {}
  Pair(T f, T s) : fst(f), snd(s) {}
};
template <typename T, typename K>
std::istream &operator>>(std::istream &in, Pair<T, K> &p) {
  return in >> p.fst >> p.snd;
}
template <typename T, typename K, typename H> struct Trir {
  T fst;
  K snd;
  H trd;
  bool operator<(const Trir &t) const {
    if (fst != t.fst)
      return fst < t.fst;
    if (snd != t.snd)
      return snd < t.snd;
    return trd < t.trd;
  }
  Trir() {}
  Trir(T f, T s, H t) : fst(f), snd(s), trd(t) {}
};
template <typename T, typename K, typename H>
std::istream &operator>>(std::istream &in, Trir<T, K, H> &p) {
  return in >> p.fst >> p.snd >> p.trd;
}

typedef long long xint;
typedef unsigned long long uxint;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef vector<int> Vi;
typedef vector<xint> Vx;
typedef vector<double> Vd;
typedef set<int> Si;
typedef set<xint> Sx;
typedef Pair<int, int> Pii;
typedef vector<Pii> VPii;
typedef Trir<int, int, int> Tiii;
typedef vector<Pii> VTiii;

const int Ten5 = 100000;                               //	10^5
const int Ten6 = 1000000;                              //	10^6
const double EPS = 0.00000000023283064365386962890625; //	2^-32
} // namespace
//	min-max-mod
namespace {
//	合同式
class Mod {
public:
  typedef xint T; //	型
  static T N;     //	法

  Mod operator+(Mod m) const { return Mod(x + m.x); }
  Mod operator+=(Mod m) { return *this = Mod(x + m.x); }
  Mod operator-(Mod m) const { return Mod(x - m.x + N); }
  Mod operator-=(Mod m) { return *this = Mod(x - m.x + N); }
  Mod operator*(Mod m) const { return Mod(x * m.x); }
  Mod operator*=(Mod m) { return *this = Mod(x * m.x); }
  Mod operator/(
      Mod m) const { //	フェルマーの小定理より, m.x の逆元は m.x^( HOU-2 )
    const T n = N - 2;
    T v = m.x, r = x;
    for (T b = 1; b < n; b <<= 1) {
      if (n & b)
        r = r * v % N;
      v = v * v % N;
    }
    return r;
  }
  Mod operator/=(Mod m) { return *this = *this / m; }
  operator T() const { return x; }
  Mod() {}
  Mod(T v) : x(v % N) {}

private:
  T x;
};
Mod::T Mod::N = 1000 * 1000 * 1000 + 7;
//	最大値
template <typename T> class Max {
public:
  //	何回更新したか
  int cnt() const { return c; }

  //	更新したときに true を返す
  bool operator=(T v) {
    if (!c) {
      c = 1;
      x = v;
      return true;
    }
    if (x < v) {
      c++;
      x = v;
      return true;
    }
    return false;
  }

  operator T() const { return x; }
  Max() : x(0), c(0) {}
  Max(T v) : x(v), c(1) {}
  Max(const T *f, const T *l) : x(*f++), c(1) {
    while (f < l) {
      *this = *f++;
    }
  }
  Max(const T *a, int n) : x(0), c(0) { For(i, n) *this = *a++; }

private:
  T x;
  int c;
};
//	最小値
template <typename T> class Min {
public:
  //	何回更新したか
  int cnt() const { return c; }

  //	更新したときに true を返す
  bool operator=(T v) {
    if (!c) {
      c = 1;
      x = v;
      return true;
    }
    if (v < x) {
      c++;
      x = v;
      return true;
    }
    return false;
  }

  operator T() const { return x; }
  Min() : x(0), c(0) {}
  Min(T v) : x(v), c(1) {}
  Min(const T *f, const T *l) : x(*f++), c(1) {
    while (f < l) {
      *this = *f++;
    }
  }
  Min(const T *a, int n) : x(0), c(0) { For(i, n) *this = *a++; }

private:
  T x;
  int c;
};

template <typename T> Mod operator+(Mod m, T x) { return m + Mod(x); }
template <typename T> Mod operator+=(Mod &m, T x) { return m += Mod(x); }
template <typename T> Mod operator+(T x, Mod m) { return Mod(x) + m; }
template <typename T> Mod operator-(Mod m, T x) { return m - Mod(x); }
template <typename T> Mod operator-=(Mod &m, T x) { return m -= Mod(x); }
template <typename T> Mod operator-(T x, Mod m) { return Mod(x) - m; }
template <typename T> Mod operator*(Mod m, T x) { return m * Mod(x); }
template <typename T> Mod operator*=(Mod &m, T x) { return m *= Mod(x); }
template <typename T> Mod operator*(T x, Mod m) { return Mod(x) * m; }
template <typename T> Mod operator/(Mod m, T x) { return m / Mod(x); }
template <typename T> Mod operator/=(Mod &m, T x) { return m /= Mod(x); }
istream &operator>>(istream &in, Mod &m) {
  Mod::T t;
  in >> t;
  m = Mod(t);
  return in;
}
ostream &operator<<(ostream &ot, Mod m) { return ot << CAST(Mod::T, m); }
template <typename T> istream &operator>>(istream &in, Max<T> &m) {
  T t;
  in >> t;
  m = Max<T>(t);
  return in;
}
template <typename T> ostream &operator<<(ostream &ot, Max<T> m) {
  return ot << CAST(T, m);
}
template <typename T> istream &operator>>(istream &in, Min<T> &m) {
  T t;
  in >> t;
  m = Min<T>(t);
  return in;
}
template <typename T> ostream &operator<<(ostream &ot, Min<T> m) {
  return ot << CAST(T, m);
}
} // namespace
//	vec
namespace {
//	2D int Vector
class Pint {
public:
  int x, y;
  static const Pint dir[8];

  //	util
  static void setup(int width, int height, int offset = -1, bool swap = false) {
    Width = width;
    Height = height;
    Offset = offset;
    Swap = swap;
  }
  inline bool isInFld() const {
    return 0 <= x && x < Width && 0 <= y && y < Height;
  }

  //	vector
  inline double len() const { return sqrt(sq()); }
  inline double len(const Pint &p) const { return sqrt(sq(p)); }
  inline int sq() const { return x * x + y * y; }
  inline int sq(const Pint &p) const {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  }
  inline int manhattan() const { return abs(x) + abs(y); }
  inline int manhattan(const Pint &p) const {
    return abs(x - p.x) + abs(y - p.y);
  }
  inline int dot(const Pint &p) const { return x * p.x + y * p.y; }
  inline int crs(const Pint &p) const { return x * p.y - y * p.x; }

  //	opr, cst
  inline Pint operator+() { return Pint(x, y); }
  inline Pint operator-() { return Pint(-x, -y); }
  inline Pint operator+(const Pint &p) const { return Pint(x + p.x, y + p.y); }
  inline const Pint &operator+=(const Pint &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  inline Pint operator-(const Pint &p) const { return Pint(x - p.x, y - p.y); }
  inline const Pint &operator-=(const Pint &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  inline Pint operator*(const Pint &p) const { return Pint(x * p.x, y * p.y); }
  inline const Pint &operator*=(const Pint &p) {
    x *= p.x;
    y *= p.y;
    return *this;
  }
  inline Pint operator/(const Pint &p) const { return Pint(x / p.x, y / p.y); }
  inline const Pint &operator/=(const Pint &p) {
    x /= p.x;
    y /= p.y;
    return *this;
  }
  inline Pint operator*(const int k) const { return Pint(x * k, y * k); }
  inline const Pint &operator*=(const int k) {
    x *= k;
    y *= k;
    return *this;
  }
  inline Pint operator/(const int k) const { return Pint(x / k, y / k); }
  inline const Pint &operator/=(const int k) {
    x /= k;
    y /= k;
    return *this;
  }
  inline bool operator<(const Pint &p) const {
    return x == p.x ? y < p.y : x < p.x;
  }
  inline bool operator>(const Pint &p) const {
    return x == p.x ? y > p.y : x > p.x;
  }
  inline bool operator==(const Pint &p) const { return x == p.x && y == p.y; }
  inline bool operator!=(const Pint &p) const { return x != p.x || y != p.y; }
  Pint() {}
  Pint(const int x, const int y) : x(x), y(y) {}

private:
  friend istream &operator>>(istream &in, Pint &p);
  friend ostream &operator<<(ostream &out, const Pint &p);
  static int Width, Height, Offset;
  static bool Swap;
};
istream &operator>>(istream &in, Pint &p) {
  int x, y;
  in >> x >> y;
  x += Pint::Offset;
  y += Pint::Offset;
  if (Pint::Swap)
    p = Pint(y, x);
  else
    p = Pint(x, y);
  return in;
}
ostream &operator<<(ostream &out, const Pint &p) {
  return out << "( " << p.x << ", " << p.y << " )";
}
int Pint::Width, Pint::Height, Pint::Offset;
bool Pint::Swap;
const Pint Pint::dir[8] = {Pint(0, 1), Pint(1, 0),  Pint(0, -1), Pint(-1, 0),
                           Pint(1, 1), Pint(1, -1), Pint(-1, 1), Pint(-1, -1)};

//	2D double Vector
class Pdouble {
public:
  double x, y;

  //	vector
  inline double len() const { return sqrt(sq()); }
  inline double len(const Pdouble &p) const { return sqrt(sq(p)); }
  inline double sq() const { return x * x + y * y; }
  inline double sq(const Pdouble &p) const {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  }
  inline Pdouble norm(const double l = 1.0) { return *this * l / len(); }
  inline double dot(const Pdouble &p) const { return x * p.x + y * p.y; }
  inline double crs(const Pdouble &p) const { return x * p.y - y * p.x; }
  inline Pdouble proj(const Pdouble &v) const {
    const double s = v.sq();
    if (s < EPS * EPS)
      return Pdouble(0, 0);
    return v * dot(v) / s;
  }
  inline Pdouble rot(const double rad) const {
    const double c = cos(rad), s = sin(rad);
    return Pdouble(c * x - s * y, s * x + c * y);
  }

  //	opr, cst
  inline Pdouble operator+() { return Pdouble(x, y); }
  inline Pdouble operator-() { return Pdouble(-x, -y); }
  inline Pdouble operator+(const Pdouble &p) const {
    return Pdouble(x + p.x, y + p.y);
  }
  inline const Pdouble &operator+=(const Pdouble &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  inline Pdouble operator-(const Pdouble &p) const {
    return Pdouble(x - p.x, y - p.y);
  }
  inline const Pdouble &operator-=(const Pdouble &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  inline Pdouble operator*(const Pdouble &p) const {
    return Pdouble(x * p.x, y * p.y);
  }
  inline const Pdouble &operator*=(const Pdouble &p) {
    x *= p.x;
    y *= p.y;
    return *this;
  }
  inline Pdouble operator/(const Pdouble &p) const {
    return Pdouble(x / p.x, y / p.y);
  }
  inline const Pdouble &operator/=(const Pdouble &p) {
    x /= p.x;
    y /= p.y;
    return *this;
  }
  inline Pdouble operator*(const double k) const {
    return Pdouble(x * k, y * k);
  }
  inline const Pdouble &operator*=(const double k) {
    x *= k;
    y *= k;
    return *this;
  }
  inline Pdouble operator/(const double k) const {
    return Pdouble(x / k, y / k);
  }
  inline const Pdouble &operator/=(const double k) {
    x /= k;
    y /= k;
    return *this;
  }
  inline bool operator<(const Pdouble &p) const {
    return x == p.x ? y < p.y : x < p.x;
  }
  inline bool operator>(const Pdouble &p) const {
    return x == p.x ? y > p.y : x > p.x;
  }
  inline bool operator==(const Pdouble &p) const {
    return x == p.x && y == p.y;
  }
  inline bool operator!=(const Pdouble &p) const {
    return x != p.x || y != p.y;
  }
  Pdouble() {}
  Pdouble(const double x, const double y) : x(x), y(y) {}
  Pdouble(const Pint &p) : x(p.x), y(p.y) {}
};
istream &operator>>(istream &in, Pdouble &p) { return in >> p.x >> p.y; }
ostream &operator<<(ostream &out, const Pdouble &p) {
  return out << "( " << p.x << ", " << p.y << " )";
}

//	( lP, lQ ) と ( nP, nQ ) の線分の交差判定
bool CollisionLine(const Pdouble lP, const Pdouble lQ, const Pdouble nP,
                   const Pdouble nQ) {
  auto sign = [](double d) { return d < 0 ? -1 : d > 0 ? 1 : 0; };
  Pdouble v = lQ - lP;
  if (sign(v.crs(nP - lP)) == sign(v.crs(nQ - lQ)))
    return false;
  v = nQ - nP;
  return sign(v.crs(lP - nP)) * sign(v.crs(lQ - nP)) <= 0;
}
} // namespace
//	util
namespace {
//	初期化
void SpeedUpIO() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}
//	座圧 O( N log N ). x に座圧後の座標が入る
void Zaatu(int *x, int N) {
  map<int, int> map;
  For(i, N) map.insert(
      std::pair<int, int>(x[i], 0)); //	sort すると順番が維持できない
  int idx = 0;
  ForItr(itr, map) itr->second = idx++;
  For(i, N) x[i] = map[x[i]];
}
//	double 出力
void DoubleOut(double d, char c = '\n') { printf("%.12f%c", d, c); }
} // namespace

Mod C(int N, int M) {
  Mod a = 1, b = 1, c = 1;
  For(i, M) { b *= (i + 1); }
  For(i, N - M) { c *= (i + 1); }
  For(i, N) a *= (i + 1);
  return a / (b * c);
}
int main() {
  int X, Y;
  cin >> X >> Y;

  int P = 0, Q = 0;
  while (1) {
    if (X < Y) {
      X--;
      Y -= 2;
      P++;
    } else {
      X -= 2;
      Y--;
      Q++;
    }

    if (X == 0 && Y == 0)
      break;
    if (X < 0 || Y < 0) {
      cout << 0 << endl;
      return 9;
    }
  }

  cout << C(P + Q, P) << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <complex>
#include <functional>
#include <iostream>
#include <limits.h>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

//	英語は 26 文字

//	common
namespace {
#define XINT_MAX LLONG_MAX
#define CAST(T, val) ((T)(val))
#define CASE(lb)                                                               \
  break;                                                                       \
  case lb:
#define CASE_CONT(lb) case lb:
#define CASE_DEF                                                               \
  break;                                                                       \
  default:
#define For(i, s) for (int i = 0, forEnd##i = CAST(int, s); i < forEnd##i; ++i)
#define ForA(i, a, s)                                                          \
  for (int i = CAST(int, a), forEnd##i = CAST(int, s); i < forEnd##i; ++i)
#define ForR(i, s) for (int i = s; i >= 0; i--)
#define ForRA(i, s, e) for (int i = s; i >= e; i--)
#define ForItr(itr, con)                                                       \
  for (auto itr = con.begin(), forEnd##itr = con.end(); itr != forEnd##itr;    \
       ++itr)
#define ForRItr(itr, con)                                                      \
  for (auto itr = con.rbegin(), forEnd##itr = con.rend(); itr != forEnd##itr;  \
       ++itr)
#define ForStr(i, str) for (int i = 0; str[i]; ++i)
#define GOTO(lb) goto lb
#define LABEL(lb)                                                              \
  lb:
#define ALL(con) (con).begin(), (con).end()

template <typename T, typename K> struct Pair {
  T fst;
  K snd;
  bool operator<(const Pair &p) const {
    if (fst != p.fst)
      return fst < p.fst;
    return snd < p.snd;
  }
  Pair() {}
  Pair(T f, T s) : fst(f), snd(s) {}
};
template <typename T, typename K>
std::istream &operator>>(std::istream &in, Pair<T, K> &p) {
  return in >> p.fst >> p.snd;
}
template <typename T, typename K, typename H> struct Trir {
  T fst;
  K snd;
  H trd;
  bool operator<(const Trir &t) const {
    if (fst != t.fst)
      return fst < t.fst;
    if (snd != t.snd)
      return snd < t.snd;
    return trd < t.trd;
  }
  Trir() {}
  Trir(T f, T s, H t) : fst(f), snd(s), trd(t) {}
};
template <typename T, typename K, typename H>
std::istream &operator>>(std::istream &in, Trir<T, K, H> &p) {
  return in >> p.fst >> p.snd >> p.trd;
}

typedef long long xint;
typedef unsigned long long uxint;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef vector<int> Vi;
typedef vector<xint> Vx;
typedef vector<double> Vd;
typedef set<int> Si;
typedef set<xint> Sx;
typedef Pair<int, int> Pii;
typedef vector<Pii> VPii;
typedef Trir<int, int, int> Tiii;
typedef vector<Pii> VTiii;

const int Ten5 = 100000;                               //	10^5
const int Ten6 = 1000000;                              //	10^6
const double EPS = 0.00000000023283064365386962890625; //	2^-32
} // namespace
//	min-max-mod
namespace {
//	合同式
class Mod {
public:
  typedef xint T; //	型
  static T N;     //	法

  Mod operator+(Mod m) const { return Mod(x + m.x); }
  Mod operator+=(Mod m) { return *this = Mod(x + m.x); }
  Mod operator-(Mod m) const { return Mod(x - m.x + N); }
  Mod operator-=(Mod m) { return *this = Mod(x - m.x + N); }
  Mod operator*(Mod m) const { return Mod(x * m.x); }
  Mod operator*=(Mod m) { return *this = Mod(x * m.x); }
  Mod operator/(
      Mod m) const { //	フェルマーの小定理より, m.x の逆元は m.x^( HOU-2 )
    const T n = N - 2;
    T v = m.x, r = x;
    for (T b = 1; b < n; b <<= 1) {
      if (n & b)
        r = r * v % N;
      v = v * v % N;
    }
    return r;
  }
  Mod operator/=(Mod m) { return *this = *this / m; }
  operator T() const { return x; }
  Mod() {}
  Mod(T v) : x(v % N) {}

private:
  T x;
};
Mod::T Mod::N = 1000 * 1000 * 1000 + 7;
//	最大値
template <typename T> class Max {
public:
  //	何回更新したか
  int cnt() const { return c; }

  //	更新したときに true を返す
  bool operator=(T v) {
    if (!c) {
      c = 1;
      x = v;
      return true;
    }
    if (x < v) {
      c++;
      x = v;
      return true;
    }
    return false;
  }

  operator T() const { return x; }
  Max() : x(0), c(0) {}
  Max(T v) : x(v), c(1) {}
  Max(const T *f, const T *l) : x(*f++), c(1) {
    while (f < l) {
      *this = *f++;
    }
  }
  Max(const T *a, int n) : x(0), c(0) { For(i, n) *this = *a++; }

private:
  T x;
  int c;
};
//	最小値
template <typename T> class Min {
public:
  //	何回更新したか
  int cnt() const { return c; }

  //	更新したときに true を返す
  bool operator=(T v) {
    if (!c) {
      c = 1;
      x = v;
      return true;
    }
    if (v < x) {
      c++;
      x = v;
      return true;
    }
    return false;
  }

  operator T() const { return x; }
  Min() : x(0), c(0) {}
  Min(T v) : x(v), c(1) {}
  Min(const T *f, const T *l) : x(*f++), c(1) {
    while (f < l) {
      *this = *f++;
    }
  }
  Min(const T *a, int n) : x(0), c(0) { For(i, n) *this = *a++; }

private:
  T x;
  int c;
};

template <typename T> Mod operator+(Mod m, T x) { return m + Mod(x); }
template <typename T> Mod operator+=(Mod &m, T x) { return m += Mod(x); }
template <typename T> Mod operator+(T x, Mod m) { return Mod(x) + m; }
template <typename T> Mod operator-(Mod m, T x) { return m - Mod(x); }
template <typename T> Mod operator-=(Mod &m, T x) { return m -= Mod(x); }
template <typename T> Mod operator-(T x, Mod m) { return Mod(x) - m; }
template <typename T> Mod operator*(Mod m, T x) { return m * Mod(x); }
template <typename T> Mod operator*=(Mod &m, T x) { return m *= Mod(x); }
template <typename T> Mod operator*(T x, Mod m) { return Mod(x) * m; }
template <typename T> Mod operator/(Mod m, T x) { return m / Mod(x); }
template <typename T> Mod operator/=(Mod &m, T x) { return m /= Mod(x); }
istream &operator>>(istream &in, Mod &m) {
  Mod::T t;
  in >> t;
  m = Mod(t);
  return in;
}
ostream &operator<<(ostream &ot, Mod m) { return ot << CAST(Mod::T, m); }
template <typename T> istream &operator>>(istream &in, Max<T> &m) {
  T t;
  in >> t;
  m = Max<T>(t);
  return in;
}
template <typename T> ostream &operator<<(ostream &ot, Max<T> m) {
  return ot << CAST(T, m);
}
template <typename T> istream &operator>>(istream &in, Min<T> &m) {
  T t;
  in >> t;
  m = Min<T>(t);
  return in;
}
template <typename T> ostream &operator<<(ostream &ot, Min<T> m) {
  return ot << CAST(T, m);
}
} // namespace
//	vec
namespace {
//	2D int Vector
class Pint {
public:
  int x, y;
  static const Pint dir[8];

  //	util
  static void setup(int width, int height, int offset = -1, bool swap = false) {
    Width = width;
    Height = height;
    Offset = offset;
    Swap = swap;
  }
  inline bool isInFld() const {
    return 0 <= x && x < Width && 0 <= y && y < Height;
  }

  //	vector
  inline double len() const { return sqrt(sq()); }
  inline double len(const Pint &p) const { return sqrt(sq(p)); }
  inline int sq() const { return x * x + y * y; }
  inline int sq(const Pint &p) const {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  }
  inline int manhattan() const { return abs(x) + abs(y); }
  inline int manhattan(const Pint &p) const {
    return abs(x - p.x) + abs(y - p.y);
  }
  inline int dot(const Pint &p) const { return x * p.x + y * p.y; }
  inline int crs(const Pint &p) const { return x * p.y - y * p.x; }

  //	opr, cst
  inline Pint operator+() { return Pint(x, y); }
  inline Pint operator-() { return Pint(-x, -y); }
  inline Pint operator+(const Pint &p) const { return Pint(x + p.x, y + p.y); }
  inline const Pint &operator+=(const Pint &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  inline Pint operator-(const Pint &p) const { return Pint(x - p.x, y - p.y); }
  inline const Pint &operator-=(const Pint &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  inline Pint operator*(const Pint &p) const { return Pint(x * p.x, y * p.y); }
  inline const Pint &operator*=(const Pint &p) {
    x *= p.x;
    y *= p.y;
    return *this;
  }
  inline Pint operator/(const Pint &p) const { return Pint(x / p.x, y / p.y); }
  inline const Pint &operator/=(const Pint &p) {
    x /= p.x;
    y /= p.y;
    return *this;
  }
  inline Pint operator*(const int k) const { return Pint(x * k, y * k); }
  inline const Pint &operator*=(const int k) {
    x *= k;
    y *= k;
    return *this;
  }
  inline Pint operator/(const int k) const { return Pint(x / k, y / k); }
  inline const Pint &operator/=(const int k) {
    x /= k;
    y /= k;
    return *this;
  }
  inline bool operator<(const Pint &p) const {
    return x == p.x ? y < p.y : x < p.x;
  }
  inline bool operator>(const Pint &p) const {
    return x == p.x ? y > p.y : x > p.x;
  }
  inline bool operator==(const Pint &p) const { return x == p.x && y == p.y; }
  inline bool operator!=(const Pint &p) const { return x != p.x || y != p.y; }
  Pint() {}
  Pint(const int x, const int y) : x(x), y(y) {}

private:
  friend istream &operator>>(istream &in, Pint &p);
  friend ostream &operator<<(ostream &out, const Pint &p);
  static int Width, Height, Offset;
  static bool Swap;
};
istream &operator>>(istream &in, Pint &p) {
  int x, y;
  in >> x >> y;
  x += Pint::Offset;
  y += Pint::Offset;
  if (Pint::Swap)
    p = Pint(y, x);
  else
    p = Pint(x, y);
  return in;
}
ostream &operator<<(ostream &out, const Pint &p) {
  return out << "( " << p.x << ", " << p.y << " )";
}
int Pint::Width, Pint::Height, Pint::Offset;
bool Pint::Swap;
const Pint Pint::dir[8] = {Pint(0, 1), Pint(1, 0),  Pint(0, -1), Pint(-1, 0),
                           Pint(1, 1), Pint(1, -1), Pint(-1, 1), Pint(-1, -1)};

//	2D double Vector
class Pdouble {
public:
  double x, y;

  //	vector
  inline double len() const { return sqrt(sq()); }
  inline double len(const Pdouble &p) const { return sqrt(sq(p)); }
  inline double sq() const { return x * x + y * y; }
  inline double sq(const Pdouble &p) const {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  }
  inline Pdouble norm(const double l = 1.0) { return *this * l / len(); }
  inline double dot(const Pdouble &p) const { return x * p.x + y * p.y; }
  inline double crs(const Pdouble &p) const { return x * p.y - y * p.x; }
  inline Pdouble proj(const Pdouble &v) const {
    const double s = v.sq();
    if (s < EPS * EPS)
      return Pdouble(0, 0);
    return v * dot(v) / s;
  }
  inline Pdouble rot(const double rad) const {
    const double c = cos(rad), s = sin(rad);
    return Pdouble(c * x - s * y, s * x + c * y);
  }

  //	opr, cst
  inline Pdouble operator+() { return Pdouble(x, y); }
  inline Pdouble operator-() { return Pdouble(-x, -y); }
  inline Pdouble operator+(const Pdouble &p) const {
    return Pdouble(x + p.x, y + p.y);
  }
  inline const Pdouble &operator+=(const Pdouble &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  inline Pdouble operator-(const Pdouble &p) const {
    return Pdouble(x - p.x, y - p.y);
  }
  inline const Pdouble &operator-=(const Pdouble &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  inline Pdouble operator*(const Pdouble &p) const {
    return Pdouble(x * p.x, y * p.y);
  }
  inline const Pdouble &operator*=(const Pdouble &p) {
    x *= p.x;
    y *= p.y;
    return *this;
  }
  inline Pdouble operator/(const Pdouble &p) const {
    return Pdouble(x / p.x, y / p.y);
  }
  inline const Pdouble &operator/=(const Pdouble &p) {
    x /= p.x;
    y /= p.y;
    return *this;
  }
  inline Pdouble operator*(const double k) const {
    return Pdouble(x * k, y * k);
  }
  inline const Pdouble &operator*=(const double k) {
    x *= k;
    y *= k;
    return *this;
  }
  inline Pdouble operator/(const double k) const {
    return Pdouble(x / k, y / k);
  }
  inline const Pdouble &operator/=(const double k) {
    x /= k;
    y /= k;
    return *this;
  }
  inline bool operator<(const Pdouble &p) const {
    return x == p.x ? y < p.y : x < p.x;
  }
  inline bool operator>(const Pdouble &p) const {
    return x == p.x ? y > p.y : x > p.x;
  }
  inline bool operator==(const Pdouble &p) const {
    return x == p.x && y == p.y;
  }
  inline bool operator!=(const Pdouble &p) const {
    return x != p.x || y != p.y;
  }
  Pdouble() {}
  Pdouble(const double x, const double y) : x(x), y(y) {}
  Pdouble(const Pint &p) : x(p.x), y(p.y) {}
};
istream &operator>>(istream &in, Pdouble &p) { return in >> p.x >> p.y; }
ostream &operator<<(ostream &out, const Pdouble &p) {
  return out << "( " << p.x << ", " << p.y << " )";
}

//	( lP, lQ ) と ( nP, nQ ) の線分の交差判定
bool CollisionLine(const Pdouble lP, const Pdouble lQ, const Pdouble nP,
                   const Pdouble nQ) {
  auto sign = [](double d) { return d < 0 ? -1 : d > 0 ? 1 : 0; };
  Pdouble v = lQ - lP;
  if (sign(v.crs(nP - lP)) == sign(v.crs(nQ - lQ)))
    return false;
  v = nQ - nP;
  return sign(v.crs(lP - nP)) * sign(v.crs(lQ - nP)) <= 0;
}
} // namespace
//	util
namespace {
//	初期化
void SpeedUpIO() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}
//	座圧 O( N log N ). x に座圧後の座標が入る
void Zaatu(int *x, int N) {
  map<int, int> map;
  For(i, N) map.insert(
      std::pair<int, int>(x[i], 0)); //	sort すると順番が維持できない
  int idx = 0;
  ForItr(itr, map) itr->second = idx++;
  For(i, N) x[i] = map[x[i]];
}
//	double 出力
void DoubleOut(double d, char c = '\n') { printf("%.12f%c", d, c); }
} // namespace

Mod C(int N, int M) {
  Mod a = 1, b = 1, c = 1;
  For(i, M) { b *= (i + 1); }
  For(i, N - M) { c *= (i + 1); }
  For(i, N) a *= (i + 1);
  return a / (b * c);
}
int main() {
  int X, Y;
  cin >> X >> Y;

  int P = 0, Q = 0;
  while (1) {
    if (X < Y) {
      X--;
      Y -= 2;
      P++;
    } else {
      X -= 2;
      Y--;
      Q++;
    }

    if (X == 0 && Y == 0)
      break;
    if (X < 0 || Y < 0) {
      cout << 0 << endl;
      return 0;
    }
  }

  cout << C(P + Q, P) << endl;

  return 0;
}