Language: C++

#define LOCAL

#include <map>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <functional>
#include <queue>
#include <deque>
#include <stack>

using namespace std;

// From Errichto's Youtube stream
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using int64 = long long;

/////////////////////
// Code starts here//
/////////////////////
const int MOD = 1000000007;

int N, M, K;

vector<int> inv, invfact, pow3, pow2, fact;

void add (int & a, int b) {
    a += b;
    if (a >= MOD)
        a -= MOD;
}

int mul (int a, int b) {
    return (int64)a * b % MOD;
}

int Choose (int n, int k) {
    assert(k <= n);
    if (!k) return 1;
    if (n == k) return 1;
    return mul(fact[n], mul(invfact[k], invfact[n-k])); 
}

inline int power(int a, int b) {
  int res = 1;
  while (b > 0) {
    if (b & 1) {
      res = mul(res, a);
    }
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}
 
inline int inverse(int x) {
  return power(x, MOD - 2);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> M >> K;

    N--;
    if (M > K) {
        swap(M, K);
    }

    int result = 0;

    pow3.resize(N + M + K + 2);
    pow2 = pow3;
    fact = pow3;
    invfact = pow3;

    pow3[0] = 1;
    pow2[0] = 1;
    for (int i = 1; i < pow3.size(); i++) {
        pow2[i] = mul(pow2[i - 1], 2);
        pow3[i] = mul(pow3[i - 1], 3);
    }

    fact[0] = 1;
    for (int i = 1; i < fact.size(); i++) {
        fact[i] = mul(fact[i-1], i);
    }

    invfact[N + M + K + 1] = inverse(fact[N + M + K + 1]);
    for (int i = N + M + K; i >= 0; i--) {
        invfact[i] = mul(invfact[i + 1], i + 1);
    }

    for (int m = 0; m <= M; m++) {
        for (int k = 0; k <= K; k++) {
            auto cur = Choose(m + k, k);
            cur = mul (cur, pow3[M + K - (m + k)]);
            cur = mul (cur, Choose(N + m + k, N));
            add(result, cur);
        }
    }

    // divide by N!

    cout << result << "\n";

    return 0;
}


Compiler output:
a.cc: In function 'int Choose(int, int)':
a.cc:73:5: error: 'assert' was not declared in this scope
   73 |     assert(k <= n);
      |     ^~~~~~
a.cc:18:1: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'
   17 | #include <stack>
  +++ |+#include <cassert>
   18 |