#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
const ld eps = 1e-8;
template <class U, class V>
ostream& operator<<(ostream& out, const pair<U, V>& p) {
  return out << "(" << p.first << ", " << p.second << ")";
}
template <size_t i, class T>
ostream& print_tuple_utils(ostream& out, const T& tup) {
  if constexpr (i == tuple_size<T>::value)
    return out << ")";
  else
    return print_tuple_utils<i + 1, T>(out << (i ? ", " : "(") << get<i>(tup),
                                       tup);
}
template <class... U>
ostream& operator<<(ostream& out, const tuple<U...>& tup) {
  return print_tuple_utils<0, tuple<U...>>(out, tup);
}
template <class Con, class = decltype(begin(declval<Con>()))>
typename enable_if<!is_same<Con, string>::value, ostream&>::type operator<<(
    ostream& out, const Con& container) {
  out << "{";
  for (auto it = container.begin(); it != container.end(); ++it)
    out << (it == container.begin() ? "" : ", ") << *it;
  return out << "}";
}
template <int mod_>
struct modint {
  static constexpr int mod = mod_;
  int x;
  modint(int xx = 0) : x(xx) {}
  modint(ll xx) : x((int)(xx % mod)) {}
  friend inline modint operator+(modint u, const modint& v) { return u += v; }
  modint& operator+=(const modint& o) {
    if ((x += o.x) >= mod) x -= mod;
    return *this;
  }
  friend inline modint operator-(modint u, const modint& v) { return u -= v; }
  modint& operator-=(const modint& o) {
    if ((x -= o.x) < 0) x += mod;
    return *this;
  }
  friend inline modint operator*(modint u, const modint& v) { return u *= v; }
  modint& operator*=(const modint& o) { return *this = modint(1ll * x * o.x); }
  modint pow(ll exp) const {
    modint base = *this, ans = 1;
    for (; exp > 0; exp >>= 1, base *= base)
      if (exp & 1) ans *= base;
    return ans;
  }
  friend inline modint operator/(modint u, const modint& v) { return u /= v; }
  modint& operator/=(const modint& o) { return *this *= o.pow(mod - 2); }
  friend ostream& operator<<(ostream& out, const modint& u) {
    return out << u.x;
  }
};
using mint = modint<(int)1e9 + 7>;
const int maxn = 52;
int n;
int d[maxn];
const int maxval = maxn * 3;
mint choose[maxval][maxval];
mint fac[maxval], ifac[maxval];
void precal() {
  for (int i = (int)(0); i < (int)(maxval); ++i) {
    choose[i][0] = 1;
    for (int f = (int)(1); f < (int)(i + 1); ++f)
      choose[i][f] = choose[i - 1][f] + choose[i - 1][f - 1];
  }
  fac[0] = 1;
  for (int i = (int)(1); i < (int)(maxval); ++i) fac[i] = fac[i - 1] * i;
  ifac[maxval - 1] = 1 / fac[maxval - 1];
  for (int i = maxval; i-- > 1;) {
    ifac[i - 1] = ifac[i] * i;
  }
}
mint dp[2][maxn][maxn][maxn][maxn];
void print_dp(int l) {
  ;
  for (int p1 = (int)(0); p1 < (int)(n + 1); ++p1)
    for (int p2 = (int)(0); p2 < (int)(n + 1 - p1); ++p2)
      for (int c1 = (int)(0); c1 < (int)(n + 1 - p1 - p2); ++c1)
        for (int c2 = (int)(0); c2 < (int)(n + 1 - p1 - p2 - c1); ++c2) {
          auto cur = dp[l][p1][p2][c1][c2];
          if (!cur.x) continue;
          if (0)
            cerr << "["
                    "p1"
                    " = "
                 << (p1) << "] "
                 << "["
                    "p2"
                    " = "
                 << (p2) << "] "
                 << "["
                    "c1"
                    " = "
                 << (c1) << "] "
                 << "["
                    "c2"
                    " = "
                 << (c2) << "] "
                 << "["
                    "cur"
                    " = "
                 << (cur) << "] " << endl;
        }
}
int main() {
  precal();
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = (int)(0); i < (int)(n); ++i) cin >> d[i];
  dp[0][d[0]][0][0][0] = 1;
  for (int i = (int)(1); i < (int)(n); ++i) {
    if (0)
      cerr << "["
              "i"
              " = "
           << (i) << "] " << endl;
    print_dp(!(i & 1));
    auto& cdp = dp[i & 1];
    auto& pdp = dp[!(i & 1)];
    for (int p1 = (int)(0); p1 < (int)(n + 1); ++p1)
      for (int p2 = (int)(0); p2 < (int)(n + 1 - p1); ++p2)
        for (int c1 = (int)(0); c1 < (int)(n + 1 - p1 - p2); ++c1)
          for (int c2 = (int)(0); c2 < (int)(n + 1 - p1 - p2 - c1); ++c2) {
            auto& cur = pdp[p1][p2][c1][c2];
            if (cur.x == 0) continue;
            if (p1 == 0 and p2 == 0) pdp[c1][c2][0][0] += cur;
            auto upd = [&](int np1, int np2, int par_way) {
              if (d[i] == 2) {
                cdp[np1][np2][c1 + 1][c2] += cur * par_way;
                if (c1) cdp[np1][np2][c1 - 1][c2] += cur * c1 * par_way;
                if (c2) cdp[np1][np2][c1 + 1][c2 - 1] += cur * c2 * par_way;
              } else {
                cdp[np1][np2][c1][c2 + 1] += cur * par_way;
                if (c1) cdp[np1][np2][c1][c2] += cur * c1 * par_way;
                if (c2) cdp[np1][np2][c1 + 2][c2 - 1] += cur * c2 * par_way;
                if (c1 >= 2)
                  cdp[np1][np2][c1 - 2][c2] += cur * choose[c1][2] * par_way;
                if (c1 and c2)
                  cdp[np1][np2][c1][c2 - 1] += cur * c1 * c2 * par_way;
                if (c2 >= 2)
                  cdp[np1][np2][c1 + 2][c2 - 2] +=
                      cur * choose[c2][2] * par_way;
              }
            };
            if (p1) upd(p1 - 1, p2, p1);
            if (p2) upd(p1 + 1, p2 - 1, p2);
            cur = 0;
          }
  }
  if (0)
    cerr << "["
            "n - 1"
            " = "
         << (n - 1) << "] " << endl;
  print_dp((n - 1) & 1);
  cout << dp[(n - 1) & 1][0][0][0][0] / fac[d[0]];
  return 0;
}
