#include <bits/stdc++.h>

using namespace std;

#define int long long
const int N = 2e5 + 50;
int mod = 998244353;
vector<int> g[N];
int ans;
int vis[N];

void dfs(int node) {
    vis[node] = 1;
    for (auto to: g[node]) {
        if (vis[to] == 1)
            ans++;
        else if (vis[to] == 0) {
            dfs(to);
        }
    }
    vis[node]++;
}

int binpow(int a, int b) {
    int ret = 1;
    while (b) {
        if (b & 1) {
            ret *= a;
            ret %= mod;
        }
        a = (a * a) % mod;
        b >>= 1;
    }
    return ret;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 1; i <= n; i++) {
        int fi;
        cin >> fi;

        g[i].push_back(fi);
    }

    for (int i = 1; i <= n; i++) {
        if (vis[i] == 0)
            dfs(i);
    }

    cout << (binpow(2, ans) - 1 + mod) % mod << '\n';


}



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

#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template<typename T> using Graph = vector<vector<T>>;
template<typename T> using Spacial = vector<vector<vector<T>>>;
template<typename T> using greater_priority_queue = priority_queue<T, vector<T>, greater<T>>;
constexpr int MOD = 1e9+7;
constexpr int MOD2 = 998244353;
const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };
char interval[2] = {' ', '\n'};

template<typename T> struct is_plural : false_type{};
template<typename T1, typename T2> struct is_plural<pair<T1, T2>> : true_type{};
template<typename T> struct is_plural<vector<T>> : true_type{};
template<typename T> struct is_plural<complex<T>> : true_type{};
template<> struct is_plural<string> : true_type{};

template<typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { return is >> p.first >> p.second; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p) { return os << p.first << ' ' << p.second; }
template<typename T> istream &operator>>(istream &is, vector<T> &vec) { for(auto itr = vec.begin(); itr != vec.end(); ++itr) is >> *itr; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec) { if(vec.empty()) return os; bool pl = is_plural<T>(); os << vec.front(); for(auto itr = ++vec.begin(); itr != vec.end(); ++itr) os << interval[pl] << *itr; return os; }
template<typename T> istream &operator>>(istream &is, complex<T> &x) { T a, b; is >> a >> b; x = complex<T>(a, b); return is; }
template<typename T> ostream &operator<<(ostream &os, complex<T> &x) { return os << x.real() << ' ' << x.imag(); }

bool CoutYN(bool a, string y = "Yes", string n = "No") { cout << (a ? y : n) << '\n'; return a; }

template<typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template<typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }


/* -------- <templates end> -------- */


int64_t modpow(int a, int64_t n, int mod = MOD) { int64_t ret = 1; do { if(n & 1) ret = ret * a % mod; a = 1LL * a * a % mod; } while(n >>= 1); return ret; }

void solve() {
  int n; cin >> n;
  vector<int> a(n); cin >> a;
  for(auto &x : a) --x;

  vector<int> timestamp(n, -1);
  int pw = 0;

  auto dfs = [&](auto dfs, int v, int t) -> void {
    if(timestamp[v] != -1) {
      if(timestamp[v] == t) ++pw;
      return;
    }
    timestamp[v] = t;
    dfs(dfs, a[v], t);
  };

  for(int i=0; i<n; ++i) {
    dfs(dfs, i, i);
  }

  cout << modpow(2, pw, MOD2) - 1 << endl;
}


/* -------- <programs end> -------- */


signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  solve();
  return 0;
}
