#ifndef LOCAL
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<vector>
#pragma GCC optimize("avx2")
#endif

#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;

using i128 = __int128;
using ll = long long;
using ld = long double;

template<typename T>
using orderet_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template<typename T, typename V>
using table = gp_hash_table<T, V>;

const int inf = 2e9 + 7;
const ll INF = 4e18 + 7;
const int maxn = 1e6 + 7;
const int MOD = 998244353;
#define int ll

vector<int> g[maxn];
int mark[maxn];
int two[maxn];
int ans = 0;

int dfs(int v, int root) {
    vector<int> szs;
    int sz = 0;
    for (auto to: g[v]) {
        auto sz1 = dfs(to, root);
        sz += sz1;
        szs.push_back(sz1);
    }
    if (v == root) {
        ans = two[sz + 1] - 1;
        for (auto x: szs) ans = (ans + 1 - two[x] + MOD) % MOD;
    }
    return sz + 1;
}

void solve() {
    int n, k;
    cin >> n >> k;
    int root = -1;
    for (int i = 0; i < k; ++i) {
        int x;
        cin >> x;
        mark[x] = 1;
        root = x;
    }
    for (int i = 2; i <= n; ++i) {
        int x;
        cin >> x;
        g[x].push_back(i);
    }
    dfs(root, root);
    cout << ans;
}

signed main() {
    two[0] = 1;
    for (int i = 1; i < maxn; ++i) two[i] = (two[i - 1] * 2) % MOD;
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int t = 1;
    //cin>>t;
    while (t--) solve();
}
