#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bits/stdc++.h>

using namespace __gnu_pbds;
using namespace std;

using ll = long long;
using ld = long double;

typedef tree<
        int,
        null_type,
        less<int>,
        rb_tree_tag,
        tree_order_statistics_node_update>
        ordered_set;

#define mp make_pair


const int MOD =  998244353;

int mul(int a, int b) {
    return (1LL * a * b) % MOD;
}

int add(int a, int b) {
    int s = (a+b);
    if (s>=MOD) s-=MOD;
    return s;
}

int sub(int a, int b) {
    int s = (a+MOD-b);
    if (s>=MOD) s-=MOD;
    return s;
}

int po(int a, ll deg)
{
    if (deg==0) return 1;
    if (deg%2==1) return mul(a, po(a, deg-1));
    int t = po(a, deg/2);
    return mul(t, t);
}

int inv(int n)
{
    return po(n, MOD-2);
}


mt19937 rnd(time(0));


const int LIM = 3e5 + 5;

vector<int> facs(LIM), invfacs(LIM);

void init()
{
    facs[0] = 1;
    for (int i = 1; i<LIM; i++) facs[i] = mul(facs[i-1], i);
    invfacs[LIM-1] = inv(facs[LIM-1]);
    for (int i = LIM-2; i>=0; i--) invfacs[i] = mul(invfacs[i+1], i+1);
}

int C(int n, int k)
{
    if (n<k) return 0;
    if (n<0 || k<0) return 0;
    return mul(facs[n], mul(invfacs[k], invfacs[n-k]));
}


/*struct DSU
{
    vector<int> sz;
    vector<int> parent;
    void make_set(int v) {
        parent[v] = v;
        sz[v] = 1;
    }

    int find_set(int v) {
        if (v == parent[v])
            return v;
        return find_set(parent[v]);
    }

    void union_sets(int a, int b) {
        find_set(a);
        find_set(b);

        a = find_set(a);
        b = find_set(b);

        if (a != b) {
            if (sz[a] < sz[b])
                swap(a, b);
            parent[b] = a;
            sz[a] += sz[b];
        };
    }

    DSU (int n)
    {
        parent.resize(n);
        sz.resize(n);
        for (int i = 0; i<n; i++) make_set(i);
    }
};*/

/*

 dp[cnt][sum][xor]

 Bit dp


 */

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);

    init();

    int n, m; cin>>n>>m;

    vector<int> dp(m+1);

    dp[0] = 1;
    for (int sum = 2; sum<=m; sum+=2)
    {
        for (int odd = 0; odd<=min(n, sum); odd+=2)
        {
            dp[sum] = add(dp[sum], mul(C(n, odd), dp[(sum-odd)/2]));
        }
    }
    cout<<dp[m];






}

#include<bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(),(a).end()
#define SZ(a) (int)(a).size()
#define FOR(i, a, b) for(int i=(a); i<=(b); ++i)
#define ROF(i, a, b) for(int i=(a); i>=(b); --i)
#define make_unique(a) sort(all((a))), (a).resize(unique(all((a)))-(a).begin())
#define pc(x) putchar(x)
#define make_pair MP
#define make_tuple MT

using namespace std;

typedef long long i64;
typedef tuple<int,int,int> iii;
typedef pair<int,int> pii;
typedef pair<i64, i64> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;

void solve(){
    int n;
    scanf("%d",&n);
    vi nxt(n+1);
    FOR(i, 1, n) scanf("%d",&nxt[i]);
    vi visit(n+1), onstack(n+1);
    stack<int> stk;
    int cnt = 0;
    FOR(i, 1, n){
        if(visit[i]) continue;
        int nw = i;
        while(1){
            visit[nw] = 1;
            onstack[nw] = 1;
            stk.push(nw);
            if(visit[nxt[nw]]){
                if(onstack[nxt[nw]]) ++cnt;
                while(!stk.empty()){
                    onstack[stk.top()] = 0;
                    stk.pop();
                }
                break;
            }else{
                nw = nxt[nw];
            }
        }
    }
    int ans = 1;
    int mod = 998244353;
    FOR(i, 1, cnt) ans = (ans+ans >= mod) ? ans+ans-mod : ans+ans;
    printf("%d",(ans-1+mod)%mod);
}

int main(){
    solve();
	return 0;
}
/*
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */