use std::cmp::*;
use std::io::*;
use std::ops::*;
use std::str::FromStr;
use utils::*;


pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let n = i.read::<usize>();
    let mut a = Vec::new();
    for _ in 0..n {
        a.push(i.read::<usize>());
    }
    writeln!(o, "{}", solve(&a)).unwrap();
}
fn solve(a: &[usize]) -> usize {
    let s: usize = a.iter().sum();
    let mut dp = vec![Mod::new(0); s + 1]; // dp[i] は赤の合計がiとなるパターンの数
    dp[0] = Mod::new(1);
    let mut end = 1;
    for &a in a {
        for i in (0..end).rev() {
            dp[i + a] = dp[i + a] * 2 + dp[i];
        }
        for i in (0..a).rev() {
            dp[i] *= 2;
        }
        end += a;
    }

    let count_all = Mod::new(3).pow(a.len()); // 全パターン数
    let mut count = Mod::new(0); // 赤の合計が最大(s/2より以上)の場合のパターン数
    for &c in &dp[(s + 1) / 2..] {
        count += c;
    }
    if s % 2 != 0 {
        (count_all - count * 3).0
    } else {
        // 赤と青がs/2のパターン数を計算する
        for i in dp.iter_mut() {
            *i = Mod::new(0);
        }
        dp[0] = Mod::new(1);
        end = 1;
        for &a in a {
            for i in (0..end).rev() {
                dp[i + a] += dp[i];
            }
            end = min(end + a, s / 2 + 1);
        }
        let count_same = dp[s / 2];
        (count_all + count_same * 3 - count * 3).0
    }
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        { $f:ident($($t:ident),*) } => {
            #[allow(dead_code)]
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                ($(read_next::<$t,_>(i)),*)
            }
        };
    }

    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(T1, T2) }
        fn_read! { read3(T1, T2, T3) }
        fn_read! { read4(T1, T2, T3, T4) }
        fn_read! { read5(T1, T2, T3, T4, T5) }

    }
    fn read_next<'a, T: FromStr, I: Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    #[derive(Clone, Copy)]
    pub struct Mod(pub usize);

    use std::fmt;
    impl fmt::Debug for Mod {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{:?}", self.0)
        }
    }

    const MOD_BASE: usize = 998244353;
    const MOD_INV_POW: usize = MOD_BASE - 2;

    impl Mod {
        pub fn new(n: usize) -> Self {
            Mod(n % MOD_BASE)
        }
        pub fn pow(self, mut exp: usize) -> Self {
            let mut b = self;
            let mut r = Mod(1);
            while exp != 0 {
                if exp % 2 == 1 {
                    r *= b;
                }
                exp /= 2;
                b = b * b;
            }
            r
        }
        pub fn inverse_element(self) -> Self {
            self.pow(MOD_INV_POW)
        }
    }

    macro_rules! mod_op {
        (($ot:ident, $f:ident), ($ot_a:ident, $f_a:ident), $($rhs:ty : $e:expr,)*) => {
            $(
            impl $ot<$rhs> for Mod {
                type Output = Self;

                #[inline]
                fn $f(self, rhs: $rhs) -> Self {
                    ($e)(self, rhs)
                }
            }
            impl $ot_a<$rhs> for Mod {

                #[inline]
                fn $f_a(&mut self, rhs: $rhs) {
                    *self = ($e)(*self, rhs)
                }
            }
            )*
        }
    }

    mod_op!(
        (Add, add),
        (AddAssign, add_assign),
        Mod : |l: Mod, r: Mod| Mod::new(l.0 + r.0),
        usize : |l: Mod, r: usize| l + Mod::new(r),
    );

    mod_op!(
        (Mul, mul),
        (MulAssign, mul_assign),
        Mod : |l: Mod, r: Mod| Mod::new(l.0 * r.0),
        usize : |l: Mod, r: usize| l * Mod::new(r),
    );

    mod_op!(
        (Sub, sub),
        (SubAssign, sub_assign),
        Mod : |l: Mod, r: Mod| Mod::new(MOD_BASE + l.0 - r.0),
        usize : |l: Mod, r: usize| l - Mod::new(r),
    );

    mod_op!(
        (Div, div),
        (DivAssign, div_assign),
        Mod : |l: Mod, r: Mod| l * r.inverse_element(),
        usize : |l: Mod, r: usize| l / Mod::new(r),
    );
}


Measured memory_bytes: 4352