Problem p02862 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

template <long long mod> class modint {
private:
  long long a;

public:
  constexpr modint(const long long x = 0) noexcept : a(x % mod) {}
  constexpr long long &value() noexcept { return a; }
  constexpr const long long &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= mod)
      a -= mod;
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a)
      a += mod;
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % mod;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    long long k = mod - 2;
    while (k > 0) {
      if (k & 1) {
        *this *= rhs;
      }
      rhs *= rhs;
      k /= 2;
    }
    return *this;
  }
  friend ostream &operator<<(ostream &os, const modint &X) { return os << X.a; }
  friend istream &operator>>(istream &is, modint &X) {
    is >> X.a;
    X.a %= mod;
    if (X.a < 0)
      X.a += mod;
    return is;
  }
};

template <typename T> struct Combination {
private:
  int sz;
  vector<T> F, F_;

public:
  Combination(int sz) : sz(sz), F(sz + 1), F_(sz + 1) {
    F[0] = 1;
    for (int i = 0; i < sz; ++i)
      F[i + 1] = F[i] * (i + 1);
    F_.back() = (T)1 / F.back();
    for (int i = sz - 1; i >= 0; --i)
      F_[i] = F_[i + 1] * (i + 1);
  }
  T C(int n, int k) {
    assert(n <= sz);
    if (n < 0 or k > n)
      return (T)0;
    return F[n] * F_[k] * F_[n - k];
  }
};

int main() {
  using mint = modint<(int)1e9 + 7>;
  Combination<mint> comb((int)1e6);
  int X, Y;
  cin >> X >> Y;
  int s = (2 * Y - X) / 3, t = (2 * X - Y) / 3;
  if (s + 2 * t != X or 2 * s + t != Y) {
    cout << 0 << endl;
    return 0;
  }
  cout << comb.C(s + t, s) << endl;
}


Fixed submission:
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

template <long long mod> class modint {
private:
  long long a;

public:
  constexpr modint(const long long x = 0) noexcept : a(x % mod) {}
  constexpr long long &value() noexcept { return a; }
  constexpr const long long &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= mod)
      a -= mod;
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a)
      a += mod;
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % mod;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    long long k = mod - 2;
    while (k > 0) {
      if (k & 1) {
        *this *= rhs;
      }
      rhs *= rhs;
      k /= 2;
    }
    return *this;
  }
  friend ostream &operator<<(ostream &os, const modint &X) { return os << X.a; }
  friend istream &operator>>(istream &is, modint &X) {
    is >> X.a;
    X.a %= mod;
    if (X.a < 0)
      X.a += mod;
    return is;
  }
};

template <typename T> struct Combination {
private:
  int sz;
  vector<T> F, F_;

public:
  Combination(int sz) : sz(sz), F(sz + 1), F_(sz + 1) {
    F[0] = 1;
    for (int i = 0; i < sz; ++i)
      F[i + 1] = F[i] * (i + 1);
    F_.back() = (T)1 / F.back();
    for (int i = sz - 1; i >= 0; --i)
      F_[i] = F_[i + 1] * (i + 1);
  }
  T C(int n, int k) {
    assert(n <= sz);
    if (n < 0 or k > n)
      return (T)0;
    return F[n] * F_[k] * F_[n - k];
  }
};

int main() {
  using mint = modint<(int)1e9 + 7>;
  Combination<mint> comb((int)1e6);
  int X, Y;
  cin >> X >> Y;
  int s = (2 * Y - X) / 3, t = (2 * X - Y) / 3;
  if (s + 2 * t != X or 2 * s + t != Y or s < 0 or t < 0) {
    cout << 0 << endl;
    return 0;
  }
  cout << comb.C(s + t, s) << endl;
}