#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

using namespace std;

typedef long long ll;

#define MOD 998244353

struct UnionFind {
  vector<int> data;
  void init(int n) { data.assign(n, -1); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  bool same(int x, int y) { return root(x) == root(y); }
  bool unite(int x, int y) {
    x = root(x), y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  int size(int x) { return -data[root(x)]; }
};

// x^n
ll mod_pow(ll x, ll n) {
  if (n == 0) return 1;
  ll res = mod_pow(x * x % MOD, n / 2);
  if (n & 1) res = res * x % MOD;
  return res;
}

// x^{-1}
ll mod_inv(ll x) { return mod_pow(x, MOD - 2); }

int main() {
  int n;
  cin >> n;
  UnionFind uf;
  uf.init(n);
  for (int i = 0; i < n; ++i) {
    int f;
    cin >> f;
    f--;
    uf.unite(i, f);
  }
  set<int> st;
  for (int i = 0; i < n; ++i) {
    st.insert(uf.root(i));
  }
  ll ans = mod_pow(2, (ll)st.size());
  ans = (ans - 1 + MOD) % MOD;
  cout << ans << endl;
  return 0;
}


/**
 * Dont raise your voice, improve your argument.
 * --Desmond Tutu
 */
#include <bits/stdc++.h>
using namespace std;

const bool ready = [](){
    ios_base::sync_with_stdio(false); cin.tie(0);
    cout << fixed << setprecision(12);
    return true;
}();

using ld=long double;
const ld PI = acos((ld)-1);
using ll= long long;
#define int ll
#define all(v) (v).begin(), (v).end()
#define fori(n) for(int i=0; i<int(n); i++)

#define cini(i) int i; cin>>i;
#define cins(s) string s; cin>>s;
#define cind(d) ld d; cin>>d;
#define cinai(a,n) vi a(n); fori(n) { cin>>a[i]; }
#define cinas(s,n) vs s(n); fori(n) { cin>>s[i]; }
#define cinad(a,n) vd a(n); fori(n) { cin>>a[i]; }

using pii= pair<int, int>;
using pdd= pair<ld, ld>;
using vd= vector<ld>;
using vb= vector<bool>;
using vi= vector<int>;
using vvi= vector<vi>;
using vs= vector<string>;

#define endl "\n"

const int MOD=998244353;

int mul(const int v1, const int v2, int mod=MOD) {
    return (int)((1LL * v1 * v2) % mod);
}

int pl(int v1, int v2, int mod=MOD) {
    int res = v1 + v2;

    while(res < 0)
        res += mod;

    while(res>=mod)
        res-=mod;

    return res;
}

/* int pow */
int toPower(int a, int p, int mod=MOD) {
    int res = 1;
    while (p != 0) {
        if (p & 1)
            res = mul(res, a, mod);
        p >>= 1;
        a = mul(a, a, mod);
    }
    return res;
}

int inv(const int x, const int mod=MOD) {
    return toPower(x, mod - 2);
}

const int N=1e6;
vector<int> fac(N);

const bool initFac=[](const int mod) {
    fac[1]=1;
    for(int i=2; i<N; i++) {
        fac[i]=mul(fac[i-1], i, mod);
    }
    return true;
}(MOD);

/** see https://cp-algorithms.com/combinatorics/binomial-coefficients.html */
int nCr(int n, int k) {
    if(k==0 || k==n)
        return 1;
    if(k==1 || k==n-1)
        return n;
    if(k>n/2)
        return nCr(n, n-k);

    return mul(mul(fac[n], inv(fac[k])), inv(fac[n - k]));
}

/*
 * Consider including i into the set, so f[i]
 * must be included, too, and so on.
 * So we need to find components in f[].
 * Each complete component satisfies first rule.
 *
 * And such component allways satisfies the second rule, too.
 *
 * So we can put each combination of those components
 * into the set. If c is count of components, then ans=c!
 * ***
 * No, but sample 3 makes not sense.
 * How can answer be 7?
 * There are 7 subsets, but the ones of size 2 do not work,
 * the first rule is not satisfied :/
 * ...It is! It is three independend components.
 * ********************
 * So, only circles can be included at all.
 * Then each combination of those circles can be used.
 * sum(nCr(c, 1..c));
 * ************
 * The circle detection is more complecated :/
 * Starting search somehwere there are several cases:
 * -simply a cicle
 * -> increment circle count and mark all vertex seen
 *
 * -ends in previously seen something
 *  -> just mark visited
 *
 * -ends somewhere else
 *  -> increment cirlce count
 */
void solve() {
    cini(n);
    vi f(n+1);
    for(int i=1; i<=n; i++)
        cin>>f[i];

    int ccnt=0;
    vb vis1(n+1);   /* vis1[i] -> i is checked */
    for(int i=1; i<=n; i++) {
        if(vis1[i])
            continue;

        bool isC=true;
        vi nums;
        vb vis2(n+1);
        int v=i;
        while(!vis2[v] && !vis1[v]) {
            vis2[v]=true;
            nums.push_back(v);
            v=f[v];
            if(vis1[v])
                isC=false;
        }

        if(isC)   /* found a circle */
            ccnt++;

        for(int j=0; j<nums.size(); j++)
                vis1[nums[j]]=true;
    }

    //cerr<<"ccnt="<<ccnt<<endl;

    if(ccnt==0) {
        cout<<0<<endl;
        return;
    }
    int ans=0;
    for(int i=1; i<=ccnt; i++) {
        ans=pl(ans, nCr(ccnt, i));
    }
    cout<<ans<<endl;
}

signed main() {
    solve();
}