#include <bits/stdc++.h>   struct Edge {     Edge(int _from, int _to) : from(_from), to(_to) {}     int from, to;   };   enum GraphNodeColor { NODE_WHITE, NODE_GREY, NODE_BLACK };   class Graph {    public:     Graph(int nodes, std::vector<Edge> edges)         : neighb(nodes, std::vector<int>()) {       node_count = nodes;       for (int i = 0; i < edges.size(); ++i) {         neighb[edges[i].from].push_back(edges[i].to);       }     }     void dfs() {       timer = 0;       components.resize(node_count, 0);       tout.assign(node_count, 0);       colors.assign(node_count, NODE_WHITE);       nodeExitOrder.clear();       nodeExitOrder.reserve(node_count);       for (int i = 0; i < node_count; ++i) {         if (colors[i] == NODE_WHITE) {           dfs_traverse(i);         }       }     }     void count_components(const std::vector<int>& order) {       int label = 0;       timer = 0;       components.resize(node_count, 0);       tout.assign(node_count, 0);       colors.assign(node_count, NODE_WHITE);       nodeExitOrder.clear();       nodeExitOrder.reserve(node_count);       for (int i = 0; i < node_count; ++i) {         int v = order[i];         if (colors[v] == NODE_WHITE) {           dfs_traverse(v, label++);         }       }     }     void dfs_traverse(int v, int label = 0) {       colors[v] = NODE_GREY;       components[v] = label;       for (int neighbor : neighb[v]) {         if (colors[neighbor] == NODE_WHITE) {           dfs_traverse(neighbor, label);         }       }       colors[v] = NODE_BLACK;       tout[v] = timer++;       nodeExitOrder.push_back(v);     }     int node_count;     int timer;     std::vector<std::vector<int>> neighb;     std::vector<GraphNodeColor> colors;     std::vector<int> tout;     std::vector<int> nodeExitOrder;     std::vector<int> components;   };   int powModulo(int base, int power, int modulo) {     if (power == 0) {       return 1 % modulo;     } else {       long long ans = powModulo(base, power / 2, modulo);       ans = (ans * ans) % modulo;       ans = (power % 2 == 0) ? ans : ans * base % modulo;       return ans;     }   }   int main() {     const int modulo = 1e9 + 7;     int n;     std::cin >> n;     std::vector<Edge> edges, edges_tr;     edges.reserve(n);     edges_tr.reserve(n);     for (int i = 0; i < n; ++i) {       int ai;       std::cin >> ai;       edges.emplace_back(i, ai - 1);     }     Graph gr(n, edges);     gr.dfs();     std::vector<int> traverse_order = gr.nodeExitOrder;     std::reverse(traverse_order.begin(), traverse_order.end());     for (int i = 0; i < n; ++i) {       edges_tr.emplace_back(edges[i].to, edges[i].from);     }     Graph gr_tr(n, edges_tr);     gr_tr.count_components(traverse_order);     std::vector<int> comp_sizes;     comp_sizes.reserve(n);     for (int comp : gr_tr.components) {       if (comp >= comp_sizes.size()) {         comp_sizes.resize(comp + 1, 0);       }       ++comp_sizes[comp];     }     long long ans = 1;     int rest_edges = 0;     for (int comp_size : comp_sizes) {       if (comp_size > 1) {         int tmp = powModulo(2, comp_size, modulo);         if (tmp < 2) {           tmp += modulo;         }         ans = ans * (tmp - 2) % modulo;       } else {         ++rest_edges;       }     }     ans = ans * powModulo(2, rest_edges, modulo) % modulo;     std::cout << ans << std::endl;     return 0;   }   