#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,int> LP;
const int INF=1<<30;
const LL MAX=998244353;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}

class union_find_tree{
private:
    static constexpr int N=100005;
    int n;
    queue<int> q1;
    vector<int> parent;
    vector<int> num;
public:
    void init(){
        parent.assign(n,-1);
        num.assign(n,1);
    }
    union_find_tree(int n_init){
        assert(n_init>=0);
        n=n_init;
        init();
    }
    union_find_tree(){
        n=N;
        init();
    }

    int check_parent(int x){
        assert(x>=0 && x<n);
        if(parent[x]!=-1){
            q1.push(x);
            return check_parent(parent[x]);
        }
        int a;
        while(!q1.empty()){
            a=q1.front(),q1.pop();
            parent[a]=x;
        }
        return x;
    }

    bool connect(int x,int y){
        assert(x>=0 && x<n);
        assert(y>=0 && y<n);
        x=check_parent(x),y=check_parent(y);
        if(x==y)return true;
        if(num[x]>num[y])swap(x,y);
        parent[x]=y;
        num[y]+=num[x];
        return false;
    }

    int size(int pos){
        pos=check_parent(pos);
        return num[pos];
    }

    bool check(int x,int y){//connect:true
        assert(x>=0 && x<n);
        assert(y>=0 && y<n);
        return check_parent(x)==check_parent(y);
    }
};

long long int pow_mod(long long int a,long long int n,long long int p=1e9+7){
    //a^n mod p
    long long int b=1,t=1;
    for(;b<=n;b<<=1);
    for(b>>=1;b>0;b>>=1){
        t*=t;
        if(t>=p)t%=p;
        if(n&b)t*=a;
        if(t>=p)t%=p;
    }
    return t;
}

namespace sol{

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        cin>>n;
        union_find_tree ua(n);
        for(i=0;i<n;i++){
            cin>>a;
            a--;
            ua.connect(a,i);
        }
        int s=0;
        for(i=0;i<n;i++){
            if(ua.check_parent(i)==i)s++;
        }
        LL ans=pow_mod(2,s,MAX)-1;
        if(ans<0)ans+=MAX;
        cout<<ans<<endl;
    }
}

int main(){
    sol::solve();
}
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
ll z = 0, mod = 998244353;

ll ruijo(ll a, ll b) {
  ll res = 1;
  for (a %= mod; b; a = a * a % mod, b >>= 1)
    if (b & 1) res = res * a % mod;
  return res;
}

int main(){
  ll N;
  cin >> N;
  
  vector<ll> f(N + 1);
  for (ll i = 1; i <= N; i++){
    cin >> f[i];
    //f[i] = i;
  }
  
  vector<ll> par(N + 1, -1);
  ll loopnum = 0;
  for (ll i = 1; i <= N; i++){
    if (par[i] > -1) continue;
    
    ll now = i;
    while (par[now] == -1){
      par[now] = i;
      now = f[now];
    }
    if (par[now] == i) loopnum++;
  }
  //cout << loopnum << endl;
  cout << ruijo(2, loopnum) - 1 << endl;
}