#include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using P = pair<int,int>;
#define rep(i,n) for(ll i = 0;i < (ll)n;i++)
#define ALL(x) (x).begin(),(x).end()
#define MOD 1000000007


// 2021/1/19
struct SCC{
  /*
    v := 隣接リスト有向グラフ
    rv := vの逆辺
    C := 同じ強連結成分のリスト
    H := 強連結成分分解後のDAGの隣接リスト(頂点の重複有り。)
    vs := 帰りがけ順
    blg := その頂点が属す強連結成分の番号
  */
  vector<vector<int>> v,rv,C,H;
  vector<int> vs,blg;
  vector<bool> used;
  SCC(int n) : v(n),rv(n),blg(n),used(n,0) {}

  void add_edge(int a,int b){
    v[a].push_back(b);
    rv[b].push_back(a);
  }

  //帰り帰りがけ順を探す
  void dfs(int ov){
    used[ov] = 1;
    for(auto nv : v[ov]){
      if(used[nv])continue;
      dfs(nv);
    }
    vs.push_back(ov);
  }

  //逆辺を移動して、scc
  void rdfs(int ov,int nu){
    used[ov] = 1;
    blg[ov] = nu;
    C[nu].push_back(ov);
    for(auto nv : rv[ov]){
      if(used[nv])continue;
      rdfs(nv,nu);
    }
  }

  int build(){
    int n = v.size();
    for(int i = 0;i < n;i++)if(!used[i])dfs(i);
    fill(used.begin(),used.end(),0);
    int nu = 0;
    for(int i = n-1;i >= 0;i--){
      if(used[vs[i]])continue;
      H.emplace_back();
      C.emplace_back();
      rdfs(vs[i],nu++);
    }

    for(int i = 0;i < n;i++){
      for(auto j : v[i]){
        if(blg[i] != blg[j])H[blg[i]].push_back(blg[j]);
      }
    }

    return nu;
  }
};

// 2020/12/06 rechecked
long long modpow(long long n,long long r,const int mod = 998244353){
  long long res = 1;
  while(r){
    if(r & 1)res = res*n%mod;
    n = n*n%mod;
    r >>= 1;
  }
  return res;
}

int main(){
  
  int n;
  cin >> n;
  vector<int> f(n);
  rep(i,n)cin >> f[i],f[i]--;
  SCC scc(n);
  rep(i,n)scc.add_edge(i,f[i]);
  scc.build();
  int cnt = 0;
  for(auto au : scc.C)if(au.size() >= 2 || au[0] == f[au[0]])cnt++;
  cout << (modpow(2,cnt)-1+998244353)%998244353 << "\n";
  

  return 0;
}
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <algorithm>
#define rep(i, n) for(i = 0; i < (n); i++)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
#define MOD 998244353
#define PI 3.14159265358979323846
#define INF 1 << 30

using namespace std;
typedef long long ll;
typedef pair<int, int> pp;

ll Pow(ll n, ll k) {
	ll ans = 1, a = n % MOD;
	while (k > 0) {
		if (k & 1) {
			ans *= a;
			ans %= MOD;
		}
		a *= a;
		a %= MOD;
		k >>= 1;
	}
	return ans;
}

int DFS(int n, int k, vector<int>& d, vector<int>& v) {
	v[n] = k;
	if (v[d[n]] < 0)
		return DFS(d[n], k, d, v);
	else if (v[d[n]] == k)
		return 1;
	return 0;
}

int main(void) {
	int num, i, k = 0, x = 0;
	cin >> num;
	vector<int> d(num), v(num, -1);
	rep(i, num) {
		cin >> d[i];
		d[i]--;
	}
	rep(i, num) {
		if (v[i] < 0) {
			if (DFS(i, x, d, v))
				k++;
			x++;
		}
	}
	cout << Pow(2ll, k) - 1 << "\n";
	return 0;
}