#pragma GCC optimize ("O3")
#pragma GCC target ("tune=native")
#pragma GCC target ("avx")

#include <bits/stdc++.h>

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define UNIQUE(v) (v).erase(unique((v).begin(), (v).end()), (v).end())
template<class T> bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0; }
template<class T> bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0; }
#define INF 0x7FFFFFFF
#define LINF 0x7FFFFFFFFFFFFFFFLL
#define Yes(q) (q ? "Yes" : "No")
#define YES(q) (q ? "YES" : "NO")
#define DUMP(q) cerr << "[DEBUG] " #q ": " << (q) << " at " __FILE__ ":" << __LINE__ << endl
#define DUMPALL(q) cerr << "[DEBUG] " #q ": ["; REP(dumpall_i, (q).size()) { cerr << q[dumpall_i] << (dumpall_i == (q).size() - 1 ? "" : ", "); } cerr << "] at " __FILE__ ":" << __LINE__ << endl

// gcc拡張マクロ
#define gcd __gcd
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// エイリアス
using  ll = long long;
using ull = unsigned long long;
using  ld = long double;
using namespace std;

// モジュール
// 剰余演算
constexpr ll p = 998244353LL;
ll powll(ll a, ll n) { // a^n mod p
    if (n == 0) {
        return 1LL;
    } else if (n == 1) {
        return a % p;
    } else {
        ll temp = powll(a, n/2);
        temp *= temp;
        temp %= p;
        if (n % 2) {
            temp *= a;
            temp %= p;
        }
        return temp;
    }
}

ll invll(ll a) { // a^p == a, so a^(p-2) == a^(-1) if a != 0 mod p, O(loga)
    return powll(a, p-2);
}

vector<ll> fac_cache = {1}, invfac_cache = {1};
void make_fac_cache(ll a) { // prepare for 1! ~ a! by O(aloga). execute this at the beginning
    ll old_size = fac_cache.size();
    if (a >= old_size) {
        fac_cache   .resize(a+1);
        invfac_cache.resize(a+1);
        for (ll i = old_size; i <= a; i++) {
               fac_cache[i] = fac_cache[i-1] * i % p;
            invfac_cache[i] = invll(fac_cache[i]);
        }
    }
}
ll facll(ll a) { // a!
    make_fac_cache(a);
    return fac_cache[a];
}
ll invfacll(ll a) { // (a!)^(-1)
    make_fac_cache(a);
    return invfac_cache[a];
}
ll nCr(ll n, ll r) {
    if (n < 0 || r < 0 || n < r) return 0;
    return facll(n) * invfacll(n-r) % p * invfacll(r) % p;
}
ll nPr(ll n, ll r) {
    if (n < 0 || r < 0 || n < r) return 0;
    return facll(n) * invfacll(r) % p;
}

// 処理内容
int main() {
    
    ll n;
    cin >> n;
    vector<ll> a(n), s(n+1, 0);
    REP(i, n) {
        cin >> a[i];
        s[i+1] = s[i] + a[i];
    }

    constexpr ll maxa = 300;
    // dp[i][M] := i個目まで見て M==max{R,G,B}な塗り方
    vector<vector<ll>> dp(n+1, vector<ll>(s[n] + 1, 0));
    // dq[i][M] := i個目まで見て M==max{R,G,B} かつ min{R,G,B}==0 な塗り方
    vector<vector<ll>> dq(n+1, vector<ll>(s[n] + 1, 0));
    dp[0][0] = 1LL;
    dq[0][0] = 1LL;
    REP(i, n) {
        REP(m, s[n]+1) {
            // max色を塗った
            if (m + a[i] <= s[n]) {
                dp[i+1][m + a[i]] += dp[i][m] % p;
                dp[i+1][m + a[i]] %= p;
                dq[i+1][m + a[i]] += dq[i][m] % p;
                dq[i+1][m + a[i]] %= p;
            }
            // max色でないものを塗った
            dp[i+1][m] += dp[i][m] * 2 % p;
            dp[i+1][m] %= p;
            dq[i+1][m] += dq[i][m] % p;
            dq[i+1][m] %= p;
        }
    }

    ll ans = 0, anq = 0;
    RANGE(m, (s[n] + 1) / 2, s[n]) {
        ans += dp[n][m];
        ans %= p;
    }
    if (s[n] % 2 == 0) {
        anq += dq[n][s[n]/2];
        anq %= p;
    }
    cout << (powll(3LL, n) - (ans - anq) * 3 + p * 4) % p << endl;
    
}

Measured memory_bytes: 423744