#ifndef __INTMOD_H__
#define __INTMOD_H__

/* updated: 2019-10-10 */

#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <unordered_map>
#include <vector>

template <uint32_t Mod> class IntMod {
  static_assert(Mod != 0, "Mod must not be 0");
  static_assert(Mod < 0x80000000, "Mod must be less than 0x80000000");

private:
  uint32_t value_m;

public:
  IntMod();
  IntMod(int32_t value);
  IntMod(uint32_t value);
  IntMod(int64_t value);
  IntMod(uint64_t value);

  const IntMod<Mod> &operator+() const;
  IntMod<Mod> operator-() const;
  IntMod<Mod> &operator++();
  IntMod<Mod> &operator--();
  IntMod<Mod> operator++(int dummy);
  IntMod<Mod> operator--(int dummy);
  IntMod<Mod> &operator+=(const IntMod<Mod> &right);
  IntMod<Mod> &operator-=(const IntMod<Mod> &right);
  IntMod<Mod> &operator*=(const IntMod<Mod> &right);
  IntMod<Mod> &operator/=(const IntMod<Mod> &right);
  IntMod<Mod> operator[](uint64_t exp) const;

  static IntMod<Mod> add(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> subtract(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> multiply(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> divide(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static int compare(const IntMod<Mod> &a, const IntMod<Mod> &b);

  IntMod<Mod> inverse() const;
  IntMod<Mod> power(uint64_t exp) const;
  uint32_t get() const;

  static IntMod<Mod> fact(uint32_t num);
  static IntMod<Mod> invFact(uint32_t num);
  static IntMod<Mod> combi(uint32_t n, uint32_t r);
  static IntMod<Mod> homcombi(uint32_t n, uint32_t r);
  static IntMod<Mod> perm(uint32_t n, uint32_t r);
  static std::vector<IntMod<Mod>> calcInverseList(int max);
};

template <uint32_t Mod>
IntMod<Mod> operator+(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator-(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator*(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator/(const IntMod<Mod> &a, const IntMod<Mod> &b);

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const IntMod<Mod> &a, const Int &b);

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const Int &a, const IntMod<Mod> &b);

template <uint32_t Mod>
bool operator==(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator!=(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator<(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator<=(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator>(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator>=(const IntMod<Mod> &a, const IntMod<Mod> &b);

template <uint32_t Mod, class Int>
bool operator==(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
bool operator!=(const IntMod<Mod> &a, const Int &b);

template <uint32_t Mod>
std::istream &operator>>(std::istream &ist, IntMod<Mod> &object);
template <uint32_t Mod>
std::ostream &operator<<(std::ostream &ost, const IntMod<Mod> &object);

using MInt = IntMod<1000000007>;
using MF = IntMod<998244353>;

// for unordered_set/map
namespace std {
template <uint32_t Mod> struct hash<IntMod<Mod>> {
  size_t operator()(const IntMod<Mod> &object) const {
    return std::hash<uint32_t>()(object.get());
  }
};
} // namespace std

template <uint32_t Mod>
uint32_t discreteLog(const IntMod<Mod> &a, const IntMod<Mod> &b);

/*------------------------------------*/
/*-------   Implementations   --------*/
/*------------------------------------*/

template <uint32_t Mod> IntMod<Mod>::IntMod() : value_m(0) {}

template <uint32_t Mod> IntMod<Mod>::IntMod(int32_t value) {
  int32_t tmp = value % int32_t(Mod);
  value_m = tmp >= 0 ? tmp : Mod - uint32_t(-tmp);
}

template <uint32_t Mod>
IntMod<Mod>::IntMod(uint32_t value) : value_m(value % Mod) {}

template <uint32_t Mod> IntMod<Mod>::IntMod(int64_t value) {
  int32_t tmp = value % int64_t(Mod);
  value_m = tmp >= 0 ? tmp : Mod - uint32_t(-tmp);
}

template <uint32_t Mod>
IntMod<Mod>::IntMod(uint64_t value) : value_m(value % Mod) {}

template <uint32_t Mod> const IntMod<Mod> &IntMod<Mod>::operator+() const {
  return *this;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator-() const {
  IntMod<Mod> ret;
  if (value_m == 0) {
    ret.value_m = 0;
  } else {
    ret.value_m = Mod - value_m;
  }
  return ret;
}

template <uint32_t Mod> IntMod<Mod> &IntMod<Mod>::operator++() {
  ++value_m;
  if (value_m == Mod) {
    value_m = 0;
  }
  return *this;
}

template <uint32_t Mod> IntMod<Mod> &IntMod<Mod>::operator--() {
  if (value_m == 0) {
    value_m = Mod;
  }
  --value_m;
  return *this;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator++(int dummy) {
  IntMod ret(*this);
  ++*this;
  return ret;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator--(int dummy) {
  IntMod ret(*this);
  --*this;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator+=(const IntMod<Mod> &right) {
  value_m += right.value_m; // note: value_m < 0x80000000
  if (value_m >= Mod) {
    value_m -= Mod;
  }
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator-=(const IntMod<Mod> &right) {
  if (value_m < right.value_m) {
    value_m += Mod; // note: value_m < 0x80000000
  }
  value_m -= right.value_m;
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator*=(const IntMod<Mod> &right) {
  value_m = (uint64_t(value_m) * right.value_m) % Mod;
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator/=(const IntMod<Mod> &right) {
  *this *= right.inverse();
  return *this;
}

// for power
template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::operator[](uint64_t exp) const {
  return power(exp);
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::add(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret += b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::subtract(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret -= b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::multiply(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret *= b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::divide(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret /= b;
  return ret;
}

template <uint32_t Mod>
int IntMod<Mod>::compare(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  if (a.value_m < b.value_m)
    return -1;
  if (a.value_m > b.value_m)
    return 1;
  return 0;
}

/* Mod must be a prime. */
template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::inverse() const {
  assert(value_m != 0);
  return power(Mod - 2);
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::power(uint64_t exp) const {
  IntMod<Mod> product(1);
  IntMod<Mod> factor(*this);
  while (exp > 0) {
    if (exp & 1) {
      product *= factor;
    }
    factor *= factor;
    exp >>= 1;
  }
  return product;
}

template <uint32_t Mod> uint32_t IntMod<Mod>::get() const { return value_m; }

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::fact(uint32_t num) {
  assert(num <= 0x80000000);

  static std::vector<IntMod<Mod>> table(1, 1);
  if (table.size() > num)
    return table[num];

  uint32_t old_size = table.size();
  table.resize(num + 1);
  for (uint32_t i = old_size; i <= num; ++i) {
    table[i] = table[i - 1] * i;
  }
  return table[num];
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::invFact(uint32_t num) {
  assert(num <= 0x80000000);

  static std::vector<IntMod<Mod>> table(1, 1);
  if (table.size() > num)
    return table[num];

  uint32_t old_size = table.size();
  table.resize(num + 1);
  table[num] = fact(num).inverse();
  for (uint32_t i = num; i >= old_size; --i) {
    table[i - 1] = table[i] * i;
  }
  return table[num];
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::combi(uint32_t n, uint32_t r) {
  assert(n >= r);
  return fact(n) * invFact(n - r) * invFact(r);
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::homcombi(uint32_t n, uint32_t r) {
  assert(n != 0 || r == 0);

  if (n == 0 && r == 0)
    return IntMod<Mod>(1);
  return combi(n + r - 1, r);
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::perm(uint32_t n, uint32_t r) {
  assert(n >= r);
  return fact(n) / fact(n - r);
}

template <uint32_t Mod>
std::vector<IntMod<Mod>> IntMod<Mod>::calcInverseList(int max) {
  assert(max < Mod);

  std::vector<IntMod<Mod>> table(max + 1);
  table[1] = 1;
  for (int i = 2; i <= max; ++i) {
    table[i] = (uint64_t(Mod - Mod / i) * table[Mod % i].get()) % Mod;
  }
  return table;
}

template <uint32_t Mod>
IntMod<Mod> operator+(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::add(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator-(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::subtract(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator*(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::multiply(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator/(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::divide(a, b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const IntMod<Mod> &a, const Int &b) {
  return a + IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const IntMod<Mod> &a, const Int &b) {
  return a - IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const IntMod<Mod> &a, const Int &b) {
  return a * IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const IntMod<Mod> &a, const Int &b) {
  return a / IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) + b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) - b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) * b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) / b;
}

template <uint32_t Mod>
bool operator==(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) == 0;
}

template <uint32_t Mod>
bool operator!=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) != 0;
}

template <uint32_t Mod>
bool operator<(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) < 0;
}

template <uint32_t Mod>
bool operator<=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) <= 0;
}

template <uint32_t Mod>
bool operator>(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) > 0;
}

template <uint32_t Mod>
bool operator>=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) >= 0;
}

template <uint32_t Mod, class Int>
bool operator==(const IntMod<Mod> &a, const Int &b) {
  return a == IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
bool operator!=(const IntMod<Mod> &a, const Int &b) {
  return a != IntMod<Mod>(b);
}

template <uint32_t Mod>
std::istream &operator>>(std::istream &ist, IntMod<Mod> &object) {
  uint64_t value;
  ist >> value;
  object = IntMod<Mod>(value);
  return ist;
}

template <uint32_t Mod>
std::ostream &operator<<(std::ostream &ost, const IntMod<Mod> &object) {
  ost << object.get();
  return ost;
}

#endif

#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;
using uint = uint32_t;
using LL = int64_t;
using ULL = uint64_t;
using PP = pair<LL, LL>;
template <typename T>
using PriorityQ = priority_queue<T, vector<T>, greater<T>>;
#define REP(i, a, n) for (LL i = (a), i##_max_ = (n); i < i##_max_; ++i)
#define REM(i, a, n) for (LL i = (LL)(n)-1, i##_min_ = (a); i >= i##_min_; --i)
#define FLOAT fixed << setprecision(16)
#define SPEEDUP                                                                \\
  {                                                                            \\
    cin.tie(NULL);                                                             \\
    ios::sync_with_stdio(false);                                               \\
  }
const int INF = 0x3FFFFFFF;
const LL INFLL = 0x3FFFFFFF3FFFFFFF;
const double INFD = 1.0e+308;
const double EPS = 1.0e-9;

void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
template <class T, class U>
istream &operator>>(istream &ist, pair<T, U> &right) {
  return ist >> right.first >> right.second;
}
template <class T, class U>
ostream &operator<<(ostream &ost, const pair<T, U> &right) {
  return ost << right.first << ' ' << right.second;
}
template <class T, class TCompatible, size_t N>
void Fill(T (&dest)[N], const TCompatible &val) {
  fill(dest, dest + N, val);
}
template <class T, class TCompatible, size_t M, size_t N>
void Fill(T (&dest)[M][N], const TCompatible &val) {
  for (int i = 0; i < M; ++i)
    Fill(dest[i], val);
}
template <class T> T Next() {
  T buf;
  cin >> buf;
  return buf;
}
istream &Ignore(istream &ist) {
  string s;
  ist >> s;
  return ist;
}
bool Inside(int i, int j, int h, int w) {
  return i >= 0 && i < h && j >= 0 && j < w;
}

#ifdef ONLY_MY_ENVIR
#include "Accumulator.h"
#include "Algebraic.h"
#include "BIT.h"
#include "BinaryMatrix.h"
#include "BinaryTree.h"
#include "Bipartite.h"
#include "Compressor.h"
#include "Decompositions.h"
#include "DynamicMod.h"
#include "FFT.h"
#include "Factorization.h"
#include "FlowSolver.h"
#include "Graph.h"
#include "GraphUtil.h"
#include "IntMod.h"
#include "LIS.h"
#include "LazySegmentTree.h"
#include "Math.h"
#include "MathUtil.h"
#include "Matrix.h"
#include "MinCostFlowSolver.h"
#include "MinMax.h"
#include "Numbers.h"
#include "Optimize.h"
#include "Permutation.h"
#include "Polynomial.h"
#include "Position.h"
#include "Range.h"
#include "Rational.h"
#include "SegmentTree.h"
#include "SegmentTree2D.h"
#include "Sets.h"
#include "Shortest.h"
#include "SlidingWindow.h"
#include "SpanningTree.h"
#include "StringSearching.h"
#include "SuffixArray.h"
#include "Tree.h"
#include "TreeUtil.h"
#include "UnionFind.h"
#include "Util.h"
#include "VectorUtil.h"
#endif

#ifdef __GNUC__
typedef __int128 LLL;
istream &operator>>(istream &ist, __int128 &val) {
  LL tmp;
  ist >> tmp;
  val = tmp;
  return ist;
}
ostream &operator<<(ostream &ost, __int128 val) {
  LL tmp = val;
  ost << tmp;
  return ost;
}
#endif

int N, A, B, C;
int main() {
  cin >> N >> A >> B >> C;
  if (B % 2 == 0) {
    MInt sum;
    REP(x, 0, N) {
      REP(y, 0, 2 * N) {
        if ((C - x - y) % 3 != 0)
          continue;
        int p = A - x;
        int q = x;
        int r = (C - x - y) / 3;
        int s = B / 2;
        if (p < 0)
          continue;
        if (q < 0)
          continue;
        if (r < 0)
          continue;
        sum += MInt::fact(p + q + r + s) * MInt::homcombi(s, y) /
               (MInt::fact(p) * MInt::fact(q) * MInt::fact(r) * MInt::fact(s));
      }
    }
    cout << sum << endl;
  } else {
    cout << 0 << endl;
  }
  return 0;
}

#ifndef __INTMOD_H__
#define __INTMOD_H__

/* updated: 2019-10-10 */

#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <unordered_map>
#include <vector>

template <uint32_t Mod> class IntMod {
  static_assert(Mod != 0, "Mod must not be 0");
  static_assert(Mod < 0x80000000, "Mod must be less than 0x80000000");

private:
  uint32_t value_m;

public:
  IntMod();
  IntMod(int32_t value);
  IntMod(uint32_t value);
  IntMod(int64_t value);
  IntMod(uint64_t value);

  const IntMod<Mod> &operator+() const;
  IntMod<Mod> operator-() const;
  IntMod<Mod> &operator++();
  IntMod<Mod> &operator--();
  IntMod<Mod> operator++(int dummy);
  IntMod<Mod> operator--(int dummy);
  IntMod<Mod> &operator+=(const IntMod<Mod> &right);
  IntMod<Mod> &operator-=(const IntMod<Mod> &right);
  IntMod<Mod> &operator*=(const IntMod<Mod> &right);
  IntMod<Mod> &operator/=(const IntMod<Mod> &right);
  IntMod<Mod> operator[](uint64_t exp) const;

  static IntMod<Mod> add(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> subtract(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> multiply(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static IntMod<Mod> divide(const IntMod<Mod> &a, const IntMod<Mod> &b);
  static int compare(const IntMod<Mod> &a, const IntMod<Mod> &b);

  IntMod<Mod> inverse() const;
  IntMod<Mod> power(uint64_t exp) const;
  uint32_t get() const;

  static IntMod<Mod> fact(uint32_t num);
  static IntMod<Mod> invFact(uint32_t num);
  static IntMod<Mod> combi(uint32_t n, uint32_t r);
  static IntMod<Mod> homcombi(uint32_t n, uint32_t r);
  static IntMod<Mod> perm(uint32_t n, uint32_t r);
  static std::vector<IntMod<Mod>> calcInverseList(int max);
};

template <uint32_t Mod>
IntMod<Mod> operator+(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator-(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator*(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
IntMod<Mod> operator/(const IntMod<Mod> &a, const IntMod<Mod> &b);

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const IntMod<Mod> &a, const Int &b);

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const Int &a, const IntMod<Mod> &b);
template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const Int &a, const IntMod<Mod> &b);

template <uint32_t Mod>
bool operator==(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator!=(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator<(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator<=(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator>(const IntMod<Mod> &a, const IntMod<Mod> &b);
template <uint32_t Mod>
bool operator>=(const IntMod<Mod> &a, const IntMod<Mod> &b);

template <uint32_t Mod, class Int>
bool operator==(const IntMod<Mod> &a, const Int &b);
template <uint32_t Mod, class Int>
bool operator!=(const IntMod<Mod> &a, const Int &b);

template <uint32_t Mod>
std::istream &operator>>(std::istream &ist, IntMod<Mod> &object);
template <uint32_t Mod>
std::ostream &operator<<(std::ostream &ost, const IntMod<Mod> &object);

using MInt = IntMod<1000000007>;
using MF = IntMod<998244353>;

// for unordered_set/map
namespace std {
template <uint32_t Mod> struct hash<IntMod<Mod>> {
  size_t operator()(const IntMod<Mod> &object) const {
    return std::hash<uint32_t>()(object.get());
  }
};
} // namespace std

template <uint32_t Mod>
uint32_t discreteLog(const IntMod<Mod> &a, const IntMod<Mod> &b);

/*------------------------------------*/
/*-------   Implementations   --------*/
/*------------------------------------*/

template <uint32_t Mod> IntMod<Mod>::IntMod() : value_m(0) {}

template <uint32_t Mod> IntMod<Mod>::IntMod(int32_t value) {
  int32_t tmp = value % int32_t(Mod);
  value_m = tmp >= 0 ? tmp : Mod - uint32_t(-tmp);
}

template <uint32_t Mod>
IntMod<Mod>::IntMod(uint32_t value) : value_m(value % Mod) {}

template <uint32_t Mod> IntMod<Mod>::IntMod(int64_t value) {
  int32_t tmp = value % int64_t(Mod);
  value_m = tmp >= 0 ? tmp : Mod - uint32_t(-tmp);
}

template <uint32_t Mod>
IntMod<Mod>::IntMod(uint64_t value) : value_m(value % Mod) {}

template <uint32_t Mod> const IntMod<Mod> &IntMod<Mod>::operator+() const {
  return *this;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator-() const {
  IntMod<Mod> ret;
  if (value_m == 0) {
    ret.value_m = 0;
  } else {
    ret.value_m = Mod - value_m;
  }
  return ret;
}

template <uint32_t Mod> IntMod<Mod> &IntMod<Mod>::operator++() {
  ++value_m;
  if (value_m == Mod) {
    value_m = 0;
  }
  return *this;
}

template <uint32_t Mod> IntMod<Mod> &IntMod<Mod>::operator--() {
  if (value_m == 0) {
    value_m = Mod;
  }
  --value_m;
  return *this;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator++(int dummy) {
  IntMod ret(*this);
  ++*this;
  return ret;
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::operator--(int dummy) {
  IntMod ret(*this);
  --*this;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator+=(const IntMod<Mod> &right) {
  value_m += right.value_m; // note: value_m < 0x80000000
  if (value_m >= Mod) {
    value_m -= Mod;
  }
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator-=(const IntMod<Mod> &right) {
  if (value_m < right.value_m) {
    value_m += Mod; // note: value_m < 0x80000000
  }
  value_m -= right.value_m;
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator*=(const IntMod<Mod> &right) {
  value_m = (uint64_t(value_m) * right.value_m) % Mod;
  return *this;
}

template <uint32_t Mod>
IntMod<Mod> &IntMod<Mod>::operator/=(const IntMod<Mod> &right) {
  *this *= right.inverse();
  return *this;
}

// for power
template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::operator[](uint64_t exp) const {
  return power(exp);
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::add(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret += b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::subtract(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret -= b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::multiply(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret *= b;
  return ret;
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::divide(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  IntMod<Mod> ret(a);
  ret /= b;
  return ret;
}

template <uint32_t Mod>
int IntMod<Mod>::compare(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  if (a.value_m < b.value_m)
    return -1;
  if (a.value_m > b.value_m)
    return 1;
  return 0;
}

/* Mod must be a prime. */
template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::inverse() const {
  assert(value_m != 0);
  return power(Mod - 2);
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::power(uint64_t exp) const {
  IntMod<Mod> product(1);
  IntMod<Mod> factor(*this);
  while (exp > 0) {
    if (exp & 1) {
      product *= factor;
    }
    factor *= factor;
    exp >>= 1;
  }
  return product;
}

template <uint32_t Mod> uint32_t IntMod<Mod>::get() const { return value_m; }

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::fact(uint32_t num) {
  assert(num <= 0x80000000);

  static std::vector<IntMod<Mod>> table(1, 1);
  if (table.size() > num)
    return table[num];

  uint32_t old_size = table.size();
  table.resize(num + 1);
  for (uint32_t i = old_size; i <= num; ++i) {
    table[i] = table[i - 1] * i;
  }
  return table[num];
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::invFact(uint32_t num) {
  assert(num <= 0x80000000);

  static std::vector<IntMod<Mod>> table(1, 1);
  if (table.size() > num)
    return table[num];

  uint32_t old_size = table.size();
  table.resize(num + 1);
  table[num] = fact(num).inverse();
  for (uint32_t i = num; i >= old_size; --i) {
    table[i - 1] = table[i] * i;
  }
  return table[num];
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::combi(uint32_t n, uint32_t r) {
  assert(n >= r);
  return fact(n) * invFact(n - r) * invFact(r);
}

template <uint32_t Mod>
IntMod<Mod> IntMod<Mod>::homcombi(uint32_t n, uint32_t r) {
  assert(n != 0 || r == 0);

  if (n == 0 && r == 0)
    return IntMod<Mod>(1);
  return combi(n + r - 1, r);
}

template <uint32_t Mod> IntMod<Mod> IntMod<Mod>::perm(uint32_t n, uint32_t r) {
  assert(n >= r);
  return fact(n) / fact(n - r);
}

template <uint32_t Mod>
std::vector<IntMod<Mod>> IntMod<Mod>::calcInverseList(int max) {
  assert(max < Mod);

  std::vector<IntMod<Mod>> table(max + 1);
  table[1] = 1;
  for (int i = 2; i <= max; ++i) {
    table[i] = (uint64_t(Mod - Mod / i) * table[Mod % i].get()) % Mod;
  }
  return table;
}

template <uint32_t Mod>
IntMod<Mod> operator+(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::add(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator-(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::subtract(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator*(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::multiply(a, b);
}

template <uint32_t Mod>
IntMod<Mod> operator/(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::divide(a, b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const IntMod<Mod> &a, const Int &b) {
  return a + IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const IntMod<Mod> &a, const Int &b) {
  return a - IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const IntMod<Mod> &a, const Int &b) {
  return a * IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const IntMod<Mod> &a, const Int &b) {
  return a / IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator+(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) + b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator-(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) - b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator*(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) * b;
}

template <uint32_t Mod, class Int>
IntMod<Mod> operator/(const Int &a, const IntMod<Mod> &b) {
  return IntMod<Mod>(a) / b;
}

template <uint32_t Mod>
bool operator==(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) == 0;
}

template <uint32_t Mod>
bool operator!=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) != 0;
}

template <uint32_t Mod>
bool operator<(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) < 0;
}

template <uint32_t Mod>
bool operator<=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) <= 0;
}

template <uint32_t Mod>
bool operator>(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) > 0;
}

template <uint32_t Mod>
bool operator>=(const IntMod<Mod> &a, const IntMod<Mod> &b) {
  return IntMod<Mod>::compare(a, b) >= 0;
}

template <uint32_t Mod, class Int>
bool operator==(const IntMod<Mod> &a, const Int &b) {
  return a == IntMod<Mod>(b);
}

template <uint32_t Mod, class Int>
bool operator!=(const IntMod<Mod> &a, const Int &b) {
  return a != IntMod<Mod>(b);
}

template <uint32_t Mod>
std::istream &operator>>(std::istream &ist, IntMod<Mod> &object) {
  uint64_t value;
  ist >> value;
  object = IntMod<Mod>(value);
  return ist;
}

template <uint32_t Mod>
std::ostream &operator<<(std::ostream &ost, const IntMod<Mod> &object) {
  ost << object.get();
  return ost;
}

#endif

#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;
using uint = uint32_t;
using LL = int64_t;
using ULL = uint64_t;
using PP = pair<LL, LL>;
template <typename T>
using PriorityQ = priority_queue<T, vector<T>, greater<T>>;
#define REP(i, a, n) for (LL i = (a), i##_max_ = (n); i < i##_max_; ++i)
#define REM(i, a, n) for (LL i = (LL)(n)-1, i##_min_ = (a); i >= i##_min_; --i)
#define FLOAT fixed << setprecision(16)
#define SPEEDUP                                                                \\
  {                                                                            \\
    cin.tie(NULL);                                                             \\
    ios::sync_with_stdio(false);                                               \\
  }
const int INF = 0x3FFFFFFF;
const LL INFLL = 0x3FFFFFFF3FFFFFFF;
const double INFD = 1.0e+308;
const double EPS = 1.0e-9;

void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
template <class T, class U>
istream &operator>>(istream &ist, pair<T, U> &right) {
  return ist >> right.first >> right.second;
}
template <class T, class U>
ostream &operator<<(ostream &ost, const pair<T, U> &right) {
  return ost << right.first << ' ' << right.second;
}
template <class T, class TCompatible, size_t N>
void Fill(T (&dest)[N], const TCompatible &val) {
  fill(dest, dest + N, val);
}
template <class T, class TCompatible, size_t M, size_t N>
void Fill(T (&dest)[M][N], const TCompatible &val) {
  for (int i = 0; i < M; ++i)
    Fill(dest[i], val);
}
template <class T> T Next() {
  T buf;
  cin >> buf;
  return buf;
}
istream &Ignore(istream &ist) {
  string s;
  ist >> s;
  return ist;
}
bool Inside(int i, int j, int h, int w) {
  return i >= 0 && i < h && j >= 0 && j < w;
}

#ifdef ONLY_MY_ENVIR
#include "Accumulator.h"
#include "Algebraic.h"
#include "BIT.h"
#include "BinaryMatrix.h"
#include "BinaryTree.h"
#include "Bipartite.h"
#include "Compressor.h"
#include "Decompositions.h"
#include "DynamicMod.h"
#include "FFT.h"
#include "Factorization.h"
#include "FlowSolver.h"
#include "Graph.h"
#include "GraphUtil.h"
#include "IntMod.h"
#include "LIS.h"
#include "LazySegmentTree.h"
#include "Math.h"
#include "MathUtil.h"
#include "Matrix.h"
#include "MinCostFlowSolver.h"
#include "MinMax.h"
#include "Numbers.h"
#include "Optimize.h"
#include "Permutation.h"
#include "Polynomial.h"
#include "Position.h"
#include "Range.h"
#include "Rational.h"
#include "SegmentTree.h"
#include "SegmentTree2D.h"
#include "Sets.h"
#include "Shortest.h"
#include "SlidingWindow.h"
#include "SpanningTree.h"
#include "StringSearching.h"
#include "SuffixArray.h"
#include "Tree.h"
#include "TreeUtil.h"
#include "UnionFind.h"
#include "Util.h"
#include "VectorUtil.h"
#endif

#ifdef __GNUC__
typedef __int128 LLL;
istream &operator>>(istream &ist, __int128 &val) {
  LL tmp;
  ist >> tmp;
  val = tmp;
  return ist;
}
ostream &operator<<(ostream &ost, __int128 val) {
  LL tmp = val;
  ost << tmp;
  return ost;
}
#endif

int N, A, B, C;
int main() {
  cin >> N >> A >> B >> C;
  if (B % 2 == 0) {
    MInt sum;
    REP(x, 0, N + 1) {
      REP(y, 0, 2 * N + 1) {
        if (B == 0 && y != 0)
          continue;
        if ((C - x - y) % 3 != 0)
          continue;
        int p = A - x;
        int q = x;
        int r = (C - x - y) / 3;
        int s = B / 2;
        if (p < 0)
          continue;
        if (q < 0)
          continue;
        if (r < 0)
          continue;
        sum += MInt::fact(p + q + r + s) * MInt::homcombi(s, y) /
               (MInt::fact(p) * MInt::fact(q) * MInt::fact(r) * MInt::fact(s));
      }
    }
    cout << sum << endl;
  } else {
    cout << 0 << endl;
  }
  return 0;
}


#include <bits/stdc++.h>
#define DN(en, ka) (F[en] * pot(F[ka] * F[en - ka] % Q, -1) % Q)
using namespace std;
typedef long long int ll;
const ll N = 1 << 16, Q = 1000000007;
ll n, a, b, c, res, F[N] = {1};
int pot(ll a, ll b) {
  a %= Q;
  if (b < 0)
    return pot(pot(a, -b), Q - 2);
  if (b == 0)
    return 1;
  if (b % 2 == 1)
    return ((ll)pot(a, b - 1) * a) % Q;
  ll t = pot(a, b / 2);
  return (t * t) % Q;
}
int solve(int x, int y) {
  ll t = c - a + x - 3 * y, l = F[a + y + b / 2],
     m = F[x] * F[y] % Q * F[a - x] % Q * F[b / 2] % Q,
     k = b ? DN(b / 2 + t - 1, t) : 1;
  return (c < y * 3 + a - x) ? 0 : (l * pot(m, -1) % Q * k % Q);
}
int main() {
  for (int i = 1; i < N; i++)
    F[i] = (F[i - 1] * i) % Q;
  cin >> n >> a >> b >> c;
  if (b % 2 == 1) {
    cout << "0\\n";
    return 0;
  }
  for (int i = 0; i <= a; i++)
    for (int j = 0; j <= c / 3; j++)
      res += solve(i, j);
  cout << res % Q << endl;
}

#include <bits/stdc++.h>
#define DN(en, ka) (F[en] * pot(F[ka] * F[en - ka] % Q, -1) % Q)
using namespace std;
typedef long long int ll;
const ll N = 1 << 16, Q = 1000000007;
ll n, a, b, c, res, F[N] = {1};
int pot(ll a, ll b) {
  a %= Q;
  if (b < 0)
    return pot(pot(a, -b), Q - 2);
  if (b == 0)
    return 1;
  if (b % 2 == 1)
    return ((ll)pot(a, b - 1) * a) % Q;
  ll t = pot(a, b / 2);
  return (t * t) % Q;
}
int solve(int x, int y) {
  if (b % 2 == 1 || c < y * 3 + a - x ||
      (b == 0 && ((c - a + x) % 3 != 0 || c != y * 3 + a - x)))
    return 0;
  ll t = c - a + x - 3 * y, l = F[a + y + b / 2],
     m = F[x] * F[y] % Q * F[a - x] % Q * F[b / 2] % Q,
     k = b ? DN(b / 2 + t - 1, t) : 1;
  return l * pot(m, -1) % Q * k % Q;
}
int main() {
  for (int i = 1; i < N; i++)
    F[i] = (F[i - 1] * i) % Q;
  cin >> n >> a >> b >> c;
  for (int i = 0; i <= a; i++)
    for (int j = 0; j <= c / 3; j++) {
      res += solve(i, j);
    }
  cout << res % Q << endl;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define P 1000000007
int N, A, B, C;
int co[5010][5010];
int dp[2501][5010][2];
int ans;

void up(int &x, int y) { x = (x + y) % P; }

int main() {
  cin >> N >> A >> B >> C;
  co[0][0] = 1;
  for (int i = 1; i <= 5000; i++) {
    co[i][0] = 1;
    for (int j = 1; j <= i; j++)
      co[i][j] = (co[i - 1][j] + co[i - 1][j - 1]) % P;
  }
  if (B % 2 != 0) {
    printf("0\\n");
    return 0;
  }
  dp[0][0][0] = 1;
  for (int i = 0; i <= N / 2; i++)
    for (int j = 0; j <= N; j++) {
      if (dp[i][j][1]) {
        up(dp[i][j][0], dp[i][j][1]);
        up(dp[i][j + 1][1], dp[i][j][1]);
      }
      if (dp[i][j][0]) {
        up(dp[i + 1][j][1], dp[i][j][0]);
        // up(dp[i + 1][j][0], dp[i][j][0]);
      }
    }
  // for (int i = 0; i <= N / 3; i++)
  for (int j = 0; j <= C; j++)
    if (dp[B / 2][j][0])
      for (int q = 0; j + 3 * q <= C; q++) {
        // if ((B - 2 * i) % 2 != 0)
        // 	continue;
        int aa = C - j - 3 * q, bb = q, cc = A - aa;
        // printf("?? %d %d %d %d %d\\n", i, j, aa, bb, cc);
        if (aa < 0 || cc < 0)
          continue;
        // printf("?? %d %d %d %d %d %d\\n", i, j, aa, bb, cc, dp[i][j][0]);

        int tmp = dp[B / 2][j][0];
        tmp = 1LL * tmp * co[B / 2 + aa][aa] % P;
        tmp = 1LL * tmp * co[B / 2 + aa + bb][bb] % P;
        tmp = 1LL * tmp * co[B / 2 + aa + bb + cc][cc] % P;
        // tmp = 1LL * tmp * co[i + aa + bb + cc][cc] % P;
        // tmp = 1LL * tmp * co[i + aa + bb + cc + q][q] % P;

        up(ans, tmp);
      }
  printf("%d\\n", ans);
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define P 1000000007
int N, A, B, C;
int co[5010][5010];
int dp[2511][5010][2];
int ans;

void up(int &x, int y) { x = (x + y) % P; }

int main() {
  cin >> N >> A >> B >> C;
  co[0][0] = 1;
  for (int i = 1; i <= 5000; i++) {
    co[i][0] = 1;
    for (int j = 1; j <= i; j++)
      co[i][j] = (co[i - 1][j] + co[i - 1][j - 1]) % P;
  }
  if (B % 2 != 0) {
    printf("0\\n");
    return 0;
  }
  dp[0][0][0] = 1;
  for (int i = 0; i <= N / 2; i++)
    for (int j = 0; j <= N; j++) {
      if (dp[i][j][1]) {
        up(dp[i][j][0], dp[i][j][1]);
        up(dp[i][j + 1][1], dp[i][j][1]);
      }
      if (dp[i][j][0]) {
        up(dp[i + 1][j][1], dp[i][j][0]);
        // up(dp[i + 1][j][0], dp[i][j][0]);
      }
    }
  // for (int i = 0; i <= N / 3; i++)
  for (int j = 0; j <= C; j++)
    if (dp[B / 2][j][0])
      for (int q = 0; j + 3 * q <= C; q++) {
        // if ((B - 2 * i) % 2 != 0)
        // 	continue;
        int aa = C - j - 3 * q, bb = q, cc = A - aa;
        // printf("?? %d %d %d %d %d\\n", i, j, aa, bb, cc);
        if (aa < 0 || cc < 0)
          continue;
        // printf("?? %d %d %d %d %d %d\\n", i, j, aa, bb, cc, dp[i][j][0]);

        int tmp = dp[B / 2][j][0];
        tmp = 1LL * tmp * co[B / 2 + aa][aa] % P;
        tmp = 1LL * tmp * co[B / 2 + aa + bb][bb] % P;
        tmp = 1LL * tmp * co[B / 2 + aa + bb + cc][cc] % P;
        // tmp = 1LL * tmp * co[i + aa + bb + cc][cc] % P;
        // tmp = 1LL * tmp * co[i + aa + bb + cc + q][q] % P;

        up(ans, tmp);
      }
  printf("%d\\n", ans);
}


#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \\
  do {                                                                         \\
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \\
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\\n');
}
inline int bits(int m) { return (1 << m) - 1; }
using Double = double;
const Double INF = 1e100;

int N;
LL X[15], Y[15], A[15];

Double D[15][15];
Double cst[1 << 15];
Double sum[1 << 15];
bool dp[1 << 15];

bool ok(Double mid) {
  Double need = 0;
  Double rest = 0;
  REP(i, N) {
    if (A[i] < mid) {
      need += mid - A[i];
    } else {
      rest += A[i] - mid;
    }
  }
  if (need == 0)
    return true;
  if (rest < need)
    return false;

  REP(s, 1 << N) if (s) {
    REP(i, N) if (s >> i & 1) {
      sum[s] = sum[s ^ (1 << i)] + A[i];
      break;
    }
  }

  memset(dp, 0, sizeof dp);
  dp[0] = true;
  REP(s, 1 << N) if (dp[s]) {
    int sup = bits(N) ^ s;
    for (int t = sup; t; t = (t - 1) & sup) {
      if (sum[t] - __builtin_popcount(t) * mid - cst[t] >= 0)
        dp[s | t] = true;
    }
  }

  return dp[bits(N)];
}

void MAIN() {
  scanf("%d", &N);
  REP(i, N) scanf("%lld%lld%lld", X + i, Y + i, A + i);

  REP(t, N) REP(i, N - 1) if (A[i] > A[i + 1]) {
    swap(X[i], X[i + 1]);
    swap(Y[i], Y[i + 1]);
    swap(A[i], A[i + 1]);
  }

  REP(i, N) REP(j, N) D[i][j] = hypot((Double)X[i] - X[j], (Double)Y[i] - Y[j]);
  REP(s, 1 << N) cst[s] = INF;
  REP(s, 1 << N) {
    if (__builtin_popcount(s) <= 1)
      cst[s] = 0;
    REP(i, N)
    if (s >> i & 1) REP(j, N) if (~s >> j & 1)
        amin(cst[s | 1 << j], cst[s] + D[i][j]);
  }

  Double lo = *min_element(A, A + N), hi = *max_element(A, A + N);
  REP(t, 60) {
    Double mid = (lo + hi) / 2;
    (ok(mid) ? lo : hi) = mid;
  }
  double ans = (lo + hi) / 2;
  printf("%.12f\\n", ans);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \\
  do {                                                                         \\
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \\
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\\n');
}
inline int bits(int m) { return (1 << m) - 1; }
using Double = double;
const Double INF = 1e100;

int N;
LL X[15], Y[15], A[15];

Double D[15][15];
Double cst[1 << 15];
Double sum[1 << 15];
bool dp[1 << 15];

bool ok(Double mid) {
  Double need = 0;
  Double rest = 0;
  REP(i, N) {
    if (A[i] < mid) {
      need += mid - A[i];
    } else {
      rest += A[i] - mid;
    }
  }
  if (need == 0)
    return true;
  if (rest < need)
    return false;

  REP(s, 1 << N) if (s) {
    REP(i, N) if (s >> i & 1) {
      sum[s] = sum[s ^ (1 << i)] + A[i];
      break;
    }
  }

  memset(dp, 0, sizeof dp);
  dp[0] = true;
  REP(s, 1 << N) if (dp[s]) {
    int other = bits(N) ^ s;
    int sup = other & (other - 1);
    int small = sup ^ other;
    for (int t = sup;; t = (t - 1) & sup) {
      if (sum[t | small] - __builtin_popcount(t | small) * mid -
              cst[t | small] >=
          0)
        dp[s | t | small] = true;
      if (t == 0)
        break;
    }
  }

  return dp[bits(N)];
}

void MAIN() {
  scanf("%d", &N);
  REP(i, N) scanf("%lld%lld%lld", X + i, Y + i, A + i);

  REP(t, N) REP(i, N - 1) if (A[i] > A[i + 1]) {
    swap(X[i], X[i + 1]);
    swap(Y[i], Y[i + 1]);
    swap(A[i], A[i + 1]);
  }

  REP(i, N) REP(j, N) D[i][j] = hypot((Double)X[i] - X[j], (Double)Y[i] - Y[j]);
  REP(s, 1 << N) cst[s] = INF;
  REP(s, 1 << N) {
    if (__builtin_popcount(s) <= 1)
      cst[s] = 0;
    REP(i, N)
    if (s >> i & 1) REP(j, N) if (~s >> j & 1)
        amin(cst[s | 1 << j], cst[s] + D[i][j]);
  }

  Double lo = *min_element(A, A + N), hi = *max_element(A, A + N);
  REP(t, 60) {
    Double mid = (lo + hi) / 2;
    (ok(mid) ? lo : hi) = mid;
  }
  double ans = (lo + hi) / 2;
  printf("%.12f\\n", ans);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}


#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Problem Specific Parameter:
#define error(args...)                                                         \\
  {                                                                            \\
    vector<string> _debug = split(#args, ',');                                 \\
    err(begin(_debug), args);                                                  \\
  }

vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}

void err(vector<string>::iterator it) { cerr << endl; }
template <typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << " = " << a << " ",
      err(++it, args...);
}

// Description: 素集合を管理するデータ構造
// TimeComplexity: 初期化$\\mathcal{O}(n)$ 更新$\\mathcal{O}(\\log n)$
// Verifyed: AOJ DSL_1_A

struct Union_find {
  Union_find(int n) { data.assign(n, -1); }
  int find(int x) { return (data[x] < 0) ? x : data[x] = find(data[x]); }
  void unite(int a, int b) {
    a = find(a), b = find(b);
    if (a != b) {
      if (data[a] < data[b])
        swap(a, b);
      data[a] += data[b], data[b] = a;
    }
  }
  bool same(int a, int b) { return find(a) == find(b); }
  int size(int x) { return -data[x]; }
  vector<int> data;
};

int x[15], y[15], a[15];
bool dp[1 << 15];
R cost[1 << 15];

bool check(int n, R val) {
  rep(mask, 1 << n) {
    dp[mask] = false;
    const R m = __builtin_popcountll(mask);
    R cur = 0.0;
    rep(i, n) if (mask & (1 << i)) cur += a[i];
    cur -= cost[mask] + m * val;
    if (cur >= 0.0)
      dp[mask] = true;
    // error(mask, dp[mask]);
  }

  rep(mask, 1 << n) {
    if (dp[mask])
      continue;
    for (int smask = (mask - 1) & mask; smask > 0; smask = (smask - 1) & mask) {
      const int tmask = mask ^ smask;
      if (dp[smask] and dp[tmask]) {
        dp[mask] = true;
        break;
      }
    }
  }

  return dp[(1 << n) - 1];
}

int main(void) {
  int n;
  cin >> n;

  rep(i, n) cin >> x[i] >> y[i] >> a[i];

  rep(mask, 1 << n) {
    cost[mask] = 0.0;
    using edge = tuple<R, int, int>;
    vector<edge> ary;

    rep(j, n) rep(i, j) {
      if (((mask >> i) & 1) == 0)
        continue;
      if (((mask >> j) & 1) == 0)
        continue;
      ary.push_back(edge(hypot(x[i] - x[j], y[i] - y[j]), i, j));
    }

    sort(begin(ary), end(ary));
    Union_find uf(n);

    for (auto &e : ary) {
      R w;
      int a, b;
      tie(w, a, b) = e;
      if (uf.same(a, b))
        continue;
      cost[mask] += w;
      uf.unite(a, b);
    }
    // error(mask, cost[mask]);
  }

  R low = 0.0, high = 1e10;

  rep(loop, 100) {
    const R mid = (low + high) / 2.0;
    if (check(n, mid))
      low = mid;
    else
      high = mid;
  }

  cout.precision(20);
  cout << fixed << low << endl;

  /*
  cerr << check(n, 5.5) << endl;
  cerr << check(n, 7.5) << endl;
  */

  return 0;
}

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Problem Specific Parameter:
#define error(args...)                                                         \\
  {                                                                            \\
    vector<string> _debug = split(#args, ',');                                 \\
    err(begin(_debug), args);                                                  \\
  }

vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}

void err(vector<string>::iterator it) { cerr << endl; }
template <typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << " = " << a << " ",
      err(++it, args...);
}

// Description: 素集合を管理するデータ構造
// TimeComplexity: 初期化$\\mathcal{O}(n)$ 更新$\\mathcal{O}(\\log n)$
// Verifyed: AOJ DSL_1_A

struct Union_find {
  Union_find(int n) { data.assign(n, -1); }
  int find(int x) { return (data[x] < 0) ? x : data[x] = find(data[x]); }
  void unite(int a, int b) {
    a = find(a), b = find(b);
    if (a != b) {
      if (data[a] < data[b])
        swap(a, b);
      data[a] += data[b], data[b] = a;
    }
  }
  bool same(int a, int b) { return find(a) == find(b); }
  int size(int x) { return -data[x]; }
  vector<int> data;
};

int x[15], y[15], a[15];
bool dp[1 << 15];
R cost[1 << 15];

bool check(int n, R val) {
  rep(mask, 1 << n) {
    dp[mask] = false;
    const R m = __builtin_popcountll(mask);
    R cur = 0.0;
    rep(i, n) if (mask & (1 << i)) cur += a[i];
    cur -= cost[mask] + m * val;
    if (cur >= 0.0)
      dp[mask] = true;
    // error(mask, dp[mask]);
  }

  rep(mask, 1 << n) {
    if (dp[mask])
      continue;
    for (int smask = (mask - 1) & mask;; smask = (smask - 1) & mask) {
      const int tmask = mask ^ smask;
      if (smask < tmask)
        break;

      if (dp[smask] and dp[tmask]) {
        dp[mask] = true;
        break;
      }
    }
  }

  return dp[(1 << n) - 1];
}

int main(void) {
  int n;
  cin >> n;

  rep(i, n) cin >> x[i] >> y[i] >> a[i];

  using edge = tuple<R, int, int>;
  vector<edge> ary;

  rep(j, n) rep(i, j)
      ary.push_back(edge(hypot(x[i] - x[j], y[i] - y[j]), i, j));
  sort(begin(ary), end(ary));

  rep(mask, 1 << n) {
    cost[mask] = 0.0;
    Union_find uf(n);

    for (auto &e : ary) {
      R w;
      int a, b;
      tie(w, a, b) = e;
      if (((mask >> a) & 1) == 0)
        continue;
      if (((mask >> b) & 1) == 0)
        continue;
      if (uf.same(a, b))
        continue;
      cost[mask] += w;
      uf.unite(a, b);
    }
    // error(mask, cost[mask]);
  }

  R low = 0.0, high = 1e10;

  rep(loop, 100) {
    const R mid = (low + high) / 2.0;
    if (check(n, mid))
      low = mid;
    else
      high = mid;
  }

  cout.precision(20);
  cout << fixed << low << endl;

  /*
  cerr << check(n, 5.5) << endl;
  cerr << check(n, 7.5) << endl;
  */

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 1000000007
#define rep(i, x) for (int i = 0; i < x; i++)
int n, m;
string f[205];
ll ans = 1;
bool mat[405][405];
ll c[5][5];
int gauss() {
  int cur = 0;
  for (int i = 0; i < 405; i++) {
    for (int j = cur; j < 405; j++) {
      if (mat[j][i] == true) {
        for (int k = 0; k < 405; k++)
          swap(mat[j][k], mat[cur][k]);
        goto nxt;
      }
    }
    continue;
  nxt:;
    for (int j = cur + 1; j < 405; j++) {
      if (mat[j][i] == true) {
        for (int k = 0; k < 405; k++)
          mat[j][k] ^= mat[cur][k];
      }
    }
    cur++;
  }
  return cur;
}
int main() {
  cin >> n >> m;
  rep(i, n) cin >> f[i];
  if (n % 2 == 1) {
    rep(i, m) {
      if (i > m - 1 - i)
        break;
      if (f[n / 2][i] != f[n / 2][m - 1 - i]) {
        ans = ans * 2ll % mod;
        break;
      }
    }
  }
  if (m % 2 == 1) {
    rep(i, n) {
      if (i > n - 1 - i)
        break;
      if (f[i][m / 2] != f[n - 1 - i][m / 2]) {
        ans = ans * 2ll % mod;
        break;
      }
    }
  }
  rep(i, 5) rep(j, i + 1) {
    if (j == 0 || j == i)
      c[i][j] = 1;
    else
      c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
  }
  int row = 0;
  rep(i, n / 2) rep(j, m / 2) {
    map<char, int> S;
    S[f[i][j]] += 1;
    S[f[n - 1 - i][j]] += 1;
    S[f[i][m - 1 - j]] += 1;
    S[f[n - 1 - i][m - 1 - j]] += 1;
    int cur = 0;
    ll mul = 1;
    for (map<char, int>::iterator it = S.begin(); it != S.end(); it++) {
      mul = mul * c[cur + it->second][cur];
      cur += it->second;
    }
    if (mul == 24) {
      ans = ans * 12LL % mod;
      mat[row][i] = 1;
      mat[row][j + n] = 1;
      row++;
    } else {
      ans = ans * mul % mod;
    }
  }
  int free = gauss();
  rep(i, free) ans = ans * 2LL % mod;
  cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 1000000007
#define rep(i, x) for (int i = 0; i < x; i++)
int n, m;
string f[205];
ll ans = 1;
bitset<205> mat[10005];
ll c[5][5];
int gauss() {
  int cur = 0;
  for (int i = 0; i < 205; i++) {
    for (int j = cur; j < 10005; j++) {
      if (mat[j][i] == true) {
        swap(mat[j], mat[cur]);
        goto nxt;
      }
    }
    continue;
  nxt:;
    for (int j = cur + 1; j < 10005; j++) {
      if (mat[j][i] == true) {
        mat[j] ^= mat[cur];
      }
    }
    cur++;
  }
  return cur;
}
int main() {
  cin >> n >> m;
  rep(i, n) cin >> f[i];
  if (n % 2 == 1) {
    rep(i, m) {
      if (i > m - 1 - i)
        break;
      if (f[n / 2][i] != f[n / 2][m - 1 - i]) {
        ans = ans * 2ll % mod;
        break;
      }
    }
  }
  if (m % 2 == 1) {
    rep(i, n) {
      if (i > n - 1 - i)
        break;
      if (f[i][m / 2] != f[n - 1 - i][m / 2]) {
        ans = ans * 2ll % mod;
        break;
      }
    }
  }
  rep(i, 5) rep(j, i + 1) {
    if (j == 0 || j == i)
      c[i][j] = 1;
    else
      c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
  }
  int row = 0;
  rep(i, n / 2) rep(j, m / 2) {
    map<char, int> S;
    S[f[i][j]] += 1;
    S[f[n - 1 - i][j]] += 1;
    S[f[i][m - 1 - j]] += 1;
    S[f[n - 1 - i][m - 1 - j]] += 1;
    int cur = 0;
    ll mul = 1;
    for (map<char, int>::iterator it = S.begin(); it != S.end(); it++) {
      mul = mul * c[cur + it->second][cur];
      cur += it->second;
    }
    if (mul == 24) {
      ans = ans * 12LL % mod;
      mat[row][i] = 1;
      mat[row][j + n / 2 + 2] = 1;
      row++;
    } else {
      ans = ans * mul % mod;
    }
  }
  int free = gauss();
  rep(i, free) ans = ans * 2LL % mod;
  cout << ans << endl;
}


#include <iostream>
using namespace std;
#pragma warning(disable : 4996)

int mod = 1000000007;
int prev_[100009], dp[100009], dpr[100009];
int mulr[100009];

long long Q;
long long N[1 << 18], C[1 << 18], Base[1 << 18];
long long Answer[1 << 18];

void init(int pos) {
  int lims = (pos - 2) * (pos - 1) / 2;
  int lim2 = max(1, lims);
  if (pos == 1) {
    for (int i = lims; i <= 100000; i++)
      dp[i] = 1;
  } else {
    for (int i = lims; i <= 100000; i++)
      prev_[i] = dp[i];
    for (int i = lims; i <= 100000; i++)
      dp[i] = 0;
    for (int i = lims; i <= 100000 - pos; i++)
      dp[i + pos - 1] = prev_[i];
    for (int i = lims; i <= 100000 - pos; i++) {
      dp[i + pos] += dp[i];
      if (dp[i + pos] >= mod)
        dp[i + pos] -= mod;
    }
  }
  for (int i = lims; i <= 100000; i++)
    dpr[i] = dp[i];
  for (int i = lim2; i <= 100000; i++) {
    dpr[i] += dpr[i - 1];
    if (dpr[i] >= mod)
      dpr[i] -= mod;
  }
  for (int i = lims; i <= 100000; i++)
    mulr[i] = (1LL * i * dp[i]) % mod;
  for (int i = lim2; i <= 100000; i++) {
    mulr[i] += mulr[i - 1];
    if (mulr[i] >= mod)
      mulr[i] -= mod;
  }
}

int main() {
  scanf("%lld", &Q);
  for (int i = 1; i <= Q; i++)
    scanf("%lld%lld", &N[i], &C[i]);
  for (int i = 1; i <= Q; i++)
    Base[i] = N[i] / C[i];
  for (int i = 1; i <= Q; i++) {
    if (Base[i] == 0)
      Answer[i] = N[i];
  }

  for (int gen = 1; gen <= 450; gen++) {
    init(gen);
    for (int i = 1; i <= Q; i++) {
      if (Base[i] == 0)
        continue;
      int cl = Base[i] - 2 * gen + 1;
      int cr = Base[i] - gen;
      if (cr < 0)
        continue;

      // 1 個目の計算
      long long V1 = 0;
      if (cr >= 0)
        V1 = dpr[cr];
      if (cl >= 1)
        V1 -= dpr[cl - 1];
      if (V1 < 0)
        V1 += mod;

      int S1 = 0;
      if (cr >= 0)
        S1 = mulr[cr];
      if (cl >= 1)
        S1 -= mulr[cl - 1];
      if (S1 < 0)
        S1 += mod;

      // 2 個目の計算
      int V2 = 0;
      if (cl >= 1)
        V2 = dp[cl - 1];

      int S2 = 0;
      if (cl >= 1)
        S2 = 1LL * (cl - 1 + gen) * dp[cl - 1] % mod;

      // 答えに加算
      Answer[i] += (1LL * V1 * N[i] - 1LL * S1 * C[i] + 1LL * mod * mod);
      Answer[i] += (1LL * V2 * N[i] - 1LL * S2 * C[i] + 1LL * mod * mod);
      Answer[i] %= mod; // cout << gen << ": " << V1 << " " << S1 << " " << V2
                        // << " " << S2 << " " << Answer[i] << endl;
    }
  }

  for (int i = 1; i <= Q; i++)
    printf("%lld\\n", Answer[i]);
  return 0;
}

#include <iostream>
using namespace std;
#pragma warning(disable : 4996)

int mod = 1000000007;
int prev_[100009], dp[100009], dpr[100009];
int mulr[100009];

long long Q;
long long N[1 << 18], C[1 << 18], Base[1 << 18];
long long Answer[1 << 18];

void init(int pos) {
  int lims = (pos - 2) * (pos - 1) / 2;
  int lim2 = max(1, lims);
  if (pos == 1) {
    for (int i = lims; i <= 100000; i++)
      dp[i] = 1;
  } else {
    for (int i = lims; i <= 100000; i++)
      prev_[i] = dp[i];
    for (int i = lims; i <= 100000; i++)
      dp[i] = 0;
    for (int i = lims; i <= 100000 - pos; i++)
      dp[i + pos - 1] = prev_[i];
    for (int i = lims; i <= 100000 - pos; i++) {
      dp[i + pos] += dp[i];
      if (dp[i + pos] >= mod)
        dp[i + pos] -= mod;
    }
    for (int i = 0; i < lims; i++)
      dp[i] = 0;
  }
  for (int i = lims; i <= 100000; i++)
    dpr[i] = dp[i];
  for (int i = lim2; i <= 100000; i++) {
    dpr[i] += dpr[i - 1];
    if (dpr[i] >= mod)
      dpr[i] -= mod;
  }
  for (int i = lims; i <= 100000; i++)
    mulr[i] = (1LL * i * dp[i]) % mod;
  for (int i = lim2; i <= 100000; i++) {
    mulr[i] += mulr[i - 1];
    if (mulr[i] >= mod)
      mulr[i] -= mod;
  }
}

int main() {
  scanf("%lld", &Q);
  for (int i = 1; i <= Q; i++)
    scanf("%lld%lld", &N[i], &C[i]);
  for (int i = 1; i <= Q; i++)
    Base[i] = N[i] / C[i];
  for (int i = 1; i <= Q; i++) {
    if (Base[i] == 0)
      Answer[i] = N[i];
  }

  for (int gen = 1; gen <= 450; gen++) {
    init(gen);
    int lims = gen * (gen - 1) / 2;
    for (int i = 1; i <= Q; i++) {
      if (Base[i] <= lims)
        continue;
      int cl = Base[i] - 2 * gen + 1;
      int cr = Base[i] - gen;
      if (cr < 0)
        continue;

      // 1 個目の計算
      long long V1 = 0;
      if (cr >= 0)
        V1 = dpr[cr];
      if (cl >= 1)
        V1 -= dpr[cl - 1];
      if (V1 < 0)
        V1 += mod;

      long long S1 = 0;
      if (cr >= 0)
        S1 = mulr[cr];
      if (cl >= 1)
        S1 -= mulr[cl - 1];
      if (S1 < 0)
        S1 += mod;

      // 2 個目の計算
      long long V2 = 0;
      if (cl >= 1)
        V2 = dp[cl - 1];

      long long S2 = 0;
      if (cl >= 1)
        S2 = 1LL * (cl - 1 + gen) * dp[cl - 1] % mod;

      // 答えに加算
      Answer[i] += (1LL * V1 * N[i] - 1LL * S1 * C[i] + 1LL * mod * mod);
      Answer[i] += (1LL * V2 * N[i] - 1LL * S2 * C[i] + 1LL * mod * mod);
      Answer[i] %= mod; // cout << gen << ": " << V1 << " " << S1 << " " << V2
                        // << " " << S2 << " " << Answer[i] << endl;
    }
  }

  for (int i = 1; i <= Q; i++)
    printf("%lld\\n", Answer[i]);
  return 0;
}