#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
const ll MAXN = 200010;
const ll MOD = 1e9+7;
ll N;
ll dir[MAXN];
vector<ll> cycles;

bool vis[MAXN];
bool inCycle[MAXN];
ll dfs(ll cur){
    if (vis[dir[cur]]) return cur;
    vis[dir[cur]]=true;
    return dfs(dir[cur]);
}
ll cycleSize(ll cur, ll l, ll init){
    if (dir[cur]==init) return l+1;
    if (inCycle[cur]) return 0;
    inCycle[cur]=true;
    return cycleSize(dir[cur], l+1, init);
}
ll exp2(ll n){
    ll res = 1;
    for(ll i=0; i<n; i++){
        res = (res*2)%MOD;
    }
    return res;
}
int main(){
    // freopen("input.in", "r", stdin);
    cin>>N;
    for(ll i=0; i<N; i++){
        cin>>dir[i];
        dir[i]--;
    }
    int freeEdges = N;
    ll res = 1;
    for (int i=0; i<N; i++){
        if (vis[i]) continue;
        ll cycleStart = dfs(i);
        ll cycleLength = cycleSize(cycleStart, 0, cycleStart);
        if (cycleLength==0) continue;
        // cout<<i<<' '<<cycleStart<<' '<<cycleLength<<endl;
        freeEdges -= cycleLength;
        ll sgn=1;
        ll cycle_res=0;
        for(ll i=cycleLength-2; i>=0; i-=2){
            cycle_res = (cycle_res+sgn*(i+2)*exp2(i))%MOD;
            sgn*=-1;
        }
        res = (cycle_res*res)%MOD;
        // cout<<res<<endl;
    }
    res = (res*exp2(freeEdges))%MOD;
    cout<<res<<endl;

}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2,all-in,Mod) * (((power_mod(2,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = ans * topsort(i) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	ll all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] <= 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    ll in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		deg[next]--;
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	ll all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    ll in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%lld\n",ans % Mod);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	ll all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    ll in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		deg[next]--;
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2,all-in,Mod) * ((power_mod(2,in,Mod) - 2) + Mod) % Mod) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = ans * topsort(i) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	ll all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    ll in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans % Mod);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2,all-in,Mod) * (((power_mod(2,in,Mod) - 2) + Mod) % Mod) % Mod);
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = ans * topsort(i) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans % Mod);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	ll all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    ll in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		deg[next]--;
    		if (deg[next] == 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2ll,all-in,Mod) * (((power_mod(2ll,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200005;
typedef long long ll;
vector<int> v[maxn];
bool vis[maxn];
int deg[maxn];
int n;
const ll Mod = 1e9 + 7;
ll power_mod(ll a, ll m, ll mod)
{
    ll tmp = 1;
    while (m)
	{
        if (m & 1)
            tmp = tmp * a % mod;
        m >>= 1;
        a = a * a % mod;
    }
    return tmp;
}
ll topsort(int k)
{
	queue<int> all_q,out_q;
   	all_q.push(k);
   	vis[k] = 1;
   	int all = 0;
    while (!all_q.empty())
    {
        int temp = all_q.front();
        all_q.pop();
        all++;
		if (deg[temp] == 1) out_q.push(temp);
        for (int i = 0; i < v[temp].size(); i++)
        {
            int next = v[temp][i];
            if (!vis[next])
            {
            	vis[next] = true;
				all_q.push(next);
            }
        }
    }
    int in = all;
    while (!out_q.empty())
    {
    	int temp = out_q.front();
    	out_q.pop();
    	in--;
    	for (int i = 0; i < v[temp].size(); i++)
    	{
    		int next = v[temp][i];
    		if (deg[next] <= 1)
    		{
    			out_q.push(next);
			}
		}
	}
	return (power_mod(2,all-in,Mod) * (((power_mod(2,in,Mod) - 2) + Mod) % Mod)) % Mod;
}
int main()
{
	int num;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &num);
		v[i].push_back(num);
		v[num].push_back(i);
		deg[i]++;
		deg[num]++;
	}
	ll ans = 1;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i])
		{
			ans = (ans * topsort(i)) % Mod;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


// I/O stream
#include <iostream>
#include <iomanip>

// Algorithms & Maths
#include <cmath>
#include <numeric>
#include <algorithm>

// C headers
#include <cstdlib>
#include <cstdio>

// String
#include <string>
#include <cstring>

// STL
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>

// Exeption
#include <exception>
#include <stdexcept>
#include <cassert>

using namespace std;

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ac = 0, v;
LL e2[MAXN];
int edge[MAXE];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXE];
bool flag;
int cc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

//	cin >> n;
	scanf ( "%d", &n );
	int v;
	lpi ( i, 1, n ){
		//cin >> v;
		scanf ( "%d", &v );
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );

	lpi ( i, 1, n ){
		if ( !vis[i] ){
			flag = false;
			top = 0;
			dfs ( i );
		}
	}

	LL ans = 1;
	int sum = 0;
	lp ( i, 0, ac ){
		sum += cc[i];
		ans *= ( e2[cc[i]] + MOD - 2 ) % MOD;
		ans %= MOD;
	}
	ans *= e2[n-sum];
	ans %= MOD;

	//cout << ans << endl;
	printf ( "%I64d\n", ans );
}

void dfs ( int now )
{
	vis[now] = true;
	if ( !flag ) s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( !flag && vis[v] ){
				cc[ac] = 0;
				for ( --top; s[top] ^ v; ++cc[ac], --top );
				++cc[ac];
				++ac;
				flag = true;
			}else{
				ena[i^1] = false;
				dfs ( v );
			}
		}
	}

	if ( !flag ) --top;
}


// I/O stream
#include <iostream>
#include <iomanip>

// Algorithms & Maths
#include <cmath>
#include <numeric>
#include <algorithm>

// C headers
#include <cstdlib>
#include <cstdio>

// String
#include <string>
#include <cstring>

// STL
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>

// Exeption
#include <exception>
#include <stdexcept>
#include <cassert>

using namespace std;

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ac = 0, v;
LL e2[MAXN];
int edge[MAXE];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXE];
bool flag;
int cc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

//	cin >> n;
	scanf ( "%d", &n );
	int v;
	lpi ( i, 1, n ){
		//cin >> v;
		scanf ( "%d", &v );
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );

	lpi ( i, 1, n ){
		if ( !vis[i] ){
			flag = false;
			top = 0;
			dfs ( i );
		}
	}

	LL ans = 1;
	int sum = 0;
	lp ( i, 0, ac ){
		sum += cc[i];
		ans *= ( e2[cc[i]] + MOD - 2 ) % MOD;
		ans %= MOD;
	}
	ans *= e2[n-sum];
	ans %= MOD;

	//cout << ans << endl;
	printf ( "%I64d\n", ans );
}

void dfs ( int now )
{
	vis[now] = true;
	if ( !flag ) s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( vis[v] ){
				cc[ac] = 0;
				for ( --top; s[top] ^ v; ++cc[ac], --top );
				++cc[ac];
				++ac;
				flag = true;
			}

			ena[i^1] = false;
			dfs ( v );
		}
	}

	if ( !flag ) --top;
}


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

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ac = 0, v;
LL e2[MAXN];
int edge[MAXE];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXE];
bool flag;
int cc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

	cin >> n;
	int v;
	lpi ( i, 1, n ){
		cin >> v;
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );

	lpi ( i, 1, n ){
		if ( !vis[i] ){
			flag = false;
			top = 0;
			dfs ( i );
		}
	}

	LL ans = 1;
	int sum = 0;
	lp ( i, 0, ac ){
		sum += cc[i];
		ans *= e2[cc[i]] - 2;
		ans %= MOD;
	}
	ans *= e2[n-sum];
	ans %= MOD;

	cout << ans << endl;
}

void dfs ( int now )
{
	vis[now] = true;
	s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( vis[v] ){
				cc[ac] = 0;
				for ( --top; s[top] ^ v; ++cc[ac], --top );
				++cc[ac];
				++ac;
				flag = true;
				return;
			}

			ena[i^1] = false;
			dfs ( v );
			if ( flag ) return;
		}
	}

	--top;
}


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

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ans = 0, v;
LL e2[MAXN];
int edge[MAXE];
int pr[MAXN];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXN];
bool flag;

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

	cin >> n;
	int v;
	lpi ( i, 1, n ){
		cin >> v;
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );
	flag = false;

	dfs ( 1 );

	cout << ( e2[n] + MOD - e2[n-ans+1] ) % MOD << endl;
}

void dfs ( int now )
{
	vis[now] = true;
	s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( vis[v] ){
				ans = 0;
				for ( --top; s[top] ^ v; ++ans, --top );
				++ans;
				flag = true;
				break;
			}

			ena[i^1] = false;
			dfs ( v );
			if ( flag ) return;
		}
	}

	--top;
}


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

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ac = 0, v;
LL e2[MAXN];
int edge[MAXE];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXE];
bool flag;
int cc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

	cin >> n;
	int v;
	lpi ( i, 1, n ){
		cin >> v;
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );
	flag = false;

	lpi ( i, 1, n ){
		if ( !vis[i] ) dfs ( i );
	}

	LL ans = 1;
	int sum = 0;
	lp ( i, 0, ac ){
		sum += cc[i];
		ans *= e2[cc[i]] - 2;
		ans %= MOD;
	}
	ans *= e2[n-sum];
	ans %= MOD;

	cout << ans << endl;
}

void dfs ( int now )
{
	vis[now] = true;
	s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( vis[v] ){
				cc[ac] = 0;
				for ( --top; s[top] ^ v; ++cc[ac], --top );
				++cc[ac];
				++ac;
				flag = true;
				break;
			}

			ena[i^1] = false;
			dfs ( v );
			if ( flag ) return;
		}
	}

	--top;
}


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

#define LL long long
#define LD long double
#define SC(t,x) static_cast<t>(x)
#define AR(t) vector < t >
#define lp(loop,start,end) for ( int loop = start; loop < end; ++loop )
#define lpd(loop,start,end) for ( int loop = start; loop > end; --loop )
#define lpi(loop,start,end) for ( int loop = start; loop <= end; ++loop )
#define lpdi(loop,start,end) for ( int loop = start; loop >= end; --loop )
#define qmax(a,b) (((a)>(b))?(a):(b))
#define qmin(a,b) (((a)<(b))?(a):(b))
#define qabs(a) (((a)>=0)?(a):(-(a)))

const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MAXN = 200007;
const int MAXE = MAXN*2;
const int MOD = 1e9 + 7;

int n, k = 0, top = 0, ac = 0, v;
LL e2[MAXN];
int edge[MAXE];
int nxt[MAXE];
int last[MAXN];
int s[MAXN];
bool vis[MAXN];
bool ena[MAXE];
bool flag;
int cc[MAXN];

void init ();
void input ();
void work ();

void dfs ( int now );

int main()
{
	init();
	input();
	work();
}

void init ()
{
	// Init Everything Here

	ios::sync_with_stdio ( false );

	e2[0] = 1;
	lp ( i, 1, MAXN )
		e2[i] = ( e2[i-1] << 1 ) % MOD;
}

void input ()
{
	// input method

	memset ( last, -1, sizeof ( last ) );

	cin >> n;
	int v;
	lpi ( i, 1, n ){
		cin >> v;
		edge[k] = v;
		nxt[k] = last[i];
		last[i] = k;
		++k;

		edge[k] = i;
		nxt[k] = last[v];
		last[v] = k;
		++k;
	}
}

void work ()
{
	// main work

	memset ( vis, false, sizeof ( vis ) );
	memset ( ena, true, sizeof ( ena ) );
	flag = false;

	lpi ( i, 1, n ){
		if ( !vis[i] ) dfs ( i );
	}

	LL ans = 1;
	int sum = 0;
	lp ( i, 0, ac ){
		sum += cc[i];
		ans *= e2[cc[i]] - 2;
		ans %= MOD;
	}
	ans *= e2[n-sum];
	ans %= MOD;

	cout << ans << endl;
}

void dfs ( int now )
{
	vis[now] = true;
	s[top++] = now;

	for ( int i = last[now]; i ^ -1; i = nxt[i] ){
		if ( ena[i] ){
			v = edge[i];
			if ( vis[v] ){
				cc[ac] = 0;
				for ( --top; s[top] ^ v; ++cc[ac], --top );
				++cc[ac];
				++ac;
				top = 0;
				flag = true;
				return;
			}

			ena[i^1] = false;
			dfs ( v );
			if ( flag ) return;
		}
	}

	--top;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

const ll M=200005;
const ll P=1000000007;

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, count2, countthiscycle;
ll quickpowlist[M];

ll quickpow2(ll b) {
	if(quickpowlist[b]!=-1) return quickpowlist[b];
	if(b==0) return quickpowlist[b]=1;
	ll c=quickpow2(b>>1);
	if(b%2==1) return quickpowlist[b]=(((c*c)%P)<<1)%P;
	else return quickpowlist[b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			countthiscycle=label2[x]-label2[y]+1;
			n-=countthiscycle;
			cout << x << " " << y << " : " << countthiscycle << endl;
			num=(num*((quickpow2(countthiscycle)+P-2)%P))%P;
			cout << num << endl;
		}
	}
}

ll findnext(ll v) {
	ll u=++v;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	num=1;
	cin >> n;
	for(ll i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1, m=n;
	do{
		dfs(v);
		count++;
		v=findnext(v);
	}while(v<=m);
	cout << (num*quickpow2(n))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

#define M 200005
#define P 1000000007

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, countcycle, count2, countthiscycle;
ll quickpowlist[M];

ll quickpow2(ll b) {
	if(quickpowlist[b]!=-1) return quickpowlist[b];
	if(b==0) return quickpowlist[b]=1;
	ll c=quickpow2(b>>1);
	if(b%2==1) return quickpowlist[b]=(((c*c)%P)<<1)%P;
	else return quickpowlist[b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			countthiscycle=label2[x]-label2[y]+1;
			countcycle+=countthiscycle;
			num=(num*((quickpow2(countthiscycle)+P-2)%P))%P;
		}
	}
}

ll findnext() {
	ll u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v<=n);

	cout << (num*quickpow2(n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ull;

#define M 200001
#define P 1000000007

int n;
ull a[M];
ull label1[M];
ull count, num, countcycle;

ull quickpow(ull a, ull b) {
	if(b==0) return 1;
	ull c=quickpow(a,b/2);
	if(b%2==1) return (a*((c*c)%P))%P;
	else return (c*c)%P;
}

void dfs(int x) {
	label1[x]=count;
	ull y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			ull z=y, countthiscycle=0;
			do{
				countcycle++;
				countthiscycle++;
				z=a[z];
			}while(z!=y);
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

int findnext() {
	ull u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	int v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (num*quickpow(2,n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

#define M 200001
#define P 1000000007

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, countcycle, count2, countthiscycle;
ll quickpowlist[M];

ll quickpow2(ll b) {
	if(quickpowlist[b]!=-1) return quickpowlist[b];
	if(b==0) return quickpowlist[b]=1;
	ll c=quickpow2(b>>1);
	if(b%2==1) return quickpowlist[b]=(((c*c)%P)<<1)%P;
	else return quickpowlist[b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			countthiscycle=label2[x]-label2[y]+1;
			countcycle+=countthiscycle;
			num=(num*((quickpow2(countthiscycle)+P-2)%P))%P;
		}
	}
}

ll findnext() {
	ll u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v<=n);

	cout << (num*quickpow2(n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef unsigned long long ull;

#define M 200001
#define P 1000000007

int n;
ull a[M];
ull label1[M];
ull count, num, countcycle;

ull quickpow(ull a, ull b) {
	if(b==0) return 1;
	ull c=quickpow(a,b/2);
	if(b%2==1) return (a*((c*c)%P))%P;
	else return (c*c)%P;
}

void dfs(int x) {
	label1[x]=count;
	ull y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			ull z=y, countthiscycle=0;
			do{
				countcycle++;
				countthiscycle++;
				z=a[z];
			}while(z!=y);
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

int findnext() {
	ull u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	int v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (num*quickpow(2,n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ull;

#define M 200001
#define P 1000000007

ull n;
ull a[M];
ull label1[M];
ull count, num, countcycle;
ull quickpowlist[3][M];

ull quickpow(ull a, ull b) {
	if(quickpowlist[a][b]!=-1) return quickpowlist[a][b];
	if(b==0) return quickpowlist[a][b]=1;
	ull c=quickpow(a,b/2);
	if(b%2==1) return quickpowlist[a][b]=(a*((c*c)%P))%P;
	else return quickpowlist[a][b]=(c*c)%P;
}

void dfs(ull x) {
	label1[x]=count;
	ull y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			ull z=y, countthiscycle=0;
			do{
				countcycle++;
				countthiscycle++;
				z=a[z];
			}while(z!=y);
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

ull findnext() {
	ull u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	ull v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (num*quickpow(2,n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

const ll M=200005;
const ll P=1000000007;

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, count2, countthiscycle;
ll quickpowlist[M];

ll quickpow2(ll b) {
	if(quickpowlist[b]!=-1) return quickpowlist[b];
	if(b==0) return quickpowlist[b]=1;
	ll c=quickpow2(b>>1);
	if(b%2==1) return quickpowlist[b]=(((c*c)%P)<<1)%P;
	else return quickpowlist[b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			countthiscycle=label2[x]-label2[y]+1;
			n-=countthiscycle;
			num=(num*((quickpow2(countthiscycle)+P-2)%P))%P;
		}
	}
}

ll findnext(ll v) {
	ll u=++v;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	num=1;
	cin >> n;
	for(ll i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1, m=n;
	do{
		dfs(v);
		count++;
		v=findnext(v);
	}while(v<=m);
	cout << (num*quickpow2(n))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ull;

#define M 200001
#define P 1000000007

ull n;
ull a[M];
ull label1[M];
ull count, num, countcycle;

ull quickpow(ull a, ull b) {
	if(b==0) return 1;
	ull c=quickpow(a,b/2);
	if(b%2==1) return (a*((c*c)%P))%P;
	else return (c*c)%P;
}

void dfs(ull x) {
	label1[x]=count;
	ull y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			ull z=y, countthiscycle=0;
			do{
				countcycle++;
				countthiscycle++;
				z=a[z];
			}while(z!=y);
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

ull findnext() {
	ull u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	ull v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (num*quickpow(2,n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

#define M 200001
#define P 1000000007

int n;
int a[M];
int label1[M];
int count, num, countcycle;

void dfs(int x) {
	label1[x]=count;
	int y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			num=(num*3)%P;
			int z=y;
			do{
				countcycle++;
				z=a[z];
			}while(z!=y);
		}
	}
}

int findnext() {
	int u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int quickpow(int a, int b) {
	if(b==0) return 1;
	int c=quickpow(a,b/2);
	if(b%2==1) return (a*((c*c)%P))%P;
	else return (c*c)%P;
}

int main() {
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	int v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (quickpow(2,n)-(num-1)*quickpow(2,n-countcycle)+P)%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

#define M 200001
#define P 1000000007

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, countcycle, count2;
ll quickpowlist[3][M];

ll quickpow(ll a, ll b) {
	if(quickpowlist[a][b]!=-1) return quickpowlist[a][b];
	if(b==0) return quickpowlist[a][b]=1;
	ll c=quickpow(a,b/2);
	if(b%2==1) return quickpowlist[a][b]=(a*((c*c)%P))%P;
	else return quickpowlist[a][b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			ll countthiscycle=label2[x]-label2[y]+1;
			countcycle+=countthiscycle;
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

ll findnext() {
	ll u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v<=n);

	cout << (num*quickpow(2,n-countcycle))%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

#define M 200001
#define P 1000000007

int n;
int a[M];
int label1[M];
int count, num, countcycle;

int quickpow(int a, int b) {
	if(b==0) return 1;
	int c=quickpow(a,b/2);
	if(b%2==1) return (a*((c*c)%P))%P;
	else return (c*c)%P;
}

void dfs(int x) {
	label1[x]=count;
	int y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			int z=y, countthiscycle=0;
			do{
				countcycle++;
				countthiscycle++;
				z=a[z];
			}while(z!=y);
			num=(num*((quickpow(2,countthiscycle)+P-2)%P))%P;
		}
	}
}

int findnext() {
	int u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(label1, -1, sizeof(label1));
	count=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> a[i];
	}
	int v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v!=n+1);

	cout << (num*quickpow(2,n-countcycle)+P)%P << endl;

	return 0;
}


#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;

typedef long long ll;

#define M 200005
#define P 1000000007

ll n;
ll a[M];
ll label1[M], label2[M];
ll count, num, countcycle, count2, countthiscycle;
ll quickpowlist[M];

ll quickpow2(ll b) {
	if(quickpowlist[b]!=-1) return quickpowlist[b];
	if(b==0) return quickpowlist[b]=1;
	ll c=quickpow2(b>>1);
	if(b%2==1) return quickpowlist[b]=(((c*c)%P)<<1)%P;
	else return quickpowlist[b]=(c*c)%P;
}

void dfs(ll x) {
	label1[x]=count;
	label2[x]=count2; count2++;
	ll y=a[x];
	if(label1[y]==-1) {
		dfs(y);
	}
	else {
		if(label1[y]==count) {
			countthiscycle=label2[x]-label2[y]+1;
			countcycle+=countthiscycle;
			num=(num*((quickpow2(countthiscycle)+P-2)%P))%P;
		}
	}
}

ll findnext() {
	ll u=1;
	while(label1[u]!=-1) {
		u++;
	}
	return u;
}

int main() {
	memset(quickpowlist, -1, sizeof(quickpowlist));
	memset(label1, -1, sizeof(label1));
	memset(label2, -1, sizeof(label2));
	count=1; count2=1;
	countcycle=0;
	num=1;
	cin >> n;
	for(ll i=1; i<=n; i++) {
		cin >> a[i];
	}
	ll v=1;
	do{
		dfs(v);
		count++;
		v=findnext();
	}while(v<=n);

	cout << (num*quickpow2(n-countcycle))%P << endl;

	return 0;
}


#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long LL;

#define min(a,b) (((a)<(b))?(a):(b))
#define mem(a,b) memset(a,b,sizeof a)

using namespace std;

const  int mod=1e9+7,INF=2e9,maxn=1e7;
const double eps=1e-10;

int n,m;
int a[300001],v[300001];
LL sum=1;

int main()
{
  //  freopen("betting.in","r",stdin);
   // freopen("betting.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    	if(v[i]==0)
    	{
    		int s=0,p=i;
    		while(v[p]==0)
    		{
    			v[p]=++s;
    			p=a[p];
    		}
    	//	cout<<s<<" ";
    		for(int j=i;j!=p;j=a[j])
    		{
    			sum=sum*2%mod;
    			s--;
			}
    	//	cout<<s<<" ";
			LL temp=1;
			for(int j=1;j<=s;j++)
				temp=temp*2%mod;
			if(s>=2)
				temp=(temp+mod-2)%mod;
			//cout<<temp<<" ";
			sum=sum*temp%mod;
			cout<<p<<endl;
    	}

    // for(int i=1;i<=n;i++)
    // 	cout<<v[i]<<" ";
    // cout<<endl;

    cout<<sum<<endl;
    return 0;
}


#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long LL;

#define min(a,b) (((a)<(b))?(a):(b))
#define mem(a,b) memset(a,b,sizeof a)

using namespace std;

const  int mod=1e9+7,INF=2e9,maxn=1e7;
const double eps=1e-10;

int n,m;
int a[300001],v[300001];
LL sum=1;

int main()
{
  //  freopen("betting.in","r",stdin);
   // freopen("betting.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    	if(v[i]==0)
    	{
    		int s=0,p=i;
    		while(v[p]==0)
    		{
    			v[p]=++s;
    			p=a[p];
    		}
    	//	cout<<s<<" ";
    		for(int j=i;j!=p;j=a[j])
    		{
    			sum=sum*2%mod;
    			s--;
			}
    	//	cout<<s<<" ";
			LL temp=1;
			for(int j=1;j<=s;j++)
				temp=temp*2%mod;
			if(s>=2)
				temp=(temp+mod-2)%mod;
			//cout<<temp<<" ";
			sum=sum*temp%mod;
			//cout<<p<<endl;
    	}

    // for(int i=1;i<=n;i++)
    // 	cout<<v[i]<<" ";
    // cout<<endl;

    cout<<sum<<endl;
    return 0;
}


#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long LL;

#define min(a,b) (((a)<(b))?(a):(b))
#define mem(a,b) memset(a,b,sizeof a)

using namespace std;

const  int mod=1e9+7,INF=2e9,maxn=1e7;
const double eps=1e-10;

int n,m;
int a[300001],v[300001];
LL sum=1;

int main()
{
    //freopen("betting.in","r",stdin);
    //freopen("betting.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    	if(v[i]==0)
    	{
    		int s=0,p=i;
    		while(v[p]==0)
    		{
    			v[p]=++s;
    			p=a[p];
    		}
    		for(int j=i;j!=p;j=a[j])
    		{
    			sum=sum*2%mod;
    			s--;
			}
			LL temp=1;
			for(int j=1;j<=s;j++)
				temp=temp*2%mod;
			temp=(temp+mod-2)%mod;
			sum=sum*temp%mod;
    	}
    	cout<<sum<<endl;
    return 0;
}


#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long LL;

#define min(a,b) (((a)<(b))?(a):(b))
#define mem(a,b) memset(a,b,sizeof a)

using namespace std;

const  int mod=1e9+7,INF=2e9,maxn=1e7;
const double eps=1e-10;

int n,m;
int a[300001],v[300001];
LL sum=1;

int main()
{
  //  freopen("betting.in","r",stdin);
   // freopen("betting.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    	if(v[i]==0)
    	{
    		int s=0,p=i;
    		while(v[p]==0)
    		{
    			v[p]=++s;
    			p=a[p];
    		}
    		cout<<s<<" ";
    		for(int j=i;j!=p;j=a[j])
    		{
    			sum=sum*2%mod;
    			s--;
			}
    		cout<<s<<" ";
			LL temp=1;
			for(int j=1;j<=s;j++)
				temp=temp*2%mod;
			if(s>=2)
				temp=(temp+mod-2)%mod;
			cout<<temp<<" ";
			sum=sum*temp%mod;
			cout<<p<<endl;
    	}

    for(int i=1;i<=n;i++)
    	cout<<v[i]<<" ";
    cout<<endl;

    cout<<sum<<endl;
    return 0;
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 100005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn];
int to[maxn];
int d[maxn];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		for(vector<edge>::iterator it = G[p.y].begin();it!=G[p.y].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[p.y] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[p.y] + e.cost;
			}

		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}
LL quick_mod(int x,int n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = res*x%mod;
		x = x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k,tmp = 0;
	cin>>n;
	k = n;
	LL ans = 1;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
			//cout<<tmp<<endl;
			k -= tmp;
			ans = ans * (quick_mod(2,tmp) - 2) % mod;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	ans = ans * quick_mod(2,k) %mod;
		//cout<<tmp<<endl;
	cout<<ans<<endl;
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 200005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn];
int to[maxn];
int d[maxn];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		if(d[p.y] < p.x) continue;
		for(vector<edge>::iterator it = G[p.y].begin();it!=G[p.y].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[p.y] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[p.y] + e.cost;
			}
		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}

LL quick_mod(LL x,LL n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = 1LL*res*x%mod;
		x = 1LL*x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k,tmp = 0;
	sd(n);
	k = n;
	LL ans = 1;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
			k -= tmp;
			ans = 1LL* ans * (quick_mod(2,tmp) - 2) % mod;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	ans = 1LL * ans * quick_mod(2,k) %mod;
	printf("%I64d\n",ans);
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 100005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn];
int to[maxn];
int d[maxn];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		for(vector<edge>::iterator it = G[p.y].begin();it!=G[p.y].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[p.y] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[p.y] + e.cost;
			}

		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}
LL quick_mod(int x,int n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = res*x%mod;
		x = x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k=-1,tmp = 0;
	cin>>n;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	LL ans = quick_mod(2,n);
	if(tmp>0)
		ans = (ans - 2*quick_mod(2,n-tmp))%mod;
		//cout<<tmp<<endl;
	cout<<ans<<endl;
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 200005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn+100];
int to[maxn+100];
int d[maxn+100];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		int v = p.y;
		//if(d[v] < p.first) continue;
		for(vector<edge>::iterator it = G[v].begin();it!=G[v].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[v] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[v] + e.cost;
			}

		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}

LL quick_mod(LL x,LL n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = 1LL*res*x%mod;
		x = 1LL*x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k,tmp = 0;
	sd(n);
	k = n;
	LL ans = 1;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
			k -= tmp;
			ans = 1LL* ans * (quick_mod(2,tmp) - 2) % mod;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	ans = 1LL * ans * quick_mod(2,k) %mod;
	printf("%I64d\n",ans);
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define all(x) (x).begin(),(x).end()
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 200005
using namespace std;
const LL mod = 1e9+7;
LL quick_mod(LL x,LL n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = 1LL*res*x%mod;
		x = 1LL*x*x%mod;
		n>>=1;
	}
	return res;
}
int to[maxn];
int vis[maxn];
void solve()
{
	int n,k,tmp = 0;
	sd(n);
	k = n;
	LL ans = 1;
	rep(i,1,n) scanf("%d",&to[i]);
	rep(i,1,n)
	{
	    if(!vis[i])
        {
            int from = i;
            while(!vis[from])
            {
                vis[from] = i;
                from = to[from];
            }
            if(vis[from]==i)
            {
                tmp = 0;
                int t = from;
                while(1)
                {
                    t = to[t];
                    tmp++;
                    if(from==t) break;
                }
                ans = 1LL* ans * (quick_mod(2,tmp) - 2) % mod;
                k -= tmp;
            }
        }
	}

	ans = 1LL * ans * quick_mod(2,k) %mod;
	printf("%I64d\n",ans);
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 300005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn];
int to[maxn];
int d[maxn];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		for(vector<edge>::iterator it = G[p.y].begin();it!=G[p.y].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[p.y] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[p.y] + e.cost;
			}

		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}
LL quick_mod(int x,int n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = res*x%mod;
		x = x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k,tmp = 0;
	cin>>n;
	k = n;
	LL ans = 1;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
			//cout<<tmp<<endl;
			k -= tmp;
			ans = ans * (quick_mod(2,tmp) - 2) % mod;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	ans = ans * quick_mod(2,k) %mod;
		//cout<<tmp<<endl;
	cout<<ans<<endl;
}
int main()
{
	solve();
}


#include <cstdio>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>

#define LL long long
#define loop(a,b,c) for(int a=b;a<=c;a++)
#define rloop(a,b,c) for(int a=b;a>=c;a--)
#define clr(a,b) memset(a,b,sizeof a)
#define sd(x) scanf("%d",&x)
#define sf(x) scanf("%lf",&x)
#define ss(x) scanf("%s",x)
#define x first
#define y second
#define inf 0x3f3f3f3f
#define maxn 300005
using namespace std;
const LL mod = 1e9+7;
typedef pair<int,int> pii;
int f[maxn];
int to[maxn];
int d[maxn];
struct edge
{
	int to,cost;
	edge(){}
	edge(int _to,int _cost)
	{
		to = _to;
		cost = _cost;
	}
};
priority_queue<pii,vector<pii>,greater<pii> > Q;
vector<edge> G[maxn];
void addedge(int u,int v,int c)
{
	G[u].push_back(edge(v,1));
	G[v].push_back(edge(u,1));
}
void dij(int s)
{
	fill(d,d+maxn,inf);
	d[s] = 0;
	Q.push(pii(0,s));
	while(!Q.empty())
	{
		pii p = Q.top();
		Q.pop();
		for(vector<edge>::iterator it = G[p.y].begin();it!=G[p.y].end();it++)
		{
			edge e = *it;
			if(d[e.to] > d[p.y] + e.cost){
				Q.push(pii(d[e.to],e.to));
				d[e.to]  = d[p.y] + e.cost;
			}

		}
	}
}
void init()
{
	loop(i,1,maxn) f[i] = i;
}
int getf(int x)
{
	return f[x]==x?f[x]:getf(f[x]);
}
void unionset(int u,int v)
{
	int a = getf(u);
	int b = getf(v);
	if(a!=b)
		f[b] = a;
}
bool same(int u,int v)
{
	return getf(u)==getf(v);
}

LL quick_mod(LL x,LL n)
{
	LL res = 1;
	while(n)
	{
		if(n&1) res = 1LL*res*x%mod;
		x = 1LL*x*x%mod;
		n>>=1;
	}
	return res;
}
void solve()
{
	init();
	int n,k,tmp = 0;
	cin>>n;
	k = n;
	LL ans = 1;
	loop(i,1,n)
	{
		scanf("%d",&to[i]);
		if(same(i,to[i]))
		{
			dij(i);
			tmp = d[to[i]] + 1;
			//cout<<tmp<<endl;
			k -= tmp;
			ans = 1LL* ans * (quick_mod(2,tmp) - 2) % mod;
		}
		unionset(i,to[i]);
		addedge(i,to[i],1);
	}
	ans = 1LL * ans * quick_mod(2,k) %mod;
		//cout<<tmp<<endl;
	cout<<ans<<endl;
}
int main()
{
	solve();
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[200005];
ll level[200005],cmp[200005],c=0;

ll mull(int base,int exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			if(x)
				ans=(ans*(mull(2,x)-2))%MOD;
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[200005];
ll level[200005],cmp[200005],c=0;

ll mull(ll base,ll exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			cout<<x<<endl;
			if(x>1)
				ans=(ans*(mull(2LL,x)-2))%MOD;
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2LL,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[100005];
ll level[100005],cmp[100005],c=0;

ll mull(int base,int exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			if(x)
				ans=(ans*(mull(2,x)-2))%MOD;
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[100005];
ll level[100005],cmp[100005],c=0;

ll mull(int base,int exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			ans=(ans*(mull(2,x)-2))%MOD;
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[200005];
ll level[200005],cmp[200005],c=0;

ll mull(ll base,ll exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			if(x>1){
				//ans=(ans*(mull(2LL,x)-2))%MOD;
                                   ll fu = (mull(2LL,x)-2+MOD)%MOD;

ans = ans*fu%MOD;}
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2LL,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[200005];
ll level[200005],cmp[200005],c=0;

ll mull(int base,int exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			if(x>1)
				ans=(ans*(mull(2,x)-2))%MOD;
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 * Created By : Aditya Agarwal
 * IT, MNNIT-ALLAHABAD
 * aditya.mnnit15@gmail.com
 _._._._._._._._._._._._._._._._._._._._._.*/

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

#define MP make_pair
#define pb push_back
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define PER(i,a,b) for(int i=b;i>=a;i--)
#define X first
#define Y second

 //i/o
#define inp(n) scanf("%d",&n)
#define inpl(n) scanf("%lld",&n)
#define inp2(n,m) inp(n), inp(m)
#define inp2l(n,m) inpl(n), inpl(m)

//cost
#define MOD 1000000007
#define MOD_INV 1000000006
#define MAX 100009
#define INF 999999999
#define mp make_pair
typedef long long ll;
typedef pair< pair<ll,ll>,ll > pairs;

vector<int> v[200005];
ll level[200005],cmp[200005],c=0;

ll mull(ll base,ll exp){
	base=base%MOD;
	ll res=1;
	while(exp){
		if(exp&1)
			res=(res*base)%MOD;
		exp/=2;
		base=(base*base)%MOD;
	}
	return res;
}

ll dfs(int x,int y){
	level[x]=y;
	cmp[x]=c;
	if(level[v[x][0]]==-1)
		dfs(v[x][0],y+1);
	else if(cmp[x]==cmp[v[x][0]])
		return level[x]-level[v[x][0]]+1;
	else
		return 0;
}

int main(){
	int n,a;
	inp(n);
	rep(i,n){
		inp(a);
		v[i+1].pb(a);
	}
	memset(level,-1,sizeof(level));
	ll ans=1,edge=0;
	for(int i=1;i<=n;i++){
		if(level[i]==-1){
			c++;
			ll x=dfs(i,0);
			edge+=x;
			//cout<<x<<endl;
			if(x>1){
				ans=(ans*(mull(2LL,x)-2))%MOD;
				if(ans==0)
					ans=1;
			}
		}
	}
	//cout<<ans<<" "<<edge<<" "<<n-edge<<" "<<mull(2,n-edge)<<endl;
	ans=(ans*mull(2LL,n-edge))%MOD;
	cout<<ans<<endl;
	return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;

    }

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];

int make()
{
    int i,j,k;
    i=0;
    while(used[i]==0)
    {
        used[i]=1;
        i=ar[i];
    }
    j=0;
    while(used[i]==1)
    {
        used[i]=2;
        i=ar[i];
        j++;
    }
    long long ANS;
    for(i=0,ANS=1;i<j;i++)
    {
        ANS = (ANS * 2)%MOD;
    }
        ANS -= 2;

    if(ANS < 0 ) ANS = (ANS + MOD)%MOD;

    for(i=0,j=N-j; i<j; i++)
    {
        ANS = (ANS * 2)%MOD;
    }

    printf("%I64d\n",ANS);
    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;

    }

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];

int make()
{
    int i,j,k;
    int t,z;
    long long ANS=1;
    for(t=0;t<N;t++)
    {
        if(used[t]) continue;
        i=t;
        z=0;
        while(used[i]==0)
        {
            z++;
            used[i]=1;
            i=ar[i];
        }
        if(used[i]==2){
            for(i=0; i<z; i++)
            {
                ANS = (ANS * 2)%MOD;
            }
            continue;
        }
        j=0;
        while(used[i]==1)
        {
            used[i]=2;
            i=ar[i];
            j++;
        }

        //printf("* %d *\n",j);
        long long ANS2;
        if(j!=1)
        {
            for(i=0,ANS2=1;i<j;i++)
            {
                ANS2 = (ANS2 * 2)%MOD;
            }
            ANS2 -= 2;
            if(ANS2 < 0 ) ANS2 = (ANS2 + MOD)%MOD;
            ANS = (ANS * ANS2)%MOD;
        }

        for(i=0,j=z-j; i<j; i++)
        {
            ANS = (ANS * 2)%MOD;
        }

        //ANS2 = (ANS2 * ANS) % MOD;
    }

    if(ANS!=1)
    {
        printf("%I64d\n",ANS);
    }
    else printf("0\n");
    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
#define ll long long
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];
ll int powx[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;
    }
    powx[0] = 1;
    for(i=1;i<=N;i++)
        powx[i] = ( powx[i-1] * 2 ) % MOD;

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];

int make()
{
    int i,j,k;
    int t,z,total=0;
    long long ANS=1,gx;
    for(i=0;i<N;i++)
    {
        if(used[i]) continue;
        j = i;
        k = 0;
        while(used[j]==0)
        {
            k++;
            used[j] = k;
            j = ar[j];
        }
        if(k == used[j]) continue;
        gx = powx[ k - used[j] + 1 ] - 2;
        gx = ( gx + MOD ) % MOD;
        ANS = ( ANS * gx ) % MOD;
        total += k - used[j] + 1;
    }

    ANS = ( ANS * powx[N - total] ) % MOD;

    printf("%I64d\n",ANS);

    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
#define ll long long
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];
ll int powx[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;
    }
    powx[0] = 1;
    for(i=1;i<=N;i++)
        powx[i] = ( powx[i-1] * 2 ) % MOD;

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];
int mark[200100];

int make()
{
    int i,j,k;
    int t,z,total=0;
    long long ANS=1,gx;
    for(i=0;i<N;i++)
    {
        if(used[i]) continue;
        j = i;
        k = 0;
        while(used[j]==0)
        {
            k++;
            mark[j] = i+1;
            used[j] = k;
            j = ar[j];
        }
        if(mark[j] != i+1) continue;
        if(k == used[j]) continue;
        //printf("c:%d\n",k - used[j] + 1);
        gx = powx[ k - used[j] + 1 ] - 2;
        gx = ( gx + MOD ) % MOD;
        ANS = ( ANS * gx ) % MOD;
        total += k - used[j] + 1;
    }

    ANS = ( ANS * powx[N - total] ) % MOD;

    printf("%I64d\n",ANS);
    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;

    }

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];

int make()
{
    int i,j,k;
    int t,z;
    long long ANS=1;
    for(t=0;t<N;t++)
    {
        if(used[t]) continue;
        i=t;
        z=0;
        while(used[i]==0)
        {
            z++;
            used[i]=1;
            i=ar[i];
        }
        if(used[i]==2){
            for(i=0; i<z; i++)
            {
                ANS = (ANS * 2)%MOD;
            }
            continue;
        }
        j=0;
        while(used[i]==1)
        {
            used[i]=2;
            i=ar[i];
            j++;
        }
        //printf("* %d *\n",j);
        long long ANS2;
        for(i=0,ANS2=1;i<j;i++)
        {
            ANS2 = (ANS2 * 2)%MOD;
        }
        ANS2 -= 2;
        if(ANS2 < 0 ) ANS2 = (ANS2 + MOD)%MOD;
        ANS = (ANS * ANS2)%MOD;

        for(i=0,j=z-j; i<j; i++)
        {
            ANS = (ANS * 2)%MOD;
        }

        //ANS2 = (ANS2 * ANS) % MOD;
    }

    printf("%I64d\n",ANS);
    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


//
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cmath>
#include <queue>
#define f first
#define s second
#define INF (2000000000)
#define NEG (-1)
#define MOD 1000000007
using namespace std;
FILE *in,*out;
struct path{
    int x,y,ind,neg;
}arx[800100];
int N,M,K;
int bas[400100];
int IND[400100];
int ar[200100];

bool operator < (path p, path q)
{
    return (p.x!=q.x) ? p.x < q.x : p.y < q.y;
}

int read()
{
    int i,j,k;
    int ANS=0;
    fscanf(in,"%d",&N);
    for(i=0;i<N;i++)
    {
        fscanf(in,"%d",&ar[i]);
        ar[i]--;

    }

    return 0;
}

int reset()
{
    int i,j,k;
    return 0;
}

int used[200100];

int make()
{
    int i,j,k;
    int t,z;
    long long ANS=1;
    for(t=0;t<N;t++)
    {
        if(used[t]) continue;
        i=t;
        z=0;
        while(used[i]==0)
        {
            z++;
            used[i]=1;
            i=ar[i];
        }
        if(used[i]==2){
            for(i=0; i<z; i++)
            {
                ANS = (ANS * 2)%MOD;
            }
            continue;
        }
        j=0;
        while(used[i]==1)
        {
            used[i]=2;
            i=ar[i];
            j++;
        }

        //printf("* %d *\n",j);
        long long ANS2;
        if(j!=1)
        {
            for(i=0,ANS2=1;i<j;i++)
            {
                ANS2 = (ANS2 * 2)%MOD;
            }
            ANS2 -= 2;
            if(ANS2 < 0 ) ANS2 = (ANS2 + MOD)%MOD;
            ANS = (ANS * ANS2)%MOD;
        }

        for(i=0,j=z-j; i<j; i++)
        {
            ANS = (ANS * 2)%MOD;
        }

        //ANS2 = (ANS2 * ANS) % MOD;
    }

    printf("%I64d\n",ANS);
    return 0;
}

int main()
{
    //in = fopen("D.in","r");
    in = stdin;
    read();
    make();
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#define LL long long
#define N 200005
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
struct EDGE{
	int u,v;
	EDGE() {}
	EDGE(int a,int b):u(a),v(b) {}
};
int pre[N],low[N],a[N],is_bridge[N],dfs_clock;
vector<EDGE> edges;
vector<int> g[N];
int Add_edge(int u,int v){
	edges.pb(EDGE(u,v));
	edges.pb(EDGE(v,u));
	int m = edges.size();
	g[u].pb(m - 2);
	g[v].pb(m - 1);
	return 0;
}
int dfs(int u,int fa){
	int lowu = pre[u] = ++dfs_clock;
	int child = 0;
	for (int i = 0; i < g[u].size(); i ++){
		int k = g[u][i];
		if (k / 2 == fa) continue;
		int v = edges[k].v;
		if (!pre[v]){
			child ++;
			int lowv = dfs(v,k / 2);
			lowu = min(lowu,lowv);
			if (lowv > pre[u]) is_bridge[k / 2] = 1;
		}
		else if (pre[v] < pre[u] && k / 2 != fa)
			 lowu = min(lowu,pre[v]);
	}
	low[u] = lowu;
	return lowu;
}
int quick_pow(LL x,LL p){
	LL t = 1,a = x;
	while (p){
		if (p & 1) t = t * a % MOD;
		p >>= 1;
		a = a * a % MOD;
	}
	return t;
}
int main(){
	int n;
	cin >> n;
	CLR(is_bridge,0);
	FOR(i,1,n){
		scanf("%d",&a[i]);
		Add_edge(i,a[i]);
	}
	int cnt1 = 0,cnt2 = 0;
	dfs_clock = 0;
	dfs(1,-1);
	FOR(i,0,n - 1) if (!is_bridge[i]) cnt2 ++;
	else cnt1 ++;
	LL ans = (quick_pow(2,cnt2) - 2 + MOD) % MOD * quick_pow(2,cnt1) % MOD;
	printf("%I64d\n",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#define LL long long
#define N 200005
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
struct EDGE{
	int u,v;
	EDGE() {}
	EDGE(int a,int b):u(a),v(b) {}
};
int pre[N],low[N],a[N],is_bridge[N],dfs_clock,p[N],vis[N];
vector<EDGE> edges;
vector<int> g[N];
int Add_edge(int u,int v){
	edges.pb(EDGE(u,v));
	edges.pb(EDGE(v,u));
	int m = edges.size();
	g[u].pb(m - 2);
	g[v].pb(m - 1);
	return 0;
}
int dfs(int u,int fa){
	int lowu = pre[u] = ++dfs_clock;
	int child = 0;
	for (int i = 0; i < g[u].size(); i ++){
		int k = g[u][i];
		if (k / 2 == fa) continue;
		int v = edges[k].v;
		if (!pre[v]){
			child ++;
			int lowv = dfs(v,k / 2);
			lowu = min(lowu,lowv);
			if (lowv > pre[u]) is_bridge[k / 2] = 1;
		}
		else if (pre[v] < pre[u] && k / 2 != fa)
			 lowu = min(lowu,pre[v]);
	}
	low[u] = lowu;
	return lowu;
}
LL quick_pow(LL x,LL p){
	LL t = 1,a = x;
	while (p){
		if (p & 1) t = t * a % MOD;
		p >>= 1;
		a = a * a % MOD;
	}
	return t;
}
int cnt;
int dfs2(int u,int fa){
	vis[u] = 1;
	for (int i = 0; i < g[u].size(); i ++){
		int k = g[u][i];
		if (k / 2 == fa || is_bridge[k / 2]) continue;
		int v = edges[k].v;
		if (!vis[v]){
			cnt ++;
			dfs2(v,k / 2);
		}
	}
	return 0;
}
int main(){
	int n;
	cin >> n;
	CLR(is_bridge,0);
	FOR(i,1,n) p[i] = i;
	FOR(i,1,n){
		scanf("%d",&a[i]);
		Add_edge(i,a[i]);
	}
	int flag = 1;
	dfs_clock = 0;
	FOR(i,1,n) if (!pre[i])
	dfs(i,-1);
	LL ans = 1;
	int c = 0;
	FOR(i,0,n - 1)
	if (!is_bridge[i]){
		int idx = edges[2 * i].u;
		if (!vis[idx]){
			cnt = 1;
			dfs2(idx,-1);
			ans = ans * (quick_pow(2,cnt) - 2 + MOD) % MOD;
		}
	}
	else c ++;
	ans = ans * quick_pow(2,c) % MOD;
	printf("%I64d\n",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#define LL long long
#define N 200005
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
struct EDGE{
	int u,v;
	EDGE() {}
	EDGE(int a,int b):u(a),v(b) {}
};
int pre[N],low[N],a[N],is_bridge[N],dfs_clock,p[N],cnt[N];
vector<EDGE> edges;
vector<int> g[N];
int Add_edge(int u,int v){
	edges.pb(EDGE(u,v));
	edges.pb(EDGE(v,u));
	int m = edges.size();
	g[u].pb(m - 2);
	g[v].pb(m - 1);
	return 0;
}
int dfs(int u,int fa){
	int lowu = pre[u] = ++dfs_clock;
	int child = 0;
	for (int i = 0; i < g[u].size(); i ++){
		int k = g[u][i];
		if (k / 2 == fa) continue;
		int v = edges[k].v;
		if (!pre[v]){
			child ++;
			int lowv = dfs(v,k / 2);
			lowu = min(lowu,lowv);
			if (lowv > pre[u]) is_bridge[k / 2] = 1;
		}
		else if (pre[v] < pre[u] && k / 2 != fa)
			 lowu = min(lowu,pre[v]);
	}
	low[u] = lowu;
	return lowu;
}
LL quick_pow(LL x,LL p){
	LL t = 1,a = x;
	while (p){
		if (p & 1) t = t * a % MOD;
		p >>= 1;
		a = a * a % MOD;
	}
	return t;
}
int find(int x){
	return x == p[x] ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	CLR(is_bridge,0);
	FOR(i,1,n) p[i] = i;
	FOR(i,1,n){
		scanf("%d",&a[i]);
		Add_edge(i,a[i]);
		int x = find(i),y = find(a[i]);
		if (x != y) p[x] = y;
	}
	int flag = 1;
	FOR(i,1,n) p[i] = find(p[i]);
	FOR(i,2,n) if (p[i] != p[i - 1]){
		flag = 0;
		break;
	}
	dfs_clock = 0;
	dfs(1,-1);
	LL ans;
	if (flag){
			int cnt1 = 0,cnt2 = 0;
			FOR(i,0,n - 1) if (!is_bridge[i]) cnt2 ++;
			else cnt1 ++;
			ans = (quick_pow(2,cnt2) - 2 + MOD) % MOD * quick_pow(2,cnt1) % MOD;
	}
	else{
		FOR(i,0,n - 1) if (!is_bridge[i]){
			int idx = edges[2 * i].u;
			cnt[p[idx]] ++;
		}
		ans = 1;
		FOR(i,1,n) if (cnt[i])
		ans = ans * (quick_pow(2,cnt[i]) - 2 + MOD) % MOD;
	}
	printf("%I64d\n",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#define LL long long
#define N 200005
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
struct EDGE{
	int u,v;
	EDGE() {}
	EDGE(int a,int b):u(a),v(b) {}
};
int pre[N],low[N],a[N],is_bridge[N],dfs_clock;
vector<EDGE> edges;
vector<int> g[N];
int Add_edge(int u,int v){
	edges.pb(EDGE(u,v));
	edges.pb(EDGE(v,u));
	int m = edges.size();
	g[u].pb(m - 2);
	g[v].pb(m - 1);
	return 0;
}
int dfs(int u,int fa){
	int lowu = pre[u] = ++dfs_clock;
	int child = 0;
	for (int i = 0; i < g[u].size(); i ++){
		int k = g[u][i];
		if (k / 2 == fa) continue;
		int v = edges[k].v;
		if (!pre[v]){
			child ++;
			int lowv = dfs(v,k / 2);
			lowu = min(lowu,lowv);
			if (lowv > pre[u]) is_bridge[k / 2] = 1;
		}
		else if (pre[v] < pre[u] && k / 2 != fa)
			 lowu = min(lowu,pre[v]);
	}
	low[u] = lowu;
	return lowu;
}
LL quick_pow(LL x,LL p){
	LL t = 1,a = x;
	while (p){
		if (p & 1) t = t * a % MOD;
		p >>= 1;
		a = a * a % MOD;
	}
	return t;
}
int main(){
	int n;
	cin >> n;
	CLR(is_bridge,0);
	FOR(i,1,n){
		scanf("%d",&a[i]);
		Add_edge(i,a[i]);
	}
	int cnt1 = 0,cnt2 = 0;
	dfs_clock = 0;
	dfs(1,-1);
	FOR(i,0,n - 1) if (!is_bridge[i]) cnt2 ++;
	else cnt1 ++;
	LL ans = (quick_pow(2,cnt2) - 2 + MOD) % MOD * quick_pow(2,cnt1) % MOD;
	printf("%I64d\n",ans);
}


#include <bits/stdc++.h>

using namespace std;
long long n,u,dem,tinh,num[100050],low[100050],tinh1=1;
vector<int>a[100050],b[100050];
stack<int>st;

void chutrinh(int u)
{
    st.push(u);
    num[u]=low[u]=++tinh;
    for(int i=0; i<a[u].size(); i++)
    {
        int v=a[u][i];
        if(num[v]!=0)
        {
            low[u]=min(low[u],num[v]);
        }
        else
        {
            chutrinh(v);
            low[u]=min(low[u],low[v]);
        }

    }
    if(num[u]==low[u])
    {
        dem++;

        //b[dem].push_back(u);

        int v;
        do
        {
            v=st.top();
            st.pop();
            b[dem].push_back(v);

            num[v]=low[v]=1e9+1;

        }
        while(v!=u);
    }
}
long long mu(int x)
{
    int tong=1;
    for(int i=1; i<=x; i++)
    {
        tong=tong*2;
    }
    return tong;
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>u;
        a[i].push_back(u);
    }
    for(int i=1; i<=n; i++)
    {
        if(num[i]==0)
            chutrinh(i);
    }
    for(int i=1; i<=dem; i++)
    {
        if(b[i].size()>1)
            tinh1=tinh1*(mu(b[i].size())-2);
        else
            tinh1=tinh1*2;
        //cout<<tinh1<<" "<<b[i].size()<<"\n";

    }
    cout<<tinh1;
}


#include <bits/stdc++.h>

using namespace std;
long long n,u,dem,tinh,num[2*100050],low[2*100050],tinh1=1,mod=1e9+7;
vector<int>a[2*100050],b[2*100050];
stack<int>st;

void chutrinh(int u)
{
    st.push(u);
    num[u]=low[u]=++tinh;
    for(int i=0; i<a[u].size(); i++)
    {
        int v=a[u][i];
        if(num[v]!=0)
        {
            low[u]=min(low[u],num[v]);
        }
        else
        {
            chutrinh(v);
            low[u]=min(low[u],low[v]);
        }

    }
    if(num[u]==low[u])
    {
        dem++;

        //b[dem].push_back(u);

        int v;
        do
        {
            v=st.top();
            st.pop();
            b[dem].push_back(v);

            num[v]=low[v]=1e9+1;

        }
        while(v!=u);
    }
}
long long mu(int x)
{
    int tong=1;
    for(int i=1; i<=x; i++)
    {
        tong=(tong*2)%mod;
    }
    return tong;
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>u;
        a[i].push_back(u);
    }
    for(int i=1; i<=n; i++)
    {
        if(num[i]==0)
            chutrinh(i);
    }
    for(int i=1; i<=dem; i++)
    {
        if(b[i].size()>1)
            tinh1=tinh1*(mu(b[i].size())-2);
        else
            tinh1=tinh1*2;
        //cout<<tinh1<<" "<<b[i].size()<<"\n";

    }
    cout<<tinh1;
}


#include <bits/stdc++.h>

using namespace std;
long long n,u,dem,tinh,num[2*100050],low[2*100050],tinh1=1,mod=1e9+7;
vector<int>a[2*100050],b[2*100050];
stack<int>st;

void chutrinh(int u)
{
    st.push(u);
    num[u]=low[u]=++tinh;
    for(int i=0; i<a[u].size(); i++)
    {
        int v=a[u][i];
        if(num[v]!=0)
        {
            low[u]=min(low[u],num[v]);
        }
        else
        {
            chutrinh(v);
            low[u]=min(low[u],low[v]);
        }

    }
    if(num[u]==low[u])
    {
        dem++;

        //b[dem].push_back(u);

        int v;
        do
        {
            v=st.top();
            st.pop();
            b[dem].push_back(v);

            num[v]=low[v]=1e9+1;

        }
        while(v!=u);
    }
}
long long mu(int x)
{
    int tong=1;
    for(int i=1; i<=x; i++)
    {
        tong=(tong*2)%mod;
    }
    return tong;
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>u;
        a[i].push_back(u);
    }
    for(int i=1; i<=n; i++)
    {
        if(num[i]==0)
            chutrinh(i);
    }
    for(int i=1; i<=dem; i++)
    {
        if(b[i].size()>1)
            tinh1=(tinh1*(mu(b[i].size()) - 2 + mod) %mod)%mod;
        else
            tinh1=tinh1*2%mod;
        //cout<<tinh1<<" "<<b[i].size()<<"\n";

    }
    cout<<tinh1%mod;
}


#include <bits/stdc++.h>

using namespace std;
long long n,u,dem,tinh,num[2*100050],low[2*100050],tinh1=1;
vector<int>a[2*100050],b[2*100050];
stack<int>st;

void chutrinh(int u)
{
    st.push(u);
    num[u]=low[u]=++tinh;
    for(int i=0; i<a[u].size(); i++)
    {
        int v=a[u][i];
        if(num[v]!=0)
        {
            low[u]=min(low[u],num[v]);
        }
        else
        {
            chutrinh(v);
            low[u]=min(low[u],low[v]);
        }

    }
    if(num[u]==low[u])
    {
        dem++;

        //b[dem].push_back(u);

        int v;
        do
        {
            v=st.top();
            st.pop();
            b[dem].push_back(v);

            num[v]=low[v]=1e9+1;

        }
        while(v!=u);
    }
}
long long mu(int x)
{
    int tong=1;
    for(int i=1; i<=x; i++)
    {
        tong=tong*2;
    }
    return tong;
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>u;
        a[i].push_back(u);
    }
    for(int i=1; i<=n; i++)
    {
        if(num[i]==0)
            chutrinh(i);
    }
    for(int i=1; i<=dem; i++)
    {
        if(b[i].size()>1)
            tinh1=tinh1*(mu(b[i].size())-2);
        else
            tinh1=tinh1*2;
        //cout<<tinh1<<" "<<b[i].size()<<"\n";

    }
    cout<<tinh1;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
#define NN 1000500
#define gson(i,root) for(__int64 i=ptx[root];~i;i=ed[i].next)
const int N=1000000;
const int e=int(1e9+7);
struct edge{
    __int64 v,next,w;
    edge(){}
    edge(__int64 v,__int64 next,__int64 w){
        this->v=v;
        this->next=next;
        this->w=w;
    }
}ed[NN*2];
__int64 ptx[NN],lnum;
void addline(__int64 x,__int64 y,__int64 w){
    ed[lnum]=edge(y,ptx[x],w);
    ptx[x]=lnum++;
}

__int64 dfn[N],low[N],belong[N]; //tarjan 求连通
__int64 inde[N]; // 入度
__int64 ins[N];  // 入栈标记
__int64 dcnt,bcnt; // 时间戳 和 连通块个数
stack<__int64> sta;
void initial(){
	memset(ptx,-1,sizeof(ptx));
	lnum=0;
	while(!sta.empty()) sta.pop();
	dcnt=bcnt=0;
	memset(ins,0,sizeof(ins));
	memset(belong,0,sizeof(belong));
}
void Tarjan(__int64 u){
	sta.push(u);
	ins[u]=1;
	low[u]=dfn[u]=++dcnt;
	gson(i,u){
		__int64 v=ed[i].v;
		if(!dfn[v]){
			Tarjan(v);
			low[u]=min(low[v],low[u]);
		}
		else if(ins[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		++bcnt;
		__int64 v;
		do{
			v=sta.top();
			ins[v]=0;
			belong[bcnt]++; //连通块标记
			sta.pop();
		}while(u!=v);
	}
}
__int64 n,m;
__int64 powermod(__int64 a,__int64 b){
	__int64 ans=1;
	while(b>0){
		if(b%2==1) ans=ans*a%e;
		a=a*a%e;
		b>>=1;
	}
	return ans;
}
int main(void){
	initial();
	scanf("%I64d",&n);
	for(__int64 i=1;i<=n;i++){
		__int64 x;
		scanf("%I64d",&x);
		addline(i,x,0);
	}
	for(__int64 i=1;i<=n;i++){
		if(!dfn[i]) Tarjan(i);
	}
	__int64 sum=1;

	__int64 s=0;
	for(__int64 i=1;i<=bcnt;i++){
		if(belong[i]>1) sum=(sum%e*(powermod(2,belong[i])%e-2+e)%e)%e,s+=belong[i];
	}
	__int64 y=n-s;
	printf("%I64d\n",(sum%e*((powermod(2,y))%e))%e);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
#define NN 1000500
#define gson(i,root) for(ll i=ptx[root];~i;i=ed[i].next)
typedef __int64 ll;
const ll N=1000000;
const ll e=ll(1e9+7);
struct edge{
    ll v,next,w;
    edge(){}
    edge(ll v,ll next,ll w){
        this->v=v;
        this->next=next;
        this->w=w;
    }
}ed[NN*2];
ll ptx[NN],lnum;
void addline(ll x,ll y,ll w){
    ed[lnum]=edge(y,ptx[x],w);
    ptx[x]=lnum++;
}

ll dfn[N],low[N],belong[N]; //tarjan 求连通
ll inde[N]; // 入度
ll ins[N];  // 入栈标记
ll dcnt,bcnt; // 时间戳 和 连通块个数
stack<ll> sta;
void initial(){
	memset(ptx,-1,sizeof(ptx));
	lnum=0;
	while(!sta.empty()) sta.pop();
	dcnt=bcnt=0;
	memset(ins,0,sizeof(ins));
	memset(belong,0,sizeof(belong));
}
void Tarjan(ll u){
	sta.push(u);
	ins[u]=1;
	low[u]=dfn[u]=++dcnt;
	gson(i,u){
		ll v=ed[i].v;
		if(!dfn[v]){
			Tarjan(v);
			low[u]=min(low[v],low[u]);
		}
		else if(ins[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		++bcnt;
		ll v;
		do{
			v=sta.top();
			ins[v]=0;
			belong[bcnt]++; //连通块标记
			sta.pop();
		}while(u!=v);
	}
}
ll n,m;
ll powermod(ll a,ll b){
	ll ans=1;
	while(b>0){
		if(b%2==1) ans=ans*a%e;
		a=a*a%e;
		b>>=1;
	}
	return ans;
}
int main(void){
	initial();
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++){
		ll x;
		scanf("%lld",&x);
		addline(i,x,0);
	}
	for(ll i=1;i<=n;i++){
		if(!dfn[i]) Tarjan(i);
	}
	ll sum=0;
	for(ll i=1;i<=bcnt;i++){
		if(belong[i]>1) sum+=belong[i];
	}
	ll y=n-sum;
	printf("%lld\n",(((powermod(2,sum)%e-2%e+e)%e)*((powermod(2,y))%e))%e);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
#define NN 1000500
#define gson(i,root) for(__int64 i=ptx[root];~i;i=ed[i].next)
const int N=1000000;
const int e=int(1e9+7);
struct edge{
    __int64 v,next,w;
    edge(){}
    edge(__int64 v,__int64 next,__int64 w){
        this->v=v;
        this->next=next;
        this->w=w;
    }
}ed[NN*2];
__int64 ptx[NN],lnum;
void addline(__int64 x,__int64 y,__int64 w){
    ed[lnum]=edge(y,ptx[x],w);
    ptx[x]=lnum++;
}

__int64 dfn[N],low[N],belong[N]; //tarjan 求连通
__int64 inde[N]; // 入度
__int64 ins[N];  // 入栈标记
__int64 dcnt,bcnt; // 时间戳 和 连通块个数
stack<__int64> sta;
void initial(){
	memset(ptx,-1,sizeof(ptx));
	lnum=0;
	while(!sta.empty()) sta.pop();
	dcnt=bcnt=0;
	memset(ins,0,sizeof(ins));
	memset(belong,0,sizeof(belong));
}
void Tarjan(__int64 u){
	sta.push(u);
	ins[u]=1;
	low[u]=dfn[u]=++dcnt;
	gson(i,u){
		__int64 v=ed[i].v;
		if(!dfn[v]){
			Tarjan(v);
			low[u]=min(low[v],low[u]);
		}
		else if(ins[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		++bcnt;
		__int64 v;
		do{
			v=sta.top();
			ins[v]=0;
			belong[bcnt]++; //连通块标记
			sta.pop();
		}while(u!=v);
	}
}
__int64 n,m;
__int64 powermod(__int64 a,__int64 b){
	__int64 ans=1;
	while(b>0){
		if(b%2==1) ans=ans*a%e;
		a=a*a%e;
		b>>=1;
	}
	return ans;
}
int main(void){
	initial();
	scanf("%I64d",&n);
	for(__int64 i=1;i<=n;i++){
		__int64 x;
		scanf("%I64d",&x);
		addline(i,x,0);
	}
	for(__int64 i=1;i<=n;i++){
		if(!dfn[i]) Tarjan(i);
	}
	__int64 sum=0;
	for(__int64 i=1;i<=bcnt;i++){
		if(belong[i]>1) sum+=belong[i];
	}
	__int64 y=n-sum;
	printf("%I64d\n",(((powermod(2,sum)%e-2%e+e)%e)*((powermod(2,y))%e))%e);
	return 0;
}