#include<bits/stdc++.h>
using namespace std;

#define rep(i, n)    for(int i = 0; i < (n); ++i)
#define repA(i, a, n)  for(int i = a; i <= (n); ++i)
#define repD(i, a, n)  for(int i = a; i >= (n); --i)
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define dbg(x) cerr<<#x<<" : "<<x<<endl

typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vii;
const ll INF = 1e18+1;
const ll MOD = 998244353L;
clock_t time_p=clock();
void timer(){time_p=clock()-time_p;cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";}

template <typename Arg1> ostream& operator << (ostream& out, const vector<Arg1> &a) {out<<"[ ";for(const auto &x:a)out<<x<<" ";return out<<"]";}

ll po(ll a,ll b, ll mod=MOD){
    if(b==0) return 1;
    ll x = po(a,b/2,mod);
    if(b%2){
        return (((x*x)%mod)*a)%mod;
    } else {
        return (x*x)%mod;
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll n;
    cin>>n;
    vi f(n);
    rep(i,n) cin>>f[i];
    rep(i,n) f[i]--;
    vi state(n,0);
    ll c = 0;
    vector<set<int>>adj(n);
    rep(i,n){
        adj[i].insert(f[i]);
        adj[f[i]].insert(i);
    }
    vi visited(n,0);
    rep(start, n){ 
        if(visited[start] == 0){
            c++;
            queue<int>s;
            s.push(start);
            while(!s.empty()){
                ll cur = s.front();
                visited[cur] = 1;
                for(auto next : adj[cur]){
                    if(visited[next] == 0){
                        visited[next] = 1;
                        s.push(next);
                    }
                }
                s.pop();
            }
        }
    }
    cout<<(po(2,c,MOD)-1+MOD)%MOD<<endl; 
    timer();
    return 0;
}

#include <iostream>
#include <vector>
#include <set>

// 引用元 : https://qiita.com/ofutonfuton/items/c17dfd33fc542c222396
struct UnionFind {
  std::vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++) par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x) return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x); //xの根をrx
    int ry = root(y); //yの根をry
    if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};


int main()
{
  int N;
  std::cin >> N;

  UnionFind uf(N + 1);

  for (int i = 1; i <= N; i++)
  {
    int n;
    std::cin >> n;
    uf.unite(i,n);
  }

  std::set<int> groups;
  for (int i = 1; i <= N; i++)
  {
    groups.insert(uf.root(i));
  }

  long long mod = 998244353;

  long long ans = 1;
  for (int i = 0; i < groups.size(); i++)
  {
    ans *= 2;
    ans %= mod;
  }

  ans += mod;
  ans -= 1;
  ans %= mod;


  std::cout << ans << std::endl;
  return 0;
}
