#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace chrono;

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template<typename T, typename Cmp = less<T>>
using ordered_set = __gnu_pbds::tree<T, __gnu_pbds::null_type, Cmp,
__gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template<typename T>
inline int sz(const T& x) {
    return (int)x.size();
}

const int MAXN = 1e6;
const int INF = 2e9;
const int ALPH = 26;
const int MAXLOG = 20;
const ll MOD = 998244353;
const ld EPS = 1e-8;

const ull SEED = steady_clock::now().time_since_epoch().count();
mt19937_64 rnd(67);

vector<int> g[MAXN];

ll binpow(ll x, ll p) {
    ll res = 1;
    while (p) {
        if (p & 1) {
            res = (res * x) % MOD;
        }
        x = (x * x) % MOD;
        p >>= 1;
    }
    return res;
}

int DFS(int v, int floor) {
    int subtree = 1;
    vector<int> children_subtrees;
    for (auto to : g[v]) {
        int child_subtree = DFS(to, floor);
        subtree += child_subtree;
        children_subtrees.emplace_back(child_subtree);
    }
    if (v == floor) {
        ll ans = ((binpow(2, subtree) + sz(g[v]) - 1) % MOD + MOD) % MOD;
        for (auto child_subtree : children_subtrees) {
            ans = ((ans - binpow(2, child_subtree)) % MOD + MOD) % MOD;
        }
        cout << ans;
        exit(0);
    }
    return subtree;
}

void solve() {
    int n, k, floor;
    cin >> n >> k >> floor; floor--;
    for (int v = 1; v < n; v++) {
        int p;
        cin >> p; p--;
        g[p].emplace_back(v);
    }
    DFS(0, floor);
}

int main() {
    #ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int test_cases = 1;
    // cin >> test_cases;
    while (test_cases--) solve();
    return 0;
}
