#pragma GCC optimize("O3")
// #include <atcoder/all>
// using namespace atcoder;
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// gp_hash_table<int, int> mapka;

using namespace std;
#define PB push_back
#define MP make_pair
#define LL long long
#define int LL
#define FOR(i,a,b) for(int i = (a); i <= (b); i++)
#define RE(i,n) FOR(i,1,n)
#define REP(i,n) FOR(i,0,(int)(n)-1)
#define R(i,n) REP(i,n)
#define VI vector<int>
#define PII pair<int,int>
#define LD long double
#define FI first
#define SE second
#define st FI
#define nd SE
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())

template<class C> void mini(C &a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C &a4, C b4) { a4 = max(a4, b4); }

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<'='<<h<<','; _dbg(sdbg+1, a...);
}

template<class T> ostream &operator<<(ostream& os, vector<T> V) {
  os << "["; for (auto vv : V) os << vv << ","; return os << "]";
}
template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
  return os << "(" << P.st << "," << P.nd << ")";
}

#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

// using mint = modint998244353;
// ostream& operator<<(ostream& out, mint m){
//   out << m.val();
//   return out;
// }

const int P = 998244353;
void add(int &a,int b){
  a += b;
  if(a >= P)
    a -= P;
}
void sub(int &a,int b){
  a -= b;
  if(a < 0)
    a += P;
}
int mul(int a,int b){
  return a * b % P;
}
int n;
int res = 0;
vector<vector<int>> dp;
vector<int> t;
void add(int x){
  int pom = t[x];
  int a = SZ(dp);
  int b = SZ(dp[0]);
  vector<vector<int>> dp2(a + 1,vector<int>(b + pom));
  R(i,a)R(j,b){
    add(dp2[i + 1][j + pom], mul(dp[i][j], i + 1));
    if(j <= pom){
      add(dp2[a - i][pom - j], mul(dp[i][j], a - i));
    }else{
      add(dp2[i][j - pom], mul(dp[i][j], a - i));
    }
  }
//   debug(dp,pom,dp2);
  swap(dp,dp2);
}
void licz(int po,int ko){
  if(po + 1 == ko){
    debug(po,dp);
    R(i,SZ(dp)){
      R(j,min(SZ(dp[0]), t[po])){
        sub(res, dp[i][j]);
      }
    }
    debug(po,t[po],res);
    return;
  }
  int m = (po + ko) / 2;
  auto pam = dp;
  for(int i = po; i < m; i++)add(i);
  licz(m,ko);
  swap(dp,pam);
  for(int i = m; i < ko; i++)add(i);
  licz(po,m);
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(11);
  cerr << fixed << setprecision(6);
  cin >> n;
  t.resize(n);
  res = 1;
  R(i,n){
    cin >> t[i];
    res = mul(res, i + 1);
  }
  debug(res);
  dp.resize(1,vector<int>(1,1));
  licz(0,n);
  cout << res << "\n";
}

#include<bits/stdc++.h>
using namespace std;
const int mod = 998244353, MAXW = 100;
int sum(int a, int b) {
	return a+b<mod?a+b:a+b-mod;
}
int cnt[101], f[10001][101], g[10001][101];
int inv[101], fact[101], invfact[101];
int main() {
	int n, tot = 0;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int w;
		cin >> w;
		++cnt[w], tot += w;
	}
	if (tot & 1) return cout << 0 << endl, 0;
	tot >>= 1;
	inv[1] = 1;
	for (int i = 2; i <= n; i++) inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;
	fact[0] = invfact[0] = 1;
	for (int i = 1; i <= n; i++) fact[i] = 1ll*fact[i-1]*i%mod;
	for (int i = 1; i <= n; i++) invfact[i] = 1ll*invfact[i-1]*inv[i]%mod;
	f[0][0] = 1;
	for (int i = 1; i <= MAXW; i++) {
		memset(g, 0, sizeof(g));
		for (int j = 0; j <= n*MAXW; j++)
			for (int k = 0; k <= n; k++) {
				if (!f[j][k]) continue;
				for (int t = 0; t <= cnt[i]; t++)
					g[j+t*i][t+k] = (g[j+t*i][t+k]+1ll*f[j][k]*invfact[t]%mod*invfact[cnt[i]-t])%mod;
			}
		memcpy(f, g, sizeof(f));
	}
	int ans = 0;
	for (int i = 0; i <= n; i++) ans = (ans + 1ll*fact[i]*fact[n-i]%mod*f[tot][i]) % mod;
	for (int i = 1; i <= MAXW; i++) ans = 1ll*ans*fact[cnt[i]]%mod;
	cout << ans << endl;
}