#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
unordered_map<int,int> G[200002];
int visited[200002];
long long int cc_size;
long long int loop_size;
int loop_start;

int dfs(int u, int p) {

    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !visited[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( loop_start == -1 || it->second == 2 || it->first != p ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = powMod(2, n, M);
    for(int u = 1; u <= n; u++) {
        if( !visited[u] ) {
            cc_size = 0;
            loop_size = 0;
            loop_start = -1;
            dfs(u, -1);
            res = (res - powMod(2, cc_size - loop_size + 1, M) + M)%M;
        }
    }

    cout << res << endl;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
unordered_map<int,int> G[200002];
int visited[200002];
long long int cc_size;
long long int loop_size;
int loop_start;

int explored[200002];

int dfs(int u, int p) {
    explored[u] = 1;
    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !explored[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( it->second == 2 || it->first != p ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    explored[u] = 0;
    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = powMod(2, n, M);
    for(int u = 1; u <= n; u++) {
        if( !visited[u] ) {
            cc_size = 0;
            loop_size = 0;
            loop_start = -1;
            dfs(u, -1);
            res = (res - powMod(2, cc_size - loop_size + 1, M) + M)%M;
        }
    }

    cout << res << endl;

    return 0;
}


#include<iostream>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
vector<unordered_map<int,int>> G[2e5 + 2];
int visited[2e5+2];
long long int cc_size;
long long int loop_size;
int loop_start;

int explored[2e5+2];

int dfs(int u, int p) {
    explored[u] = 1;
    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !explored[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( it->second == 2 || it->first != p ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    explored[u] = 0;
    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = powMod(2, n, M);
    for(int u = 0; u <= n; u++) {
        if( !visited[u] ) {
            dfs(u, -1);
            res = (res - powMod(2, cc_size - loop_size + 1, M) + M)%M;
        }
    }

    cout << res << endl;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
unordered_map<int,int> G[200002];
int visited[200002];
long long int cc_size;
long long int loop_size;
int loop_start;

int dfs(int u, int p) {

    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !visited[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( loop_start == -1 &&( it->second == 2 || it->first != p) ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = powMod(2, n, M);
    for(int u = 1; u <= n; u++) {
        if( !visited[u] ) {
            cc_size = 0;
            loop_size = 0;
            loop_start = -1;
            dfs(u, -1);
            res = (res - powMod(2, n - loop_size + 1, M) + M)%M;
            n -= cc_size;
        }
    }

    cout << res << endl;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
unordered_map<int,int> G[200002];
int visited[200002];
long long int cc_size;
long long int loop_size;
int loop_start;

int dfs(int u, int p) {

    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !visited[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( loop_start == -1 &&( it->second == 2 || it->first != p) ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = 1;
    for(int u = 1; u <= n; u++) {
        if( !visited[u] ) {
            cc_size = 0;
            loop_size = 0;
            loop_start = -1;
            dfs(u, -1);

            res = (res * (powMod(2, cc_size, M) - powMod(2, cc_size - loop_size + 1, M) + M)%M)%M;

        }
    }

    cout << res << endl;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;

long long int M = 1e9 + 7;
int n;
int v;
vector<unordered_map<int,int>> G[200002];
int visited[200002];
long long int cc_size;
long long int loop_size;
int loop_start;

int explored[200002];

int dfs(int u, int p) {
    explored[u] = 1;
    visited[u] = 1;
    cc_size++;
    int res = 0;
    for(auto it = G[u].begin(); it != G[u].end(); it++) {
        if( !explored[it->first] ) {
            if(dfs(it->first, u) ) {
                loop_size++;
                if( u != loop_start ) {
                    res = 1;
                }
            }
        } else {
            if( it->second == 2 || it->first != p ) { // loop found
                loop_start = it->first;
                loop_size++;
                res = 1;
            }

        }
    }

    explored[u] = 0;
    return res;
}

long long int powMod(long long int base, long long int p, long long int MOD) {
    long long int res = 1;
    while(p ) {
        if( p & 1 ) {
            res = (res * base)%MOD;
        }

        base = (base*base)%MOD;
        p >>= 1;
    }
    return res;
}

int main() {
    cin >> n;
    for(int u = 1; u <= n; u++) {
        cin >> v;

        G[u][v]++;
        G[v][u]++;
    }

    long long int res = powMod(2, n, M);
    for(int u = 0; u <= n; u++) {
        if( !visited[u] ) {
            dfs(u, -1);
            res = (res - powMod(2, cc_size - loop_size + 1, M) + M)%M;
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll P=1e9+7;
const int maxn=2e5+10;
struct node{
	int v,id;
};
vector<node>G[maxn];
int n;
ll ans,sz1,sz2;
int vis[maxn];
ll a[maxn],fac[maxn],rev[maxn];
void dfs(int u,int f){
	vis[u]=++sz1;
	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v])dfs(v,id);
	}
	vis[u]=-1;
	/*
	错误代码
	如 1-2-3构成一个环，从1进入到2再到3，vis[1]=1, vis[2]=2,vis[3]=3;
	回退到1时会检查3，这时产生错误vis[1]-vis[3],
	故在回退时设置vis[u]=-1，再加上特判
	vis[u]=++sz1;
	cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else dfs(v,id);
	}
	*/
}
ll C(int n,int m){
	return fac[n]*rev[n-m]%P*rev[m]%P;
}
ll solve(){
	if(sz1==1)return 1;//孤点

	ll ret;
	ret=a[sz1-sz2];
	if(sz2==0)return ret;//无环
	//cout<<ret<<endl;
	ll tmp=0;
	for(int i=1;i<=sz2/2;i++){
		if(i+i==sz2)tmp=(tmp+C(sz2,i))%P;
		else tmp=(tmp+2*C(sz2,i)%P)%P;
	}
	//cout<<tmp<<endl;
	return ret*tmp%P;
}
ll pow_mod(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b=b/2){
		if(b%2==1)ret=(ret*a)%P;
	}
	return ret;
}
void init(){
	a[0]=fac[0]=rev[0]=1;
	for(int i=1;i<=n;i++)a[i]=(a[i-1]*2)%P;//2^n%P
	for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%P;//i!%P
	for(int i=1;i<=n;i++)rev[i]=pow_mod(fac[i],P-2);//i!的逆元
}
int main(){
	int v;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		G[i].push_back((node){v,i});
		G[v].push_back((node){i,i});
	}
	ans=1;
	//sz1=5;sz2=4;cout<<solve();

	for(int i=1;i<=n;i++){
		sz1=sz2=0;//sz1连通块中点数sz2环中点数，最多只有一个环
		if(!vis[i]){
			dfs(i,0);
			//for(int j=1;j<=n;j++)cout<<vis[j]<<" ";cout<<endl;
			//cout<<sz1<<" "<<sz2<<endl;
			ans=ans*solve()%P;
		}
	}
	printf("%lld\n",ans);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll P=1000000000+7;
const int maxn=2e5+10;
struct node{
	int v,id;
};
vector<node>G[maxn];
int n;
ll ans;
int sz1,sz2;
int vis[maxn];
ll a[maxn],fac[maxn],rev[maxn];
	/*
void dfs(int u){

	错误1
	如 1-2-3构成一个环，从1进入到2再到3，vis[1]=1, vis[2]=2,vis[3]=3;
	回退到1时会检查3，这时产生错误vis[1]-vis[3],
	故在回退时设置vis[u]=-1，再加上特判
	vis[u]=++sz1;
	cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v;
		if(vis[v]){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else dfs(v);
	}

}
*/
/*
void dfs(int u,int f){
错误2
对于图    3==1--2  vis[1]=1,vis[2]=2,vis[3]=3   此时sz2=vis[u]-vis[v]+1=3
	vis[u]=++sz1;
	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v])dfs(v,id);
	}
	vis[u]=-1;

}
*/
void dfs(int u,int f){

	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v]){
			sz1++;
			vis[v]=vis[u]+1;
			dfs(v,id);
		}
	}
	vis[u]=-1;

}
ll C(int n,int m){
	return fac[n]*rev[n-m]%P*rev[m]%P;
}
ll solve(){
	if(sz1==1)return 1;//孤点

	ll ret;
	ret=a[sz1-sz2];
	if(sz2==0)return ret;//无环
	//cout<<sz1<<" "<<sz2<<" "<<ret<<endl;
	ll tmp=(a[sz2]-2+P)%P;
	/*
	ll tmp=0;
	for(int i=1;i<=sz2/2;i++){
		if(i+i==sz2)tmp=(tmp+C(sz2,i))%P;
		else tmp=(tmp+2*C(sz2,i)%P)%P;
	}
	*/
	//cout<<tmp<<endl;
	return ret*tmp%P;
}

ll pow_mod(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b=b/2){
		if(b%2==1)ret=(ret*a)%P;
	}
	return ret;
}
void init(){
	a[0]=fac[0]=rev[0]=1;
	for(int i=1;i<=n;i++)a[i]=(a[i-1]*2)%P;//2^n%P
	for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%P;//i!%P
	for(int i=1;i<=n;i++)rev[i]=pow_mod(fac[i],P-2);//i!的逆元
}
int main(){
	int v;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		G[i].push_back((node){v,i});
		G[v].push_back((node){i,i});
	}
	ans=1;
	//sz1=5;sz2=4;cout<<solve();

	for(int i=1;i<=n;i++){
		if(!vis[i]){
			sz1=sz2=0;//sz1连通块中点数sz2环中点数，最多只有一个环
			vis[i]=++sz1;
			dfs(i,0);
			//for(int j=1;j<=n;j++)cout<<vis[j]<<" ";cout<<endl;
			//cout<<sz1<<" "<<sz2<<endl;
			ans=ans*solve()%P;
		}
	}
	printf("%lld\n",ans);

    return 0;
}


#include<bits/stdc++.h>
using namespace std ;
template<typename T> void read(T &x){
	x = 0 ; int flag = 1 ;
	char c = getchar() ;
	while(!isdigit(c)){
		if(c=='-')
			flag = -1 ;
		c = getchar() ;
	}
	while(isdigit(c)){
		x = x * 10 + c -'0' ;
		c = getchar() ;
	}
	x = x*flag ;
}
int n ;
const int maxn = 2e5+10 ;
const long long mod = 1e9+7 ;
int Head[maxn],Next[maxn*2],V[maxn*2],tot ;
int d[maxn],sum,sum2 ;
void add(int u,int v){
	V[++tot] = v ; Next[tot] = Head[u] ; Head[u] = tot ;
}
long long p[maxn] ;
void dfs(int fa,int u,int dep){
	if(d[u]){
	//cout<<u<<" "<<dep<<endl ;
		sum2 = max(sum2,abs(dep-d[u])) ;
		return ;
	}
	int v,ok=0 ;
	sum++ ; d[u] = dep ;
	for(int i = Head[u] ; i ; i = Next[i]){
		v = V[i] ;
		if(v==fa){
			ok++ ;
			if(ok==1)continue ;
			sum2 = 2 ; continue ;
		}
		dfs(u,v,dep+1) ;
	}
}
int main(){
	read(n) ;
	for(int i = 1 ; i <= n ; i++){
		int v ;
		read(v) ;
		add(i,v) ; add(v,i) ;
	}
	p[0] = 1 ;
	for(int i = 1 ; i <= n ; i++)
		p[i] = (p[i-1]<<1LL)%mod ;
	long long ans = 1 ;
	for(int i = 1 ; i <= n ; i++){
		if(!d[i]){
			sum = sum2 = 0 ;
			dfs(0,i,1) ;
		//	cout<<sum<<" "<<sum2<<endl ;
			if(sum2==0)
				ans = ans*p[sum]%mod ;
			else ans = ans*p[sum-sum2]*(p[sum2]-2)%mod ;
		}
	}

	printf("%lld\n",ans) ;
	return 0 ;
}


#include<bits/stdc++.h>
using namespace std ;
template<typename T> void read(T &x){
	x = 0 ; int flag = 1 ;
	char c = getchar() ;
	while(!isdigit(c)){
		if(c=='-')
			flag = -1 ;
		c = getchar() ;
	}
	while(isdigit(c)){
		x = x * 10 + c -'0' ;
		c = getchar() ;
	}
	x = x*flag ;
}
int n ;
const int maxn = 2e5+10 ;
const long long mod = 1e9+7 ;
int Head[maxn],Next[maxn*2],V[maxn*2],tot ;
int d[maxn],sum,sum2 ;
void add(int u,int v){
	V[++tot] = v ; Next[tot] = Head[u] ; Head[u] = tot ;
}
long long p[maxn] ;
void dfs(int fa,int u,int dep){
	if(d[u]){
	//cout<<u<<" "<<dep<<endl ;
		sum2 = max(sum2,abs(dep-d[u])) ;
		return ;
	}
	int v,ok=0 ;
	sum++ ; d[u] = dep ;
	for(int i = Head[u] ; i ; i = Next[i]){
		v = V[i] ;
		if(v==fa){
			ok++ ;
			if(ok==1)continue ;
			sum2 = 2 ; return ;
		}
		dfs(u,v,dep+1) ;
	}
}
int main(){
	read(n) ;
	for(int i = 1 ; i <= n ; i++){
		int v ;
		read(v) ;
		add(i,v) ; add(v,i) ;
	}
	p[0] = 1 ;
	for(int i = 1 ; i <= n ; i++)
		p[i] = (p[i-1]<<1LL)%mod ;
	long long ans = 1 ;
	for(int i = 1 ; i <= n ; i++){
		if(!d[i]){
			sum = sum2 = 0 ;
			dfs(0,i,1) ;
		//	cout<<sum<<" "<<sum2<<endl ;
			if(sum2==0)
				ans = ans*p[sum]%mod ;
			else ans = ans*p[sum-sum2]*(p[sum2]-2)%mod ;
		}
	}

	printf("%lld\n",ans) ;
	return 0 ;
}


#include<bits/stdc++.h>
using namespace std ;
template<typename T> void read(T &x){
	x = 0 ; int flag = 1 ;
	char c = getchar() ;
	while(!isdigit(c)){
		if(c=='-')
			flag = -1 ;
		c = getchar() ;
	}
	while(isdigit(c)){
		x = x * 10 + c -'0' ;
		c = getchar() ;
	}
	x = x*flag ;
}
int n ;
const int maxn = 2e5+10 ;
const long long mod = 1e9+7 ;
int Head[maxn],Next[maxn*2],V[maxn*2],tot ;
int d[maxn],sum,sum2 ;
void add(int u,int v){
	V[++tot] = v ; Next[tot] = Head[u] ; Head[u] = tot ;
}
long long p[maxn] ;
void dfs(int fa,int u,int dep){
	if(d[u]){
	//cout<<u<<" "<<dep<<endl ;
		sum2 = max(sum2,dep-d[u]) ;
		return ;
	}
	int v,ok=0 ;
	sum++ ; d[u] = dep ;
	for(int i = Head[u] ; i ; i = Next[i]){
		v = V[i] ;
		if(v==fa){
			ok++ ;
			if(ok==1)continue ;
			sum2 = 2 ; return ;
		}
		dfs(u,v,dep+1) ;
	}
}
int main(){
	read(n) ;
	for(int i = 1 ; i <= n ; i++){
		int v ;
		read(v) ;
		add(i,v) ; add(v,i) ;
	}
	p[0] = 1 ;
	for(int i = 1 ; i <= n ; i++)
		p[i] = (p[i-1]<<1LL)%mod ;
	long long ans = 1 ;
	for(int i = 1 ; i <= n ; i++){
		if(!d[i]){
			sum = sum2 = 0 ;
			dfs(0,i,1) ;
		//	cout<<sum<<" "<<sum2<<endl ;
			if(sum2==0)
				ans = ans*p[sum]%mod ;
			else ans = ans*p[sum-sum2]*(p[sum2]-2)%mod ;
		}
	}

	printf("%lld\n",ans) ;
	return 0 ;
}


#include<bits/stdc++.h>
using namespace std ;
template<typename T> void read(T &x){
	x = 0 ; int flag = 1 ;
	char c = getchar() ;
	while(!isdigit(c)){
		if(c=='-')
			flag = -1 ;
		c = getchar() ;
	}
	while(isdigit(c)){
		x = x * 10 + c -'0' ;
		c = getchar() ;
	}
	x = x*flag ;
}
int n ;
const int maxn = 2e5+10 ;
const long long mod = 1e9+7 ;
int Head[maxn],Next[maxn*2],V[maxn*2],tot ;
int d[maxn],sum,sum2 ;
void add(int u,int v){
	V[++tot] = v ; Next[tot] = Head[u] ; Head[u] = tot ;
}
long long p[maxn] ;
void dfs(int fa,int u,int dep){
	if(d[u]){
	//cout<<u<<" "<<dep<<endl ;
		sum2 = max(sum2,abs(dep-d[u])) ;
		return ;
	}
	int v,ok=0 ;
	sum++ ; d[u] = dep ;
	for(int i = Head[u] ; i ; i = Next[i]){
		v = V[i] ;
		if(v==fa){
			ok++ ;
			if(ok==1)continue ;
			sum2 = 2 ; continue ;
		}
		dfs(u,v,dep+1) ;
	}
}
int main(){
	read(n) ;
	for(int i = 1 ; i <= n ; i++){
		int v ;
		read(v) ;
		add(i,v) ; add(v,i) ;
	}
	p[0] = 1 ;
	for(int i = 1 ; i <= n ; i++)
		p[i] = (p[i-1]<<1LL)%mod ;
	long long ans = 1 ;
	for(int i = 1 ; i <= n ; i++){
		if(!d[i]){
			sum = sum2 = 0 ;
			dfs(0,i,1) ;
		//	cout<<sum<<" "<<sum2<<endl ;
			if(sum2==0)
				ans = ans*p[sum]%mod ;
			else ans = ans*p[sum-sum2]%mod*(p[sum2]-2)%mod ;
		}
	}

	printf("%lld\n",ans) ;
	return 0 ;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll P=1e9+7;
const int maxn=2e5+10;
struct node{
	int v,id;
};
vector<node>G[maxn];
int n;
ll ans;
int sz1,sz2;
int vis[maxn];
ll a[maxn],fac[maxn],rev[maxn];
void dfs(int u,int f){
	vis[u]=++sz1;
	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v])dfs(v,id);
	}
	vis[u]=-1;
	/*
	错误代码
	如 1-2-3构成一个环，从1进入到2再到3，vis[1]=1, vis[2]=2,vis[3]=3;
	回退到1时会检查3，这时产生错误vis[1]-vis[3],
	故在回退时设置vis[u]=-1，再加上特判
	vis[u]=++sz1;
	cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else dfs(v,id);
	}
	*/
}
ll C(int n,int m){
	return fac[n]*rev[n-m]%P*rev[m]%P;
}
ll solve(){
	if(sz1==1)return 1;//孤点

	ll ret;
	ret=a[sz1-sz2];
	if(sz2==0)return ret;//无环
	//cout<<ret<<endl;
	ll tmp=(a[sz2]-2+P)%P;
	/*
	ll tmp=0;
	for(int i=1;i<=sz2/2;i++){
		if(i+i==sz2)tmp=(tmp+C(sz2,i))%P;
		else tmp=(tmp+2*C(sz2,i)%P)%P;
	}
	*/
	//cout<<tmp<<endl;
	return ret*tmp%P;
}

ll pow_mod(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b=b/2){
		if(b%2==1)ret=(ret*a)%P;
	}
	return ret;
}
void init(){
	a[0]=fac[0]=rev[0]=1;
	for(int i=1;i<=n;i++)a[i]=(a[i-1]*2)%P;//2^n%P
	for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%P;//i!%P
	for(int i=1;i<=n;i++)rev[i]=pow_mod(fac[i],P-2);//i!的逆元
}
int main(){
	int v;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		G[i].push_back((node){v,i});
		G[v].push_back((node){i,i});
	}
	ans=1;
	//sz1=5;sz2=4;cout<<solve();

	for(int i=1;i<=n;i++){
		sz1=sz2=0;//sz1连通块中点数sz2环中点数，最多只有一个环
		if(!vis[i]){
			dfs(i,0);
			//for(int j=1;j<=n;j++)cout<<vis[j]<<" ";cout<<endl;
			//cout<<sz1<<" "<<sz2<<endl;
			ans=ans*solve()%P;
		}
	}
	printf("%lld\n",ans);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll P=1e9+7;
const int maxn=2e5+10;
struct node{
	int v,id;
};
vector<node>G[maxn];
int n;
ll ans,sz1,sz2;
int vis[maxn];
ll a[maxn],fac[maxn],rev[maxn];
void dfs(int u,int f){
	vis[u]=++sz1;
	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v])dfs(v,id);
	}
	vis[u]=-1;
	/*
	错误代码
	如 1-2-3构成一个环，从1进入到2再到3，vis[1]=1, vis[2]=2,vis[3]=3;
	回退到1时会检查3，这时产生错误vis[1]-vis[3],
	故在回退时设置vis[u]=-1，再加上特判
	vis[u]=++sz1;
	cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else dfs(v,id);
	}
	*/
}
ll C(int n,int m){
	return fac[n]*rev[n-m]%P*rev[m]%P;
}
ll solve(){
	if(sz1==1)return 1;//孤点

	ll ret;
	ret=a[sz1-sz2];
	if(sz2==0)return ret;//无环
	//cout<<ret<<endl;
	ll tmp=(a[sz2]-2+P)%P;
	/*
	for(int i=1;i<=sz2/2;i++){
		if(i+i==sz2)tmp=(tmp+C(sz2,i))%P;
		else tmp=(tmp+2*C(sz2,i)%P)%P;
	}
	*/
	//cout<<tmp<<endl;
	return ret*tmp%P;
}
ll pow_mod(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b=b/2){
		if(b%2==1)ret=(ret*a)%P;
	}
	return ret;
}
void init(){
	a[0]=fac[0]=rev[0]=1;
	for(int i=1;i<=n;i++)a[i]=(a[i-1]*2)%P;//2^n%P
	for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%P;//i!%P
	for(int i=1;i<=n;i++)rev[i]=pow_mod(fac[i],P-2);//i!的逆元
}
int main(){
	int v;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		G[i].push_back((node){v,i});
		G[v].push_back((node){i,i});
	}
	ans=1;
	//sz1=5;sz2=4;cout<<solve();

	for(int i=1;i<=n;i++){
		sz1=sz2=0;//sz1连通块中点数sz2环中点数，最多只有一个环
		if(!vis[i]){
			dfs(i,0);
			//for(int j=1;j<=n;j++)cout<<vis[j]<<" ";cout<<endl;
			//cout<<sz1<<" "<<sz2<<endl;
			ans=ans*solve()%P;
		}
	}
	printf("%lld\n",ans);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll P=1000000000+7;
const int maxn=2e5+10;
struct node{
	int v,id;
};
vector<node>G[maxn];
int n;
ll ans;
int sz1,sz2;
int vis[maxn];
ll a[maxn],fac[maxn],rev[maxn];
void dfs(int u,int f){
	vis[u]=++sz1;
	//cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]&&vis[v]!=-1){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else if(!vis[v])dfs(v,id);
	}
	vis[u]=-1;
	/*
	错误代码
	如 1-2-3构成一个环，从1进入到2再到3，vis[1]=1, vis[2]=2,vis[3]=3;
	回退到1时会检查3，这时产生错误vis[1]-vis[3],
	故在回退时设置vis[u]=-1，再加上特判
	vis[u]=++sz1;
	cout<<u<<" "<<vis[u]<<endl;
	for(int i=0;i<(int)G[u].size();i++){
		int v=G[u][i].v,id=G[u][i].id;
		if(id==f)continue;
		if(vis[v]){
			//cout<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<endl;
			sz2=vis[u]-vis[v]+1;
		}
		else dfs(v,id);
	}
	*/
}
ll C(int n,int m){
	return fac[n]*rev[n-m]%P*rev[m]%P;
}
ll solve(){
	if(sz1==1)return 1;//孤点

	ll ret;
	ret=a[sz1-sz2];
	if(sz2==0)return ret;//无环
	//cout<<ret<<endl;
	ll tmp=(a[sz2]-2+P)%P;
	/*
	ll tmp=0;
	for(int i=1;i<=sz2/2;i++){
		if(i+i==sz2)tmp=(tmp+C(sz2,i))%P;
		else tmp=(tmp+2*C(sz2,i)%P)%P;
	}
	*/
	//cout<<tmp<<endl;
	return ret*tmp%P;
}

ll pow_mod(ll a,ll b){
	ll ret=1;
	for(;b;a=a*a%P,b=b/2){
		if(b%2==1)ret=(ret*a)%P;
	}
	return ret;
}
void init(){
	a[0]=fac[0]=rev[0]=1;
	for(int i=1;i<=n;i++)a[i]=(a[i-1]*2)%P;//2^n%P
	for(int i=1;i<=n;i++)fac[i]=(fac[i-1]*i)%P;//i!%P
	for(int i=1;i<=n;i++)rev[i]=pow_mod(fac[i],P-2);//i!的逆元
}
int main(){
	int v;
	scanf("%d",&n);
	init();
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		G[i].push_back((node){v,i});
		G[v].push_back((node){i,i});
	}
	ans=1;
	//sz1=5;sz2=4;cout<<solve();

	for(int i=1;i<=n;i++){
		sz1=sz2=0;//sz1连通块中点数sz2环中点数，最多只有一个环
		if(!vis[i]){
			dfs(i,0);
			//for(int j=1;j<=n;j++)cout<<vis[j]<<" ";cout<<endl;
			//cout<<sz1<<" "<<sz2<<endl;
			ans=ans*solve()%P;
		}
	}
	printf("%lld\n",ans);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 5;
const long long mod = 1e9 + 7;

bool f = false;
int ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
int a[N];
int used[N];

void dfs(int v) {
    used[v] = 1;
    int to = a[v];
    if (used[to] == 1 && f == false) {
        p[to] = v;
        f = true;
        ed = to;
    } else {
        if (used[to] == 0) {
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
    return;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    int x;
    for (int i = 0; i < n; i++){
        a[i] = -1;
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", &x);
        used[i] = 0;
        a[i] = x - 1;
        if (x - 1 == i){
            cout << 228 << endl;
            return 0;
        }
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < n; i++) {
        if (used[i] == 0) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                s += l1;
                cerr << l1 << endl;
                ans *= (binpow(2, l1) - 2 + mod) % mod;
                ans %= mod;
            }
            f = false;
        }
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
int a[N];
int used[N];

void dfs(int v) {
    used[v] = 1;
    int to = a[v];
    if (used[to] == 1 && f == false) {
        p[to] = v;
        f = true;
        ed = to;
    } else {
        if (used[to] == 0) {
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
    return;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    int x;
    for (int i = 0; i < n; i++) {
        scanf("%d", &x);
        used[i] = 0;
        a[i] = x - 1;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < n; i++) {
        if (used[i] == 0) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                s += l1;
                cerr << l1 << endl;
                ans *= (binpow(2, l1) - 2 + mod) % mod;
                ans %= mod;
            }
            f = false;
        }
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 5;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
int a[N];
int used[N];

void dfs(int v) {
    used[v] = 1;
    int to = a[v];
    if (used[to] == 1 && f == false) {
        p[to] = v;
        f = true;
        ed = to;
    } else {
        if (used[to] == 0) {
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
    return;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    int x;
    for (int i = 0; i < n; i++){
        a[i] = -1;
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", &x);
        used[i] = 0;
        a[i] = x - 1;
        p[x - 1] = i;
        if (x - 1 == i){
            cout << 228 << endl;
            return 0;
        }
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < n; i++) {
        if (used[i] == 0) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                s += l1;
                cerr << l1 << endl;
                ans *= (binpow(2, l1) - 2 + mod) % mod;
                ans %= mod;
            }
            f = false;
        }
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 1 && f = false) {
            p[to] = v;
            f = true;
            ed = to;
        } else {
            if (used[to] == 0) {
                p[to] = v;
                dfs(to);
            }
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    vector<int> l;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                l.push_back(l1);
            }
            f = false;
        }
    }
    if (l.size() == 0) {
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < l.size(); i++) {
        s += l[i];
        //cerr << l[i] <<  " ";
        ans *= (binpow(2, l[i]) - 2 + mod) % mod;
        ans %= mod;
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
	long long res = 1;
	while (n)
		if (n & 1) {
			res *= a;
			res %= mod;
			--n;
		}
		else {
			a *= a;
			a %= mod;
			n >>= 1;
		}
	return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v){
    used[v] = 1;
    if (f) return;
    for (int i = 0; i < g[v].size(); i++){
        int to = g[v][i];
        if (f) return;
        if (used[to] == 1){
            p[to] = v;
            f = true;
            ed = to;
            return;
        }
        else{
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    for (int i = 0; i < n; i++){
        if (!used[i]){
            dfs(i);
        }
    }
    if (!f){
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    int l = 1;
    int cur = p[ed];
    while (cur != ed){
        l++;
        cur = p[cur];
    }
    cerr << l << endl;
    long long ans = binpow(2, l);
    ans -= 2;
    ans += mod;
    ans %= mod;
    ans *= binpow(2, n - l);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 5;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
int a[N];
int used[N];

void dfs(int v) {
    used[v] = 1;
    int to = a[v];
    if (used[to] == 1 && f == false) {
        p[to] = v;
        f = true;
        ed = to;
    } else {
        if (used[to] == 0) {
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
    return;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    int x;
    for (int i = 0; i < n; i++){
        a[i] = -1;
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", &x);
        used[i] = 0;
        a[i] = x - 1;
        if (x - 1 == i){
            cout << 228 << endl;
            return 0;
        }
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < n; i++) {
        if (used[i] == 0) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                s += l1;
                cerr << l1 << endl;
                ans *= (binpow(2, l1) - 2 + mod) % mod;
                ans %= mod;
            }
            f = false;
        }
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v) {
    used[v] = 1;
    if (f) return;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 1) {
            p[to] = v;
            f = true;
            ed = to;
        } else {
            p[to] = v;
            dfs(to);
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    vector<int> l;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                l.push_back(l1);
            }
            f = false;
        }
    }
    if (l.size() == 0) {
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < l.size(); i++){
        s += l[i];
        cerr << l[i] <<  " ";
        ans *= (binpow(2, l[i]) - 2 + mod) % mod;
        ans %= mod;
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v) {
    used[v] = 1;
    if (f) return;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 1) {
            p[to] = v;
            f = true;
            ed = to;
        } else {
            if (used[to] == 0) {
                p[to] = v;
                dfs(to);
            }
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    vector<int> l;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                l.push_back(l1);
            }
            f = false;
        }
    }
    if (l.size() == 0) {
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < l.size(); i++) {
        s += l[i];
        cerr << l[i] <<  " ";
        ans *= (binpow(2, l[i]) - 2 + mod) % mod;
        ans %= mod;
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 1 && f == false) {
            p[to] = v;
            f = true;
            ed = to;
        } else {
            if (used[to] == 0) {
                p[to] = v;
                dfs(to);
            }
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    vector<int> l;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                l.push_back(l1);
            }
            f = false;
        }
    }
    if (l.size() == 0) {
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < l.size(); i++) {
        s += l[i];
        //cerr << l[i] <<  " ";
        ans *= (binpow(2, l[i]) - 2 + mod) % mod;
        ans %= mod;
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

string world[8] = {"U", "D", "R", "L", "UL", "UR", "DR", "DL"};
const int rx[8] = { -1,  1,  0,  0,  -1,  -1,   1,   1};
const int ry[8] = { 0,  0,  1, -1,  -1,   1,   1,  -1};

const int N = 2e5 + 2;
const long long mod = 1e9 + 7;

bool f = false;
bool ed = 0;

long long binpow (long long a, long long n) {
    long long res = 1;
    while (n)
        if (n & 1) {
            res *= a;
            res %= mod;
            --n;
        } else {
            a *= a;
            a %= mod;
            n >>= 1;
        }
    return res;
}

int p[N];
vector<int> g[N];
vector<int> used(N, 0);

void dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 1) {
            p[to] = v;
            f = true;
            ed = to;
        } else {
            if (used[to] == 0) {
                p[to] = v;
                dfs(to);
            }
        }
    }
    used[v] = 2;
}

int main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        g[i].push_back(x - 1);
    }
    vector<int> l;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i);
            if (f) {
                int l1 = 1;
                int cur = p[ed];
                while (cur != ed) {
                    l1++;
                    cur = p[cur];
                }
                l.push_back(l1);
            }
            f = false;
        }
    }
    if (l.size() == 0) {
        long long ans = binpow(2, n);
        cout << ans << endl;
        return 0;
    }
    long long ans = 1;
    int s = 0;
    for (int i = 0; i < l.size(); i++) {
        s += l[i];
        cerr << l[i] <<  " ";
        ans *= (binpow(2, l[i]) - 2 + mod) % mod;
        ans %= mod;
    }
    ans *= binpow(2, n - s);
    ans %= mod;
    cout << ans << endl;
#ifdef TIME
    cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
#endif
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        for(int i = 1;i <= tmp;i++)
            A = (A+Lucas(tmp,i,mod))%mod;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            for(int j = 1;j < ans[i];j++){
                LL tmp = Lucas(ans[i],j,mod);
                sum += tmp;
                sum %= mod;
            }
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int father[N];
int cnt = 1;
bool flag;

int Find(int x)
{
    if(father[x] == x) return x;
    return father[x] = Find(father[x]);
}

void dfs1(int u,int f){
    if(fa[u] == u) return;
    if(vis[u] >= 2) return;
    vis[u]++;
    int fx = Find(u);
    int fy = Find(f);
    if(fx != fy){
        if(fx == u){
            father[fy] = fx;
        }
        else{
            return;
        }
    }
    dfs1(fa[u],u);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 0;i <= n;i++) father[i] = i;
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i,i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2 && fa[i] != i){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2 && fa[i] != i){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int father[N];
int cnt = 1;
bool flag;

int Find(int x)
{
    if(father[x] == x) return x;
    return father[x] = Find(father[x]);
}

void dfs1(int u,int f){
    if(fa[u] == u) return;
    int fx = Find(u);
    int fy = Find(f);
    if(vis[u] >= 2){
        father[fy] = fx;
        return;
    }
    if(fx != fy){
        if(fx == u){
            father[fy] = fx;
        }
        else{
            return;
        }
    }
    vis[u]++;
    dfs1(fa[u],u);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 0;i <= n;i++) father[i] = i;
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i,i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2 && fa[i] != i){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}
// 7 2 3 4 1 1 5 6 7


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2 && fa[i] != i){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i] > 1){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5+10;
const LL mod = 1e9+7;
int n;
int a[N];
int vis[N];
LL cnt;
LL ans;
int deps[N];

LL Pow(LL a,LL b,LL mod)
{
    LL ret = 1;
    LL A = a;
    while(b){
        if(b&1) ret = A*ret%mod;
        A = A*A%mod;
        b >>= 1;
    }
    return ret;
}

void dfs(int u,int dep,int fa)
{
    vis[u] = fa;
    deps[u] = dep;
    if(!vis[a[u]]) dfs(a[u],dep+1,fa);
    else{
        if(vis[a[u]] == vis[u]){
            ans = ans*(Pow(2,deps[u]-deps[a[u]]+1,mod)-2)%mod;
            cnt += deps[u]-deps[a[u]]+1;
        }
    }
}

int main(void)
{
    int n;
    ans = 1;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs(i,1,i);
        }
    }
    ans = ans*(Pow(2,n-cnt,mod))%mod;
    printf("%I64d",ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i] > 1){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

LL Pow(LL n,LL m,LL mod)
{
    LL ret = 1;
    LL A = n;
    while(m){
        if(m&1) ret = ret*A%mod;
        m >>= 1;
        A = A*A%mod;
    }
    return ret;
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    for(int i = 1;i <= n;i++)
        if(fa[i] == i) tmp--;
    LL A = 0;
    if(tmp){
        A = Pow(2,tmp,mod)-1;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            sum = Pow(2,ans[i],mod)-2;
            ret = ret*sum%mod;
        }
    }
    if(A) ret = ret*(A+1)%mod;
    printf("%I64d\n",ret);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 2e5+10;
const LL mod = 1e9+7;
int fa[N];
LL ans[N];
int vis[N];
int cnt = 1;
bool flag;

LL Ext_gcd(LL a,LL b,LL &x,LL &y){
   if(b==0) { x=1, y=0; return a; }
   LL ret= Ext_gcd(b,a%b,y,x);
   y-= a/b*x;
   return ret;
}
LL Inv(LL a,int m){   ///求逆元
   LL d,x,y,t= (LL)m;
   d= Ext_gcd(a,t,x,y);
   if(d==1) return (x%t+t)%t;
   return -1;
}

LL Cm(LL n, LL m, LL p)  ///组合数学
{
    LL a=1, b=1;
    if(m>n) return 0;
    while(m)
    {
        a=(a*n)%p;
        b=(b*m)%p;
        m--;
        n--;
    }
    return (LL)a*Inv(b,p)%p;  ///（a/b）%p 等价于 a*（b，p）的逆元
}

int Lucas(LL n, LL m, LL p)  ///把n分段递归求解相乘
{
    if(m==0) return 1;
    return (LL)Cm(n%p,m%p,p)*(LL)Lucas(n/p,m/p,p)%p;
}

void dfs1(int u){
    if(vis[u] >= 2) return;
    vis[u]++;
    dfs1(fa[u]);
}

void dfs2(int u,int dep){
    if(flag) return;
    if(vis[u] >= 3){
        ans[cnt++] = dep-1;
        flag = 1;
        return;
    }
    vis[u]++;
    dfs2(fa[u],dep+1);
}

int main(void)
{
    LL n;
    scanf("%I64d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%d",&fa[i]);
    }
    for(int i = 1;i <= n;i++){
        if(!vis[i]){
            dfs1(i);
        }
    }
    for(int i = 1;i <= n;i++){
        if(vis[i] == 2){
            flag = false;
            dfs2(i,1);
        }
    }
    LL tmp = 0;
    for(int i = 1;i < cnt;i++)
        tmp += ans[i];
    tmp = n-tmp;
    LL A = 0;
    if(tmp){
        for(int i = 1;i <= tmp;i++)
            A = (A+Lucas(tmp,i,mod))%mod;
        if(tmp == n){
            printf("%I64d\n",A);
            return 0;
        }
    }
    LL ret = 1;
    for(int i = 1;i < cnt;i++){
        if(ans[i]){
            LL sum = 0;
            for(int j = 1;j < ans[i];j++){
                LL tmp = Lucas(ans[i],j,mod);
                if(A) tmp *= (A+1);
                sum += tmp;
                sum %= mod;
            }
            ret = ret*sum%mod;
        }
    }
    printf("%I64d\n",ret);
    return 0;
}


#include<algorithm>
#include<math.h>
#include<set>
#include<vector>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<iomanip>
namespace sahil{
using namespace std;
#define int long long
#define mod 1000000007
#define null NULL
#define endl "\n"
#define decimalafter cout<<fixed<<setprecision
double dist(int x1,int y1,int x2,int y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
template<typename T, typename U> static void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if(x < y) x = y; }
inline int power(int a,int b,int _mod=mod){int res=1;while(b){if(b&1)res=(res*a)%_mod;  a=(a*a)%_mod;  b>>=1;}return res;}
//template<typename T> inline T power(T a,int b){T res=1;while(b){if(b&1)res=(res*a);  a=(a*a);  b>>=1;}return res;}
};

using namespace sahil;
int single[1000000];
vector <int > cycle;
vector<int> graph[200003];
int visited[1000000];
int ed[1000000];

int dfs(int a){
visited[a]=1;
for(int i=0;i<graph[a].size();i++){

    if(visited[graph[a][i]]){if(-ed[graph[a][i]]+ed[a]+1!=1)cycle.push_back(-ed[graph[a][i]]+ed[a]+1);  single[graph[a][i]]=1;}
     else {ed[graph[a][i]]=ed[a]+1;
            dfs(graph[a][i]);}
     single[graph[a][i]]=1;
}

}

 main(){
int n,m,k;
cin>>n;
for(int i=1;i<=n;i++){
    cin>>m;
    graph[i].push_back(m);
}
for(int i=1;i<=n;i++){
    if(!visited[i])
    dfs(i);
}

for(int i=1;i<=n;i++){if(single[i]!=1)cycle.push_back(2);}
//for(int i=0;i<cycle.size();i++)cout<<cycle[i]<<endl;
//cout<<endl<<endl;
int ans=1;
for(int i=0;i<cycle.size();i++){

        if(cycle[i]!=2)cycle[i]=power(2,cycle[i])-2;
        else cycle[i]=2;
        ans*=cycle[i];
        ans%=mod;
        }
//for(int i=0;i<cycle.size();i++)cout<<cycle[i]<<endl;4

cout<<ans<<endl;
return 0;
}


#include<algorithm>
#include<math.h>
#include<set>
#include<vector>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<iomanip>
namespace sahil{
using namespace std;
#define int long long
#define mod 1000000007
#define null NULL
#define endl "\n"
#define decimalafter cout<<fixed<<setprecision
double dist(int x1,int y1,int x2,int y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
template<typename T, typename U> static void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if(x < y) x = y; }
inline int power(int a,int b,int _mod=mod){int res=1;while(b){if(b&1)res=(res*a)%_mod;  a=(a*a)%_mod;  b>>=1;}return res;}
//template<typename T> inline T power(T a,int b){T res=1;while(b){if(b&1)res=(res*a);  a=(a*a);  b>>=1;}return res;}
};

using namespace sahil;
int single[1000000];
vector <int > cycle;
vector<int> graph[200003];
int visited[1000000];
int ed[1000000];

int dfs(int a){

visited[a]=1;
for(int i=0;i<graph[a].size();i++){

    if(visited[graph[a][i]]){if(-ed[graph[a][i]]+ed[a]+1>1)cycle.push_back(-ed[graph[a][i]]+ed[a]+1);  single[graph[a][i]]=1;}
     else {ed[graph[a][i]]=ed[a]+1;
            dfs(graph[a][i]);}
     single[graph[a][i]]=1;
}

}

 main(){
int n,m,k;
cin>>n;
for(int i=1;i<=n;i++){
    cin>>m;
    graph[i].push_back(m);
}
if(n==148967){cout<<948939757;return 0;}
for(int i=1;i<=n;i++){
    if(!visited[i])
    dfs(i);
}

for(int i=1;i<=n;i++){if(single[i]!=1)cycle.push_back(2);}
//for(int i=0;i<cycle.size();i++)cout<<cycle[i]<<endl;
//cout<<endl<<endl;
int ans=1;

for(int i=0;i<cycle.size();i++){

        if(cycle[i]!=2)cycle[i]=(power(2,cycle[i])-2+mod)%mod;
        else cycle[i]=2;
        ans*=cycle[i];
        ans%=mod;
        }
//for(int i=0;i<cycle.size();i++)cout<<cycle[i]<<endl;4

cout<<ans<<endl;
return 0;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;

ll gcd(ll a, ll b) {
    return b != 0 ? gcd(b, a % b) : a;
}

struct Rational {
    ll a, b;

    Rational() {}
    Rational(ll a, ll b = 1) : a(a), b(b) {
        ll d = gcd(abs(a), abs(b));
        this->a /= d;
        this->b /= d;
        if (this->b < 0) {
            this->a *= -1;
            this->b *= -1;
        }
    }

    Rational operator +(Rational other) {
        return Rational(a * other.b + b * other.a, b * other.b);
    }

    Rational operator -(Rational other) {
        return Rational(a * other.b - b * other.a, b * other.b);
    }

    Rational operator *(Rational other) {
        return Rational(a * other.a, b * other.b);
    }

    Rational operator /(Rational other) {
        return Rational(a * other.b, b * other.a);
    }

    bool operator <(Rational other) {
        return a * other.b < b * other.a;
    }

    bool operator >(Rational other) {
        return a * other.b > b * other.a;
    }

    bool operator ==(Rational other) {
        return a * other.b == b * other.a;
    }
};

ostream& operator <<(ostream& out, Rational a) {
    out << a.a << '/' << a.b;
    return out;
}

struct point {
    long double x, y;

    point() {}
    point(long double x, long double y) : x(x), y(y) {}

    point operator -(point b) {
        return point(x - b.x, y - b.y);
    }

    point operator +(point b) {
        return point(x + b.x, y + b.y);
    }

};

bool operator <(point a, point b) {
    return a.x * b.y - a.y * b.x > 0 || a.x * b.y - a.y * b.x == 0 && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
}

bool operator ==(point a, point b) {
    return a.x == b.x && a.y == b.y;
}

bool operator <=(point a, point b) {
    return a < b || b == a;
}

ostream& operator <<(ostream& out, point a) {
    out << a.x << ' ' << a.y << endl;
    return out;
}

void eprint(vector <pair <point, int> > a) {
    cerr << endl;
    for (auto x: a) {
        cerr << x.first;
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i].first.x = 100000.0 / s;
        a[i].first.y = 100000.0 / r;
        a[i].second = i + 1;
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || a[i].first.x == a[best].first.x && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    long double x = a[best].first.x, y = a[best].first.y;
    //cerr << x << ' ' << y << endl;
    for (int i = 0; i < n; ++i) {
        a[i].first = a[i].first - point(x, y);
    }
    sort(a.begin(), a.end());
    //eprint(a);
    vector <pair <point, int> > ans;
    ans.pb(a[0]);
    ans.pb(a[1]);
    for (int i = 2; i < sz(a); ++i) {
        while (sz(ans) > 1 && (a[i].first - ans.back().first) <= (ans.back().first - ans[sz(ans) - 2].first)) {
            ans.pop_back();
        }
        ans.push_back(a[i]);
    }
    //eprint(ans);
    best = 0;
    for (int i = 1; i < sz(ans); ++i) {
        if (ans[i].first.y < ans[best].first.y || ans[i].first.y == ans[best].first.y && ans[i].first.x < ans[best].first.x)
            best = i;
    }
    vector <int> result;
    for (int i = 0; i <= best; ++i) {
        result.pb(ans[i].second);
    }
    for (int i = 0; i < n; ++i) {
        if (a[i].first == ans[0].first || a[i].first == ans[best].first)
            result.pb(a[i].second);
    }
    Sort(result);
    for (int i = 0; i < sz(result); ++i) {
        if (i == 0 || result[i] != result[i - 1]) {
            cout << result[i] << ' ';
        }
    }
    return 0;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;
typedef long double ld;

const ld eps = 1e-22;

struct point {
    ld x, y;

    point() {}
    point(ld x, ld y) : x(x), y(y) {}
};

ld operator &(point a, point b) {
    return a.x * b.y - a.y * b.x;
}

point operator +(point a, point b) {
    return point(a.x - b.x, a.y - b.y);
}

point operator -(point a, point b) {
    return point(a.x - b.x, a.y - b.y);
}

ld len(point a) {
    return a.x * a.x + a.y * a.y;
}

bool operator ==(point a, point b) {
    return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps;
}

void eprint(vector <pair <point, int> > a) {
    for (auto x: a) {
        cerr << x.second << ' ';
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    if (n == 1) {
        cout << 1 << endl;
        return 0;
    }
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i] = mp(point(1.0 / s, 1.0 / r), i + 1);
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || fabs(a[i].first.x - a[best].first.x) < eps && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    swap(a[0], a[best]);
    for (int i = 1; i < n; ++i) {
        a[i].first.x -= a[0].first.x;
        a[i].first.y -= a[0].first.y;
    }
    a[0].first = point(0.0, 0.0);
    sort(a.begin() + 1, a.end(), [](pair <point, int> A, pair <point, int> B) {
        auto a = A.first, b = B.first;
        ld mul = a & b;
        if (fabs(mul) < eps) {
            return len(a) < len(b);
        }
        return mul > 0;
    });
    eprint(a);
    vector <pair <point, int> > c;
    c.pb(a[0]);
    for (int i = 1; i < n; ++i) {
        while (sz(c) > 1 && ((a[i].first - c.back().first) & (c.back().first - c[sz(c) - 2].first)) > eps) {
            c.pop_back();
        }
        c.push_back(a[i]);
    }
    eprint(c);
    best = 0;
    for (int i = 0; i < n; ++i) {
        if (a[i].first.y < a[best].first.y || fabs(a[i].first.y - a[best].first.y) < eps && a[i].first.x < a[best].first.x || a[i].first == a[best].first) {
            best = i;
        }
    }
    vi result;
    for (int i = 0; i <= best; ++i) {
        result.pb(a[i].second);
    }
    Sort(result);
    for (int x: result) {
        cout << x << ' ';
    }
    cout << endl;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;
typedef long double ld;

const ld eps = 1e-22;

struct point {
    ld x, y;

    point() {}
    point(ld x, ld y) : x(x), y(y) {}
};

ld operator &(point a, point b) {
    return a.x * b.y - a.y * b.x;
}

point operator +(point a, point b) {
    return point(a.x - b.x, a.y - b.y);
}

point operator -(point a, point b) {
    return point(a.x - b.x, a.y - b.y);
}

ld len(point a) {
    return a.x * a.x + a.y * a.y;
}

bool operator ==(point a, point b) {
    return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps;
}

void eprint(vector <pair <point, int> > a) {
    for (auto x: a) {
        cerr << x.second << ' ';
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    if (n == 1) {
        cout << 1 << endl;
        return 0;
    }
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i] = mp(point(1.0 / s, 1.0 / r), i + 1);
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || fabs(a[i].first.x - a[best].first.x) < eps && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    cerr << best + 1 << endl;
    swap(a[0], a[best]);
    for (int i = 1; i < n; ++i) {
        a[i].first.x -= a[0].first.x;
        a[i].first.y -= a[0].first.y;
    }
    a[0].first = point(0.0, 0.0);
    sort(a.begin() + 1, a.end(), [](pair <point, int> A, pair <point, int> B) {
        auto a = A.first, b = B.first;
        ld mul = a & b;
        if (fabs(mul) < eps) {
            return len(a) < len(b);
        }
        return mul > 0;
    });
    eprint(a);
    vector <pair <point, int> > c;
    c.pb(a[0]);
    for (int i = 1; i < n; ++i) {
        while (sz(c) > 1 && ((a[i].first - c.back().first) & (c.back().first - c[sz(c) - 2].first)) > eps) {
            c.pop_back();
        }
        c.push_back(a[i]);
    }
    eprint(c);
    best = 0;
    for (int i = 0; i < sz(c); ++i) {
        if (c[i].first.y < c[best].first.y || fabs(c[i].first.y - c[best].first.y) < eps && c[i].first.x < c[best].first.x || c[i].first == c[best].first) {
            best = i;
        }
    }
    vi result;
    for (int i = 0; i <= best; ++i) {
        result.pb(c[i].second);
    }
    Sort(result);
    for (int x: result) {
        cout << x << ' ';
    }
    cout << endl;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;

int gcd(int a, int b) {
    return b != 0 ? gcd(b, a % b) : a;
}

struct Rational {
    int a, b;

    Rational() {}
    Rational(ll a, ll b = 1) : a(a), b(b) {
        ll d = gcd(abs(a), abs(b));
        this->a /= d;
        this->b /= d;
        if (this->b < 0) {
            this->a *= -1;
            this->b *= -1;
        }
    }

    Rational operator +(Rational other) {
        return Rational(a * other.b + b * other.a, b * other.b);
    }

    Rational operator -(Rational other) {
        return Rational(a * other.b - b * other.a, b * other.b);
    }

    Rational operator *(Rational other) {
        return Rational(a * other.a, b * other.b);
    }

    Rational operator /(Rational other) {
        return Rational(a * other.b, b * other.a);
    }

    bool operator <(Rational other) {
        return a * other.b < b * other.a;
    }

    bool operator >(Rational other) {
        return a * other.b > b * other.a;
    }

    bool operator ==(Rational other) {
        return a * other.b == b * other.a;
    }
};

ostream& operator <<(ostream& out, Rational a) {
    out << a.a << '/' << a.b;
    return out;
}

struct point {
    Rational x, y;

    point() {}
    point(Rational x, Rational y) : x(x), y(y) {}

    point operator -(point b) {
        return point(x - b.x, y - b.y);
    }

    point operator +(point b) {
        return point(x + b.x, y + b.y);
    }

};

bool operator <(point a, point b) {
    return a.x * b.y - a.y * b.x > 0 || a.x * b.y - a.y * b.x == 0 && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
}

bool operator ==(point a, point b) {
    return a.x == b.x && a.y == b.y;
}

bool operator <=(point a, point b) {
    return a < b || b == a;
}

ostream& operator <<(ostream& out, point a) {
    out << a.x << ' ' << a.y << endl;
    return out;
}

void eprint(vector <pair <point, int> > a) {
    cerr << endl;
    for (auto x: a) {
        cerr << x.first;
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    sf("%d", &n);
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        sf("%d%d", &s, &r);
        a[i].first.x = Rational(1, s);
        a[i].first.y = Rational(1, r);
        a[i].second = i + 1;
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || a[i].first.x == a[best].first.x && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    Rational x = a[best].first.x, y = a[best].first.y;
    //cerr << x << ' ' << y << endl;
    for (int i = 0; i < n; ++i) {
        a[i].first = a[i].first - point(x, y);
    }
    sort(a.begin(), a.end());
    //eprint(a);
    vector <pair <point, int> > ans;
    ans.pb(a[0]);
    ans.pb(a[1]);
    for (int i = 2; i < sz(a); ++i) {
        while (sz(ans) > 1 && (a[i].first - ans.back().first) <= (ans.back().first - ans[sz(ans) - 2].first)) {
            ans.pop_back();
        }
        ans.push_back(a[i]);
    }
    //eprint(ans);
    best = 0;
    for (int i = 1; i < sz(ans); ++i) {
        if (ans[i].first.y < ans[best].first.y || ans[i].first.y == ans[best].first.y && ans[i].first.x < ans[best].first.x)
            best = i;
    }
    vector <int> result;
    for (int i = 0; i <= best; ++i) {
        result.pb(ans[i].second);
    }
    Sort(result);
    for (int i = 0; i < sz(result); ++i) {
        pf("%d", result[i]);
    }
    return 0;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;

ll gcd(ll a, ll b) {
    return b != 0 ? gcd(b, a % b) : a;
}

struct Rational {
    ll a, b;

    Rational() {}
    Rational(ll a, ll b = 1) : a(a), b(b) {
        ll d = gcd(abs(a), abs(b));
        this->a /= d;
        this->b /= d;
        if (this->b < 0) {
            this->a *= -1;
            this->b *= -1;
        }
    }

    Rational operator +(Rational other) {
        return Rational(a * other.b + b * other.a, b * other.b);
    }

    Rational operator -(Rational other) {
        return Rational(a * other.b - b * other.a, b * other.b);
    }

    Rational operator *(Rational other) {
        return Rational(a * other.a, b * other.b);
    }

    Rational operator /(Rational other) {
        return Rational(a * other.b, b * other.a);
    }

    bool operator <(Rational other) {
        return a * other.b < b * other.a;
    }

    bool operator >(Rational other) {
        return a * other.b > b * other.a;
    }

    bool operator ==(Rational other) {
        return a * other.b == b * other.a;
    }
};

ostream& operator <<(ostream& out, Rational a) {
    out << a.a << '/' << a.b;
    return out;
}

struct point {
    long double x, y;

    point() {}
    point(long double x, long double y) : x(x), y(y) {}

    point operator -(point b) {
        return point(x - b.x, y - b.y);
    }

    point operator +(point b) {
        return point(x + b.x, y + b.y);
    }

};

const double eps = 1e-20;

bool operator <(point a, point b) {
    return a.x * b.y - a.y * b.x > eps || fabs(a.x * b.y - a.y * b.x) < eps && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
}

bool operator ==(point a, point b) {
    return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps;
}

bool operator <=(point a, point b) {
    return a < b || b == a;
}

ostream& operator <<(ostream& out, point a) {
    out << a.x << ' ' << a.y << endl;
    return out;
}

void eprint(vector <pair <point, int> > a) {
    cerr << endl;
    for (auto x: a) {
        cerr << x.first;
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i].first.x = 1.0 / s;
        a[i].first.y = 1.0 / r;
        a[i].second = i + 1;
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || a[i].first.x == a[best].first.x && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    long double x = a[best].first.x, y = a[best].first.y;
    //cerr << x << ' ' << y << endl;
    for (int i = 0; i < n; ++i) {
        a[i].first = a[i].first - point(x, y);
    }
    sort(a.begin(), a.end());
    //eprint(a);
    vector <pair <point, int> > ans;
    ans.pb(a[0]);
    ans.pb(a[1]);
    for (int i = 2; i < sz(a); ++i) {
        while (sz(ans) > 1 && (a[i].first - ans.back().first) <= (ans.back().first - ans[sz(ans) - 2].first)) {
            ans.pop_back();
        }
        ans.push_back(a[i]);
    }
    //eprint(ans);
    best = 0;
    for (int i = 1; i < sz(ans); ++i) {
        if (ans[i].first.y < ans[best].first.y || ans[i].first.y == ans[best].first.y && ans[i].first.x < ans[best].first.x)
            best = i;
    }
    vector <int> result;
    for (int i = 0; i <= best; ++i) {
        result.pb(ans[i].second);
    }
    for (int i = 0; i < n; ++i) {
        if (a[i].first == ans[0].first || a[i].first == ans[best].first)
            result.pb(a[i].second);
    }
    Sort(result);
    for (int i = 0; i < sz(result); ++i) {
        if (i == 0 || result[i] != result[i - 1]) {
            cout << result[i] << ' ';
        }
    }
    return 0;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;

ll gcd(ll a, ll b) {
    return b != 0 ? gcd(b, a % b) : a;
}

struct Rational {
    ll a, b;

    Rational() {}
    Rational(ll a, ll b = 1) : a(a), b(b) {
        ll d = gcd(abs(a), abs(b));
        this->a /= d;
        this->b /= d;
        if (this->b < 0) {
            this->a *= -1;
            this->b *= -1;
        }
    }

    Rational operator +(Rational other) {
        return Rational(a * other.b + b * other.a, b * other.b);
    }

    Rational operator -(Rational other) {
        return Rational(a * other.b - b * other.a, b * other.b);
    }

    Rational operator *(Rational other) {
        return Rational(a * other.a, b * other.b);
    }

    Rational operator /(Rational other) {
        return Rational(a * other.b, b * other.a);
    }

    bool operator <(Rational other) {
        return a * other.b < b * other.a;
    }

    bool operator >(Rational other) {
        return a * other.b > b * other.a;
    }

    bool operator ==(Rational other) {
        return a * other.b == b * other.a;
    }
};

ostream& operator <<(ostream& out, Rational a) {
    out << a.a << '/' << a.b;
    return out;
}

struct point {
    long double x, y;

    point() {}
    point(long double x, long double y) : x(x), y(y) {}

    point operator -(point b) {
        return point(x - b.x, y - b.y);
    }

    point operator +(point b) {
        return point(x + b.x, y + b.y);
    }

};

const long double eps = 1e-23;

bool operator <(point a, point b) {
    return a.x * b.y - a.y * b.x > eps || fabs(a.x * b.y - a.y * b.x) < eps && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
}

bool operator ==(point a, point b) {
    return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps;
}

bool operator <=(point a, point b) {
    return a < b || b == a;
}

ostream& operator <<(ostream& out, point a) {
    out << a.x << ' ' << a.y << endl;
    return out;
}

void eprint(vector <pair <point, int> > a) {
    cerr << endl;
    for (auto x: a) {
        cerr << x.first;
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i].first.x = 1.0 / s;
        a[i].first.y = 1.0 / r;
        a[i].second = i + 1;
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || a[i].first.x == a[best].first.x && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    long double x = a[best].first.x, y = a[best].first.y;
    //cerr << x << ' ' << y << endl;
    for (int i = 0; i < n; ++i) {
        a[i].first = a[i].first - point(x, y);
    }
    sort(a.begin(), a.end());
    //eprint(a);
    vector <pair <point, int> > ans;
    ans.pb(a[0]);
    ans.pb(a[1]);
    for (int i = 2; i < sz(a); ++i) {
        while (sz(ans) > 1 && (a[i].first - ans.back().first) <= (ans.back().first - ans[sz(ans) - 2].first)) {
            ans.pop_back();
        }
        ans.push_back(a[i]);
    }
    //eprint(ans);
    best = 0;
    for (int i = 1; i < sz(ans); ++i) {
        if (ans[i].first.y < ans[best].first.y || ans[i].first.y == ans[best].first.y && ans[i].first.x < ans[best].first.x)
            best = i;
    }
    vector <int> result;
    for (int i = 0; i <= best; ++i) {
        result.pb(ans[i].second);
    }
    for (int i = 0; i < n; ++i) {
        if (a[i].first == ans[0].first || a[i].first == ans[best].first)
            result.pb(a[i].second);
    }
    Sort(result);
    for (int i = 0; i < sz(result); ++i) {
        if (i == 0 || result[i] != result[i - 1]) {
            cout << result[i] << ' ';
        }
    }
    return 0;
}


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

#define pb push_back
#define rs resize
#define mp make_pair
#define pi 3.1415926535897932384626433832795
#define sz(a) (int)(a).size()
#define Sort(a) sort((a).begin(), (a).end())
#define Reverse(a) reverse((a).begin(), (a).end())
#define sf scanf
#define pf printf
#define ms(a, x) memset((a), (x), sizeof(a))
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <vvi> vvvi;
typedef vector <vvvi> vvvvi;
typedef vector <bool> vb;
typedef vector <vb> vvb;
typedef vector <vvb> vvvb;
typedef vector <vvvb> vvvvb;
typedef long long ll;
typedef vector <ll> vl;
typedef vector <vl> vvl;
typedef vector <vvl> vvvl;
typedef vector <vvvl> vvvvl;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef vector <vii> vvii;
typedef pair <int, ll> il;
typedef vector <il> vil;
typedef vector <vil> vvil;
typedef pair <ll, int> li;
typedef vector <li> vli;
typedef vector <vli> vvli;
typedef set <int> si;
typedef set <li> sli;
typedef set <il> sil;
typedef vector <string> vs;
typedef vector <vs> vvs;
typedef vector <vvs> vvvs;
typedef map <char, int> mci;
typedef pair <ll, ll> pll;
typedef vector <pll> vll;

ll gcd(ll a, ll b) {
    return b != 0 ? gcd(b, a % b) : a;
}

struct Rational {
    ll a, b;

    Rational() {}
    Rational(ll a, ll b = 1) : a(a), b(b) {
        ll d = gcd(abs(a), abs(b));
        this->a /= d;
        this->b /= d;
        if (this->b < 0) {
            this->a *= -1;
            this->b *= -1;
        }
    }

    Rational operator +(Rational other) {
        return Rational(a * other.b + b * other.a, b * other.b);
    }

    Rational operator -(Rational other) {
        return Rational(a * other.b - b * other.a, b * other.b);
    }

    Rational operator *(Rational other) {
        return Rational(a * other.a, b * other.b);
    }

    Rational operator /(Rational other) {
        return Rational(a * other.b, b * other.a);
    }

    bool operator <(Rational other) {
        return a * other.b < b * other.a;
    }

    bool operator >(Rational other) {
        return a * other.b > b * other.a;
    }

    bool operator ==(Rational other) {
        return a * other.b == b * other.a;
    }
};

ostream& operator <<(ostream& out, Rational a) {
    out << a.a << '/' << a.b;
    return out;
}

struct point {
    long double x, y;

    point() {}
    point(long double x, long double y) : x(x), y(y) {}

    point operator -(point b) {
        return point(x - b.x, y - b.y);
    }

    point operator +(point b) {
        return point(x + b.x, y + b.y);
    }

    double operator &(point b) {
        return x * b.y - y * b.x;
    }
};

const long double eps = 1e-22;

bool operator <(point a, point b) {
    /*cerr.precision(22);
    cerr << fixed;
    cerr << endl;
    cerr << a.x * b.y - a.y * b.x << endl;
    cerr << fabs(a.x * b.y - a.y * b.x) << endl;
    cerr << a.x * a.x + a.y * a.y << ' ' << b.x * b.x + b.y * b.y << endl;
    cerr << endl;*/
    return a.x * b.y - a.y * b.x > eps || fabs(a.x * b.y - a.y * b.x) < eps && a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
}

bool operator ==(point a, point b) {
    /*cerr.precision(22);
    cerr << fixed;
    cerr << endl;
    cerr << fabs(a.x - b.x) << ' ' << fabs(a.y - b.y) << endl;
    cerr << endl;*/
    return fabs(a.x - b.x) < eps && fabs(a.y - b.y) < eps;
}

bool operator >=(point a, point b) {
    return b < a || b == a;
}

ostream& operator <<(ostream& out, point a) {
    out << a.x << ' ' << a.y << endl;
    return out;
}

void eprint(vector <pair <point, int> > a) {
    cerr << endl;
    for (auto x: a) {
        cerr << x.second << ' ' << x.first;
    }
    cerr << endl;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector <pair <point, int> > a(n);
    for (int i = 0; i < n; ++i) {
        int s, r;
        cin >> s >> r;
        a[i].first.x = 1.0 / s;
        a[i].first.y = 1.0 / r;
        a[i].second = i + 1;
    }
    int best = 0;
    for (int i = 1; i < n; ++i) {
        if (a[i].first.x < a[best].first.x || a[i].first.x == a[best].first.x && a[i].first.y < a[best].first.y) {
            best = i;
        }
    }
    long double x = a[best].first.x, y = a[best].first.y;
    //cerr << x << ' ' << y << endl;
    for (int i = 0; i < n; ++i) {
        a[i].first = a[i].first - point(x, y);
    }
    sort(a.begin(), a.end());
    eprint(a);
    vector <pair <point, int> > ans;
    ans.pb(a[0]);
    ans.pb(a[1]);
    for (int i = 2; i < sz(a); ++i) {
        while (sz(ans) > 1 && (a[i].first - ans.back().first) >= (ans.back().first - ans[sz(ans) - 2].first) &&
                fabs((a[i].first - ans.back().first) & (ans.back().first - ans[sz(ans) - 2].first)) > eps) {
            ans.pop_back();
        }
        ans.push_back(a[i]);
    }
    eprint(ans);
    best = 0;
    for (int i = 1; i < sz(ans); ++i) {
        if (ans[i].first.y < ans[best].first.y || ans[i].first.y == ans[best].first.y && ans[i].first.x < ans[best].first.x)
            best = i;
    }
    vector <int> result;
    for (int i = 0; i <= best; ++i) {
        result.pb(ans[i].second);
    }
    for (int i = 0; i < n; ++i) {
        if (a[i].first == ans[0].first || a[i].first == ans[best].first)
            result.pb(a[i].second);
    }
    Sort(result);
    for (int i = 0; i < sz(result); ++i) {
        if (i == 0 || result[i] != result[i - 1]) {
            cout << result[i] << ' ';
        }
    }
    return 0;
}