#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;
    vector<vector<int>> children(n);
    vector<int> par(n);
    par[0] = -1;

    for (int i = 1; i < n; i++){
        int p;
        cin >> p;
        p--;
        par[i] = p;
        children[p].push_back(i);
    }

    auto dfs = [&](auto v, auto dfs) -> array<int, 2>{
        vector<array<int, 2>> A;
        for (auto &c : children[v]){
            A.push_back(dfs(c, dfs));
        }

        sort(A.begin(), A.end());
        array<int, 2> res = {1, 0};
        for (const auto &[s, p]: A){
            if (s <= 0 and p == 0)
                res[0] += s;
        }

        int b = 0;
        for (const auto &[s, p]: A){
            if (p == 1){
                if (b == 0)
                    res[0] += s;
                else
                    res[0] -= s;
                b ^= 1;
            }
        }

        for (const auto &[s, p]: A){
            if (s > 0 and p == 0){
                if (b == 0)
                    res[0] += s;
                else
                    res[0] -= s;
            }
        }

        b ^= 1;
        res[1] = b;
        return res;
    };

    auto res = dfs(0, dfs);
    cout << (res[0] + n) / 2 << endl;
}
/*input
20
2 8 4 7 5 3 1 2 4 1 2 5 4 3 3 8 1 7 8 2

*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef tree<long long,null_type,less_equal<long long>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
#pragma GCC optimize("O2","unroll-loops","no-stack-protector")
//order_of_key #of elements less than x
// find_by_order kth element
using ll=long long;
using ld=long double;
using pii=pair<ld,ld>;
#define f first
#define s second
#define pb push_back
#define REP(i,n) for(ll i=0;i<n;i++)
#define REP1(i,n) for(ll i=1;i<=n;i++)
#define FILL(n,x) memset(n,x,sizeof(n))
#define ALL(_a) _a.begin(),_a.end()
#define sz(x) (int)x.size()
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()),c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
const ll INF64=1e18+1;
const int INF=0x3f3f3f3f;
const ll MOD=998244353;
const ld PI=acos(-1);
const ld eps=1e-3;
#define lowb(x) x&(-x)
#define MNTO(x,y) x=min(x,(__typeof__(x))y)
#define MXTO(x,y) x=max(x,(__typeof__(x))y)
inline ll mult(ll a,ll b){
    if(a>=MOD) a%=MOD;
    if(b>=MOD) b%=MOD;
    return (a*b)%MOD;
}
inline ll mypow(ll a,ll b){
    if(b<=0) return 1;
    ll res=1LL;
    while(b){
        if(b&1) res=mult(res,a);
        a=mult(a,a);
        b>>=1;
    }
    return res;
}
const int maxn=1e4+5;
const int maxlg=__lg(maxn)+2;
int dp[105][maxn];
ll fac[maxn];
int32_t main(){
    ios::sync_with_stdio(false),cin.tie(0);
    int n;
    cin>>n;
    int s=0;
    fac[0]=1;
    REP1(i,n) fac[i]=mult(fac[i-1],i);
    dp[0][0]=1;
    REP(i,n){
        int w;
        cin>>w;
        s+=w;
        for(int z=n;z>=1;z--){
            for(int j=maxn-1;j>=w;j--){
                dp[z][j]+=dp[z-1][j-w];
                dp[z][j]%=MOD;
            }
        }
    }
    if(s%2) cout<<0;
    else{
        ll ans=0;
        REP1(i,n){
            ans+=mult(mult(fac[i],fac[n-i]),dp[i][s/2]);
            ans%=MOD;   
        }
        cout<<ans;
    }
}