import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

	static class Task {

		int NN = 200005;
		int MOD = 1000000007;;
		int INF = 2000000000;
		long INFINITY = 2000000000000000000L;

		int [] a;
		int [] visited;
		long [] p2 = new long[NN];

		public void solve(InputReader in, PrintWriter out) {
			p2[0] = 1;
			for(int i=1;i<NN;++i) {
				p2[i] = (p2[i - 1] * 2L) % MOD;
			}
			int n = in.nextInt();
			a = new int[n + 1];
			uf = new UnionFind[n + 1];
			for(int i=1;i<=n;++i) {
				uf[i] = new UnionFind(i, 0);
			}
			for(int i=1;i<=n;++i)
				a[i] = in.nextInt();
			for(int i=1;i<=n;++i) {
				union(i, a[i]);
			}
			visited = new int[n + 1];
			for(int i=1;i<=n;++i) {
				visited[i] = -1;
			}
			long ans = 1;
			int total = n;
			for(int i=1;i<=n;++i) {
				int parent = find(i);
				if(visited[parent] != -1)
					continue;
				int cnt = 0;
				int x = i;
				visited[x] = cnt;
				while(visited[a[x]] == -1) {
					x = a[x];
					visited[x] = ++cnt;
				}
				++cnt;
				int len = cnt - visited[a[x]];
				ans = (ans * (p2[len] - 2L)) % MOD;
				total -= len;
				visited[find(i)] = cnt;
			}
			ans = (ans * p2[total]) % MOD;
			out.println(ans);
		}

		void union(int x, int y) {
			x = find(x);
			y = find(y);
			if(uf[x].rank == uf[y].rank) {
				++uf[y].rank;
				uf[x].parent = uf[y].parent;
			} else if(uf[x].rank > uf[y].rank) {
				uf[y].parent = uf[x].parent;
			} else {
				uf[x].parent = uf[y].parent;
			}
		}

		int find(int x) {
			return uf[x].parent == x ? x : (uf[x].parent = find(uf[x].parent));
		}

		UnionFind [] uf;

		class UnionFind {
			Integer parent, rank;

			public UnionFind(Integer parent, Integer rank) {
				super();
				this.parent = parent;
				this.rank = rank;
			}

		}

	}

	static void prepareIO(boolean isFileIO) {
		//long t1 = System.currentTimeMillis();
		Task solver = new Task();
		// Standard IO
		if(!isFileIO) {
			InputStream inputStream = System.in;
	        OutputStream outputStream = System.out;
	        InputReader in = new InputReader(inputStream);
	        PrintWriter out = new PrintWriter(outputStream);
	        solver.solve(in, out);
	        //out.println("time(s): " + (1.0*(System.currentTimeMillis()-t1))/1000.0);
	        out.close();
		}
        // File IO
		else {
			String IPfilePath = System.getProperty("user.home") + "/Downloads/ip.in";
	        String OPfilePath = System.getProperty("user.home") + "/Downloads/op.out";
	        InputReader fin = new InputReader(IPfilePath);
	        PrintWriter fout = null;
	        try {
				fout = new PrintWriter(new File(OPfilePath));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
	        solver.solve(fin, fout);
	        //fout.println("time(s): " + (1.0*(System.currentTimeMillis()-t1))/1000.0);
	        fout.close();
		}
	}

	public static void main(String[] args) {
        prepareIO(false);
	}

	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public InputReader(String filePath) {
        	File file = new File(filePath);
            try {
				reader = new BufferedReader(new FileReader(file));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            tokenizer = null;
        }

        public String nextLine() {
        	String str = "";
        	try {
				str = reader.readLine();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	return str;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public double nextDouble() {
        	return Double.parseDouble(next());
        }

    }

}


import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Paints {

    static int[] a;
    static int[] processed;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt() - 1;
        }

        processed = new int[n];
        BigInteger mod = BigInteger.valueOf(1000000009L);
        BigInteger two = BigInteger.valueOf(2);
        BigInteger answer = BigInteger.ONE;
        long nocycles = 0;
        int dfsMarker = 1;
        for (int i = 0; i < n; i++) {
            if (processed[i] > 0) {
                continue;
            }
            DfsRes res = dfs(i, dfsMarker++);
            nocycles += res.nocycle;
            if (res.cycle >= 2) {
                answer = answer.multiply(two.modPow(BigInteger.valueOf(res.cycle), mod).subtract(two)).mod(mod);
            }
        }
        answer = answer.multiply(two.modPow(BigInteger.valueOf(nocycles), mod)).mod(mod);
        System.out.println(answer);
    }

    static DfsRes dfs(int start, int dfsMarker) {
        DfsRes res = new DfsRes();
        int cur = start;
        while (processed[cur] == 0) {
            res.nocycle++;
            processed[cur] = dfsMarker;
            cur = a[cur];
        }

        if (processed[cur] == dfsMarker) {
            int next = a[cur];
            res.cycle = 1;
            while (next != cur) {
                res.cycle++;
                next = a[next];
            }
            res.nocycle -= res.cycle;
        }
        return res;
    }

    static class DfsRes {
        int nocycle;
        int cycle;
    }
}


import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Paints {

    static int[] a;
    static int[] processed;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt() - 1;
        }

        processed = new int[n];
        BigInteger mod = BigInteger.valueOf(1000000007L);
        BigInteger two = BigInteger.valueOf(2);
        BigInteger answer = BigInteger.ONE;
        int nocycles = 0;
        int dfsMarker = 1;
        for (int i = 0; i < n; i++) {
            if (processed[i] > 0) {
                continue;
            }
            DfsRes res = dfs(i, dfsMarker++);
            nocycles += res.nocycle;
            if (res.cycle >= 2) {
                answer = answer.multiply(two.pow(res.cycle).subtract(two).mod(mod)).mod(mod);
            }
        }
        answer = answer.multiply(two.modPow(BigInteger.valueOf(nocycles), mod)).mod(mod);
        System.out.println(answer);
    }

    static DfsRes dfs(int start, int dfsMarker) {
        DfsRes res = new DfsRes();
        int cur = start;
        while (processed[cur] == 0) {
            res.nocycle++;
            processed[cur] = dfsMarker;
            cur = a[cur];
        }

        if (processed[cur] == dfsMarker) {
            int next = a[cur];
            res.cycle = 1;
            while (next != cur) {
                res.cycle++;
                next = a[next];
            }
            res.nocycle -= res.cycle;
        }
        return res;
    }

    static class DfsRes {
        int nocycle;
        int cycle;
    }
}


import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Paints {

    static int[] a;
    static int[] processed;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt() - 1;
        }

        processed = new int[n];
        BigInteger mod = BigInteger.valueOf(1000000009L);
        BigInteger two = BigInteger.valueOf(2);
        BigInteger answer = BigInteger.ONE;
        long nocycles = 0;
        int dfsMarker = 1;
        for (int i = 0; i < n; i++) {
            if (processed[i] > 0) {
                continue;
            }
            DfsRes res = dfs(i, dfsMarker++);
            nocycles += res.nocycle;
            answer = answer.multiply(two.modPow(BigInteger.valueOf(res.cycle), mod).subtract(two)).mod(mod);
        }
        answer = answer.multiply(two.modPow(BigInteger.valueOf(nocycles), mod)).mod(mod);
        System.out.println(answer);
    }

    static DfsRes dfs(int start, int dfsMarker) {
        DfsRes res = new DfsRes();
        int cur = start;
        while (processed[cur] == 0) {
            res.nocycle++;
            processed[cur] = dfsMarker;
            cur = a[cur];
        }

        if (processed[cur] == dfsMarker) {
            int next = a[cur];
            res.cycle = 1;
            while (next != cur) {
                res.cycle++;
                next = a[next];
            }
            res.nocycle -= res.cycle;
        }
        return res;
    }

    static class DfsRes {
        int nocycle;
        int cycle;
    }
}


import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Paints {

    static int[] a;
    static int[] processed;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt() - 1;
        }

        processed = new int[n];
        BigInteger mod = BigInteger.valueOf(1000000009L);
        BigInteger two = BigInteger.valueOf(2);
        BigInteger answer = BigInteger.ONE;
        long nocycles = 0;
        int dfsMarker = 1;
        for (int i = 0; i < n; i++) {
            if (processed[i] > 0) {
                continue;
            }
            DfsRes res = dfs(i, dfsMarker++);
            nocycles += res.nocycle;
            if (res.cycle >= 2) {
                answer = answer.multiply(two.pow(res.cycle).subtract(two).mod(mod)).mod(mod);
            }
        }
        answer = answer.multiply(two.modPow(BigInteger.valueOf(nocycles), mod)).mod(mod);
        System.out.println(answer);
    }

    static DfsRes dfs(int start, int dfsMarker) {
        DfsRes res = new DfsRes();
        int cur = start;
        while (processed[cur] == 0) {
            res.nocycle++;
            processed[cur] = dfsMarker;
            cur = a[cur];
        }

        if (processed[cur] == dfsMarker) {
            int next = a[cur];
            res.cycle = 1;
            while (next != cur) {
                res.cycle++;
                next = a[next];
            }
            res.nocycle -= res.cycle;
        }
        return res;
    }

    static class DfsRes {
        int nocycle;
        int cycle;
    }
}


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class DirectedRoads711D {
	public static int MOD = 1000000000 + 7;
	public static boolean[]  mem;

	public static void main(String[] args) throws IOException {
		int n;
		BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(System.in)));
		n = Integer.parseInt(reader.readLine());
		int[] graph = new int[n];
		String[] line = reader.readLine().split(" ");
		for (int i = 0; i < line.length; i++) {
			graph[i] = Integer.parseInt(line[i]) - 1;
		}
		mem = new boolean[n];
		Arrays.fill(mem, false);
		long result = 1;
		for (int i = 0; i < n; i++) {
			Map<Integer, Integer> map = new HashMap<>();
			result = (result * dfs(i, 1, map, graph)) % MOD;
		}
		System.out.println(result);
	}

	public static long dfs(int curr, int which, Map<Integer, Integer> map, int[] graph) {
		Integer prev = map.get(curr);
		if (prev != null) {
			int inCycle = which - prev;
			int outOfCycle = prev - 1;
			long first = (power(2, inCycle) - 2) % MOD;
			long second = power(2, outOfCycle);
			return (first * second) % MOD;
		}
		if (mem[curr]) {
			int outOfCycle = which - 1;
			return power(2, outOfCycle);
		}
		map.put(curr, which);
		mem[curr]  = true;
		return dfs(graph[curr], which + 1, map, graph);
	}

	public static long power(long a, long n) {
		if (n == 1) return a % MOD;
		if (n == 0) return 1;
		if (n % 2 == 0) {
			long temp = power(a, n/2);
			return (temp * temp) % MOD;
		}
		long temp = power(a, n-1);
		return (temp * a) % MOD;
	}

}


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class DirectedRoads711D {
	public static int MOD = 1000000000 + 7;
	public static boolean[]  mem;

	public static void main(String[] args) throws IOException {
		int n;
		BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(System.in)));
		n = Integer.parseInt(reader.readLine());
		int[] graph = new int[n];
		String[] line = reader.readLine().split(" ");
		for (int i = 0; i < line.length; i++) {
			graph[i] = Integer.parseInt(line[i]) - 1;
		}
		mem = new boolean[n];
		Arrays.fill(mem, false);
		long result = 1;
		for (int i = 0; i < n; i++) {
			int[] count = new int[n];
			Arrays.fill(count, 0);
			result = (result * dfs(i, 1, count, graph)) % MOD;
		}
		System.out.println(result);
	}

	public static long dfs(int curr, int which, int[] count, int[] graph) {
		if (count[curr] > 0) {
			int inCycle = which - count[curr];
			int outOfCycle = count[curr] - 1;
			long first = (power(2, inCycle) - 2) % MOD;
			long second = power(2, outOfCycle);
			return (first * second) % MOD;
		}
		if (mem[curr]) {
			int outOfCycle = which - 1;
			return power(2, outOfCycle);
		}
		count[curr] = which;
		mem[curr]  = true;
		return dfs(graph[curr], which + 1, count, graph);
	}

	public static long power(long a, long n) {
		if (n == 1) return a % MOD;
		if (n == 0) return 1;
		if (n % 2 == 0) {
			long temp = power(a, n/2);
			return (temp * temp) % MOD;
		}
		long temp = power(a, n-1);
		return (temp * a) % MOD;
	}

}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Temp {
    static PrintWriter w = new PrintWriter(System.out);
    static long p[]=new long[200005],m=1000000007L;
    static void cal(){
        p[0]=1;
        for(int i=1;i<=200000;i++){
            p[i]=p[i-1]*2;
            if(p[i]>=m)p[i]=p[i]%m;
        }
    }
    public static void main (String[] args)throws IOException{
        Scanner sc=new Scanner(System.in);
        cal();
        int n=sc.nextInt();
        int arr[]=new int[n+1],tc=0;
        for(int i=1;i<=n;i++)arr[i]=sc.nextInt();
        boolean v[]=new boolean[n+1];
        int c[]=new int[n+1];
        long res=1;
        for(int j=1;j<=n;j++){
            if(v[j])continue;
            Set<Integer> set=new HashSet<Integer>();
            int x=j,co=1,cl=0;
            while(true){
                if(v[arr[x]])break;
                if(set.contains(arr[x])){
                    cl=co-c[arr[x]]+1;
                    //v[x]=true;
                    set.add(x);
                    break;
                }
                else{
                    //v[x]=true;
                    set.add(x);
                    c[x]=co++;
                    x=arr[x];
                }
            }
            for(int k:set)v[k]=true;
            long ans=p[cl]-2;
            if(cl<2)continue;
            //ans-=2;
            tc+=cl;
            res=(res*ans)%m;
        }
        //for(int j=0;j<(n-tc);j++)tem=(tem*2)%m;
        w.println((res*p[n-tc])%m);
    	w.close();
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Temp {
    static PrintWriter w = new PrintWriter(System.out);

    public static void main (String[] args)throws IOException{
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        long m=1000000007L;
        int arr[]=new int[n+1],tc=0;
        for(int i=1;i<=n;i++)arr[i]=sc.nextInt();
        boolean v[]=new boolean[n+1];
        boolean cycle[]=new boolean[n+1];
        int c[]=new int[n+1];
        long res=1;
        for(int j=1;j<=n;j++){
            if(v[j])continue;
            Set<Integer> set=new HashSet<Integer>();
            int x=j,co=1,cl=0;
            while(true){
                if(v[arr[x]])break;
                if(set.contains(arr[x])){
                    cl=co-c[arr[x]]+1;
                    //v[x]=true;
                    set.add(x);
                    cycle[arr[x]]=true;
                    break;
                }
                else{
                    //v[x]=true;
                    set.add(x);
                    c[x]=co++;
                    x=arr[x];
                }
            }
            for(int k:set)v[k]=true;
            long ans=1;
            for(int i=0;i<cl;i++){
                ans=(ans*2)%m;
            }
            if(ans==1)continue;
            ans-=2;
            tc+=cl;
            res=(res*ans)%m;
        }
        long tem=1;
        for(int j=0;j<(n-tc);j++)tem=(tem*2)%m;
        w.println((res*tem)%m);
    	w.close();
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Temp {
    static PrintWriter w = new PrintWriter(System.out);

    public static void main (String[] args)throws IOException{
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        long m=(long)(1e9+7);
        int arr[]=new int[n+1],tc=0;
        for(int i=1;i<=n;i++)arr[i]=sc.nextInt();
        boolean v[]=new boolean[n+1];
        boolean cycle[]=new boolean[n+1];
        int c[]=new int[n+1];
        long res=1;
        for(int j=1;j<=n;j++){
            if(v[j])continue;
            Set<Integer> set=new HashSet<Integer>();
            int x=j,co=1,cl=0;
            while(true){
                if(v[arr[x]])break;
                if(set.contains(arr[x])){
                    cl=co-c[arr[x]]+1;
                    //v[x]=true;
                    set.add(x);
                    cycle[arr[x]]=true;
                    break;
                }
                else{
                    //v[x]=true;
                    set.add(x);
                    c[x]=co++;
                    x=arr[x];
                }
            }
            for(int k:set)v[k]=true;
            long ans=1;
            for(int i=0;i<cl;i++){
                ans=(ans*2)%m;
            }
            if(ans==1)continue;
            ans-=2;
            tc+=cl;
            res=(res*ans)%m;
        }
        w.println(n==tc?res:(res*(long)(2*(n-tc)))%m);
    	w.close();
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Temp {
    static PrintWriter w = new PrintWriter(System.out);

    public static void main (String[] args)throws IOException{
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        long m=(long)(1e9+7);
        int arr[]=new int[n+1],cl=0;
        for(int i=1;i<=n;i++)arr[i]=sc.nextInt();
        boolean v[]=new boolean[n+1];
        int c[]=new int[n+1];
        int x=1,co=1;
        while(true){
            if(v[arr[x]]){
                cl=co-c[arr[x]]+1;
                break;
            }
            else{
                v[x]=true;
                c[x]=co++;
                x=arr[x];
            }
        }
        long ans=1;
        for(int i=0;i<cl;i++){
            ans=(ans*2)%m;
        }
        ans-=2;
        if(n!=cl){
            ans=(ans*2*(n-cl))%m;
        }
        w.println(ans);
    	w.close();
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Temp {
    static PrintWriter w = new PrintWriter(System.out);

    public static void main (String[] args)throws IOException{
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        long m=(long)(1e9+7);
        int arr[]=new int[n+1],cl=0;
        for(int i=1;i<=n;i++)arr[i]=sc.nextInt();
        boolean v[]=new boolean[n+1];
        int c[]=new int[n+1];
        long res=1;
        for(int j=1;j<=n;j++){
            if(v[j])continue;
            int x=j,co=1;
            while(true){
                if(v[arr[x]]){
                    cl=co-c[arr[x]]+1;
                    v[x]=true;
                    break;
                }
                else{
                    v[x]=true;
                    c[x]=co++;
                    x=arr[x];
                }
            }
            long ans=1;
            for(int i=0;i<cl;i++){
                ans=(ans*2)%m;
            }
            ans-=2;
            if(co!=cl){
                ans=(ans*2*(n-cl))%m;
            }

            res=(res*ans)%m;
        }
        w.println(res);
    	w.close();
    }
}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        if(n==148967){
        	System.out.println(total);
        	int sum = 0;
        	for(int i=0;i<total;i++){
        		sum += sizes[i];
//        		System.out.print(sizes[i] + " ");
        	}
        	System.out.println();
        	System.out.println( sum);
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]-1] = leng;
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0){
        		dp[colors[i]-1] = Math.max(leng, dp[colors[i]-1]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] - 2) * p2[size - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0){
        		dp[colors[i]-1] = Math.max(leng, dp[colors[i]-1]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        if(n==148967){
        	System.out.println(total);
        	for(int i=0;i<total;i++){
        		System.out.println(sizes[i] + " ");
        	}
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0){
        		dp[colors[i]-1] = Math.max(leng, dp[colors[i]-1]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] - 2) * p2[sizes[i] - dp[i]] + modu) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        if(n==148967){
        	System.out.println(total);
        	int sum = 0;
        	for(int i=0;i<total;i++){
        		sum += sizes[i];
        		System.out.print(sizes[i] + " ");
        	}
        	System.out.println();
        	System.out.println(sum);
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static int[] depth;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        }
        int total = 0;
        long ans = 1;
        int sum = 0;
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        		ans = (ans * (p2[leng] - 2)) % modu;
        		sum += leng;
        	}
        }
        ans = (ans * (p2[n-sum])) % modu;
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}

	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static int[] depth;
	static int start;
	static int visited;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        Arrays.fill(depth, -1);

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        }
        int total = 0;
        long ans = 1;
        int sum = 0;
        start = 0;
        visited = 0;
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==-1){
        		start = visited;
        		if(dfs(i, start)){
        			ans = (ans * (p2[leng] - 2)) % modu;
        			sum += leng;
//        			out.println(i + " " + leng);
        		}
        	}
        }
        ans = (ans * (p2[n-sum])) % modu;
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		visited++;
		depth[index] = d;
		if(depth[to[index]] >= start){
			leng = d - depth[to[index]] + 1;
//			System.out.println("leng = " + d + depth[to[index]]);
			return true;
		}else if(depth[to[index]] > -1){
			return false;
		}else {
			return dfs(to[index], d+1);
		}
	}

	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0){
        		dp[colors[i]-1] = Math.max(leng, dp[colors[i]-1]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] - 2) * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
//        	System.out.println(p2[i]);
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        	if(n==148967)System.out.println(ans);
        }
        if(n==148967){
        	System.out.println(total);
        	int sum = 0;
        	for(int i=0;i<total;i++){
        		sum += sizes[i];
//        		System.out.print(sizes[i] + " ");
        	}
        	System.out.println();
        	System.out.println( sum);
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        if(n==148967){
        	System.out.println(total);
        	int sum = 0;
        	for(int i=0;i<total;i++){
        		sum += sizes[i];
        		System.out.print(sizes[i] + " ");
        	}
        	System.out.println("/n" + sum);
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
//        	System.out.println(p2[i]);
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        	System.out.println(ans);
        }
        if(n==148967){
        	System.out.println(total);
        	int sum = 0;
        	for(int i=0;i<total;i++){
        		sum += sizes[i];
//        		System.out.print(sizes[i] + " ");
        	}
        	System.out.println();
        	System.out.println( sum);
        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static int[] depth;
	static int start;

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        Arrays.fill(depth, -1);

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        }
        int total = 0;
        long ans = 1;
        int sum = 0;
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==-1){
            	start = i;
        		if(dfs(i, start)){
        			ans = (ans * (p2[leng] - 2)) % modu;
        			sum += leng;
//        			out.println(i + " " + leng);
        		}
        	}
        }
        ans = (ans * (p2[n-sum])) % modu;
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] >= start){
			leng = d - depth[to[index]] + 1;
//			System.out.println("leng = " + d + depth[to[index]]);
			return true;
		}else if(depth[to[index]] > -1){
			return false;
		}else {
			return dfs(to[index], d+1);
		}
	}

	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        Arrays.fill(colors, -1);
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
//        	System.out.println(p2[i]);
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==-1){
        		size = 0;
        		dfs2(i, total);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
            	dp[colors[i]] = Math.max(leng, dp[colors[i]]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        int sum = 0;
        for(int i=0;i<total;i++){
        	sum += dp[i];
        	ans = (ans * (p2[dp[i]] + modu - 2)) % modu;
//        	if(n==148967)System.out.println(ans);
        }
        ans = (ans * p2[n - sum]) % modu;
//        if(n==148967){
//        	System.out.println(total);
//        	int sum = 0;
//        	for(int i=0;i<total;i++){
//        		sum += sizes[i];
////        		System.out.print(sizes[i] + " ");
//        	}
//        	System.out.println();
//        	System.out.println( sum);
//        }
        out.println(ans);
        out.flush();
	}

	static boolean dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return true;
		}else{
			return dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=-1) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] colors;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	static NNode[] nodes;
	static int[] depth;
	static int size;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        colors = new int[n];
        nodes = new NNode[n];

        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }

        for(int i=0;i<n;i++){
        	nodes[i] = new NNode(i);
        }
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        	nodes[i].cs.add(nodes[to[i]]);
        	nodes[to[i]].cs.add(nodes[i]);
        }
        int total = 0;
        int[] sizes = new int[n];
        for(int i=0;i<n;i++){
        	if(colors[i]==0){
        		size = 0;
        		dfs2(i, total+1);
        		sizes[total] = size;
        		total++;
        	}
        }

        int[] dp = new int[total];
        for(int i=0;i<n;i++){
        	leng = 0;
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0){
        		dp[colors[i]-1] = Math.max(leng, dp[colors[i]-1]);
        	}
        }
//        out.println(leng);
        long ans = 1;
        for(int i=0;i<total;i++){
        	ans = (ans * (p2[dp[i]] - 2)) % modu;
        	ans = (ans * p2[sizes[i] - dp[i]]) % modu;
        }
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static void dfs2(int index, int color){
		colors[index] = color;
		size++;
		for(NNode c  : nodes[index].cs){
			if(colors[c.index]!=0) continue;
			dfs2(c.index, color);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}

class NNode{
	int index;
	ArrayList<NNode> cs;
	int comp;
	NNode(int index){
		this.index = index;
		this.cs = new ArrayList<>();
		int comp = 0;
	}

}


import java.io.*;
import java.util.*;

public class R711_D {
	static int[] depth;
	static int[] to;
	static int leng;
	static final long modu = 1000000007;
	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        to = new int[n];
        depth = new int[n];
        for(int i=0;i<n;i++){
        	to[i] = in.nextInt() - 1;
        }
        leng = 0;
        for(int i=0;i<n;i++){
        	if(depth[i]==0){
        		dfs(i, 1);
        	}
        	if(leng!=0) break;
        }
        long[] p2 = new long[n+1];
        p2[0] = 1;
        for(int i=1;i<=n;i++){
        	p2[i] = (p2[i-1] * 2) % modu;
        }
//        out.println(leng);
        long ans = (p2[leng] - 2) * (p2[n-leng]) % modu;
        out.println(ans);
        out.flush();
	}

	static void dfs(int index, int d){
		depth[index] = d;
		if(depth[to[index]] != 0){
			leng = d - depth[to[index]] + 1;
//			System.out.println(d + " " + depth[to[index]]);
			return;
		}else{
			dfs(to[index], d+1);
		}
	}
	static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            	try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong(){
        	return Long.parseLong(next());
        }

        public double nextDouble(){
        	return Double.parseDouble(next());
        }

    }
}


import java.util.*;
import java.io.*;

public class Directed_Roads {

	public static long mod = 1000000007;

	public static ArrayList<ArrayList<Integer>> adj;

	public static int[] num, low;
	public static boolean[] v;

	public static int ct, cycle;
	public static long ans;

	public static void SCC(int x, Stack<Integer> s) {

		num[x] = low[x] = ++ct;
		s.add(x);

		for (int i : adj.get(x)) {
			if (num[i] == 0)
				SCC(i, s);
			low[x] = Math.min(low[x], low[i]);
		}

		if (num[x] == low[x]) {

			int w = -1;
			ArrayList<Integer> tl = new ArrayList<Integer>();
			int pcycle = cycle;

			while (w != x) {
				w = s.pop();
				tl.add(w);
				low[w] = 1 << 30;
				cycle++;
			}

			if (pcycle + 1 == cycle) {
				cycle--;
			} else {
				ans = (ans * (pow(2, cycle - pcycle, mod) - 2)) % mod;
			}

		}

	}

	public static long pow(long a, long b, long mod) {

		long ret = 1;

		for (int i = 63 - Long.numberOfLeadingZeros(b); i >= 0; i--) {
			ret = (ret * ret) % mod;
			if (b << (63 - i) < 0) {
				ret = (ret * a) % mod;
			}
		}

		return ret;

	}

	public static void main(String[] args) throws IOException {

		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(f.readLine());

		int n = Integer.parseInt(st.nextToken());

		st = new StringTokenizer(f.readLine());

		adj = new ArrayList<ArrayList<Integer>>();
		for (int i = 0; i <= n; i++) {
			ArrayList<Integer> tl = new ArrayList<Integer>();
			adj.add(tl);
		}

		int pathct = 0;
		for (int i = 1; i <= n; i++) {

			int a = Integer.parseInt(st.nextToken());

			if (a != i) {
				adj.get(i).add(a);
				pathct++;
			}

		}

		f.close();

		num = new int[n + 1];
		low = new int[n + 1];
		v = new boolean[n + 1];

		ct = 1;
		cycle = 0;
		ans = 1;

		for (int i = 1; i <= n; i++) {
			if (num[i] == 0) {
				Stack<Integer> s = new Stack<Integer>();
				SCC(i, s);
			}
		}

		ans = (ans * pow(2, pathct - cycle, mod)) % mod;

		System.out.println(ans);

	}

}


import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class CF711D {
    static long mod = 1000000007;

    static long[] pow;

  static long fastPow(long a, long exp) {
		if (exp == 0)
			return 1;

		long c = fastPow(a, exp / 2);
		long d = c * c % mod;
		if (exp % 2 == 1)
			d = d * a % mod;
		return d;

	}

    static class ModMath {

		static long sub(long a, long b) {return ((a % mod) - (b % mod) + mod) % mod;}
		static long mul(long a, long b) {return ((a % mod) * (b % mod)) % mod;}
		static long add(long a, long b) {return ((a % mod) + (b % mod)) % mod;}
		static long div(long a, long b) {return mul(a, modInverse(b));}
		static long modInverse(long n) {return modPow(n, mod - 2L);} // Fermat's little theorem
		static long modPow(long a, long b) { // squared exponentiation
			if (b == 0L || a == 1L)
				return 1L;
			else if (b == 1L)
				return a;
			else {
				if ((b & 1L) == 0L) // Checking whether b is even (fast)
					return modPow((a * a) % mod, b >> 1);
				else
					return (a * modPow((a * a) % mod, b >> 1)) % mod;
			}
		}
	}

    public static void main(String[] args){
       long ans=1L;

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

         pow=new long[n+1];
          pow[0]=1;
          for(int i=1;i<=n;i++)
		 {
			 pow[i]=(pow[i-1]*2)%mod;
		 }

        Node[] a = new Node[n];
        for(int a_i=0;a_i<n;a_i++){
                     int e = sc.nextInt()-1;
                 if(a[a_i]==null){
                        a[a_i] = new Node(a_i) ;
                }

                 if(a[e] == null)
                        a[e] = new Node(e);

                 a[a_i].next = a[e];
        }

            int[] visited = new int[n];
        int nodeCount=0;
        for(int i=0;i<n;i++){
                Node r = a[i];
                if(visited[r.id]==1)
                     continue;
                Node prev=null;
                int  k =i;
                int count=0;
                while(visited[r.id]==0){
                     count = count+1;
                     r.count=count;
                     visited[r.id]=1;
                     prev = r;
                     k = r.next.id;
                     r = r.next;
                     if(visited[r.id]] == 0){r.start=i;}
                }
            //    int cnc=0;
                if(prev!=null & prev.start== r.start){
                     int   cnc = (prev.count - prev.next.count+1);
                        nodeCount = nodeCount+cnc;
                       // long pow = pw(2,cnc);
               //         long ansC=ModMath.sub(  pow[cnc] , 2 );

                        ans*=(pow[cnc]-2);
                        ans = ans +mod;
		            	ans%=mod;

                    //    ans=ModMath.mul(ans,ansC);
                }

        }
        long ansNC = pow[n-nodeCount];
       System.out.println(ModMath.mul(ans,ansNC));
  //      System.out.println(ans);
    }
}

    class Node{
  public int id;
  public Node next;
  public Node(int i){
        id=i;
         next=null;
  }
  public int count=-1;
  public int start=-1;

  @Override
  public String toString(){
              return (id+1)+"->"+(next.id+1);
   }
}


import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class CF711D {
    static long mod = 1000000007;

    static long[] pow;

  static long fastPow(long a, long exp) {
		if (exp == 0)
			return 1;

		long c = fastPow(a, exp / 2);
		long d = c * c % mod;
		if (exp % 2 == 1)
			d = d * a % mod;
		return d;

	}

    static class ModMath {

		static long sub(long a, long b) {return ((a % mod) - (b % mod) + mod) % mod;}
		static long mul(long a, long b) {return ((a % mod) * (b % mod)) % mod;}
		static long add(long a, long b) {return ((a % mod) + (b % mod)) % mod;}
		static long div(long a, long b) {return mul(a, modInverse(b));}
		static long modInverse(long n) {return modPow(n, mod - 2L);} // Fermat's little theorem
		static long modPow(long a, long b) { // squared exponentiation
			if (b == 0L || a == 1L)
				return 1L;
			else if (b == 1L)
				return a;
			else {
				if ((b & 1L) == 0L) // Checking whether b is even (fast)
					return modPow((a * a) % mod, b >> 1);
				else
					return (a * modPow((a * a) % mod, b >> 1)) % mod;
			}
		}
	}

    public static void main(String[] args){
       long ans=1L;

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

         pow=new long[n+1];
          pow[0]=1;
          for(int i=1;i<=n;i++)
		 {
			 pow[i]=(pow[i-1]*2)%mod;
		 }

        Node[] a = new Node[n];
        for(int a_i=0;a_i<n;a_i++){
                     int e = sc.nextInt()-1;
                 if(a[a_i]==null){
                        a[a_i] = new Node(a_i) ;
                }

                 if(a[e] == null)
                        a[e] = new Node(e);

                 a[a_i].next = a[e];
        }

            int[] visited = new int[n];
        int nodeCount=0;
        for(int i=0;i<n;i++){
                Node r = a[i];
                if(visited[r.id]==1)
                     continue;
                Node prev=null;
                int  k =i;
                int count=0;
                while(visited[r.id]==0){
                     count = count+1;
                     r.count=count;
                     visited[r.id]=1;
                     prev = r;
                     k = r.next.id;
                     r = r.next;
                     if(visited[r.id] == 0 || r.id  == start){r.start=i;}
                }
            //    int cnc=0;
                if(prev!=null & prev.start== r.start){
                     int   cnc = (prev.count - prev.next.count+1);
                        nodeCount = nodeCount+cnc;
                       // long pow = pw(2,cnc);
               //         long ansC=ModMath.sub(  pow[cnc] , 2 );

                        ans*=(pow[cnc]-2);
                        ans = ans +mod;
		            	ans%=mod;

                    //    ans=ModMath.mul(ans,ansC);
                }

        }
        long ansNC = pow[n-nodeCount];
       System.out.println(ModMath.mul(ans,ansNC));
  //      System.out.println(ans);
    }
}

    class Node{
  public int id;
  public Node next;
  public Node(int i){
        id=i;
         next=null;
  }
  public int count=-1;
  public int start=-1;

  @Override
  public String toString(){
              return (id+1)+"->"+(next.id+1);
   }
}


import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class CF711D {
    static long mod = 1000000007;

    static long[] pow;

  static long fastPow(long a, long exp) {
		if (exp == 0)
			return 1;

		long c = fastPow(a, exp / 2);
		long d = c * c % mod;
		if (exp % 2 == 1)
			d = d * a % mod;
		return d;

	}

    static class ModMath {

		static long sub(long a, long b) {return ((a % mod) - (b % mod) + mod) % mod;}
		static long mul(long a, long b) {return ((a % mod) * (b % mod)) % mod;}
		static long add(long a, long b) {return ((a % mod) + (b % mod)) % mod;}
		static long div(long a, long b) {return mul(a, modInverse(b));}
		static long modInverse(long n) {return modPow(n, mod - 2L);} // Fermat's little theorem
		static long modPow(long a, long b) { // squared exponentiation
			if (b == 0L || a == 1L)
				return 1L;
			else if (b == 1L)
				return a;
			else {
				if ((b & 1L) == 0L) // Checking whether b is even (fast)
					return modPow((a * a) % mod, b >> 1);
				else
					return (a * modPow((a * a) % mod, b >> 1)) % mod;
			}
		}
	}

    public static void main(String[] args){
       long ans=1L;

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

         pow=new long[n+1];
          pow[0]=1;
          for(int i=1;i<=n;i++)
		 {
			 pow[i]=(pow[i-1]*2)%mod;
		 }

        Node[] a = new Node[n];
        for(int a_i=0;a_i<n;a_i++){
                     int e = sc.nextInt()-1;
                 if(a[a_i]==null){
                        a[a_i] = new Node(a_i) ;
                }

                 if(a[e] == null)
                        a[e] = new Node(e);

                 a[a_i].next = a[e];
        }

            int[] visited = new int[n];
        int nodeCount=0;
        for(int i=0;i<n;i++){
                Node r = a[i];
                if(visited[r.id]==1)
                     continue;
                Node prev=null;
                int  k =i;
                int count=0;
                while(visited[r.id]==0){
                     count = count+1;
                     r.count=count;
                     visited[r.id]=1;
                     prev = r;
                     k = r.next.id;
                     r = r.next;
                     if(visited[r.id] == 0){r.start=i;}
                }
            //    int cnc=0;
                if(prev!=null & prev.start== r.start){
                     int   cnc = (prev.count - prev.next.count+1);
                        nodeCount = nodeCount+cnc;
                       // long pow = pw(2,cnc);
               //         long ansC=ModMath.sub(  pow[cnc] , 2 );

                        ans*=(pow[cnc]-2);
                        ans = ans +mod;
		            	ans%=mod;

                    //    ans=ModMath.mul(ans,ansC);
                }

        }
        long ansNC = pow[n-nodeCount];
       System.out.println(ModMath.mul(ans,ansNC));
  //      System.out.println(ans);
    }
}

    class Node{
  public int id;
  public Node next;
  public Node(int i){
        id=i;
         next=null;
  }
  public int count=-1;
  public int start=-1;

  @Override
  public String toString(){
              return (id+1)+"->"+(next.id+1);
   }
}


import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class CF711D {
    static long mod = 1000000007;

    static long[] pow;

  static long fastPow(long a, long exp) {
		if (exp == 0)
			return 1;

		long c = fastPow(a, exp / 2);
		long d = c * c % mod;
		if (exp % 2 == 1)
			d = d * a % mod;
		return d;

	}

    static class ModMath {

		static long sub(long a, long b) {return ((a % mod) - (b % mod) + mod) % mod;}
		static long mul(long a, long b) {return ((a % mod) * (b % mod)) % mod;}
		static long add(long a, long b) {return ((a % mod) + (b % mod)) % mod;}
		static long div(long a, long b) {return mul(a, modInverse(b));}
		static long modInverse(long n) {return modPow(n, mod - 2L);} // Fermat's little theorem
		static long modPow(long a, long b) { // squared exponentiation
			if (b == 0L || a == 1L)
				return 1L;
			else if (b == 1L)
				return a;
			else {
				if ((b & 1L) == 0L) // Checking whether b is even (fast)
					return modPow((a * a) % mod, b >> 1);
				else
					return (a * modPow((a * a) % mod, b >> 1)) % mod;
			}
		}
	}

    public static void main(String[] args){
       long ans=1L;

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

         pow=new long[n+1];
          pow[0]=1;
          for(int i=1;i<=n;i++)
		 {
			 pow[i]=(pow[i-1]*2)%mod;
		 }

        Node[] a = new Node[n];
        for(int a_i=0;a_i<n;a_i++){
                     int e = sc.nextInt()-1;
                 if(a[a_i]==null){
                        a[a_i] = new Node(a_i) ;
                }

                 if(a[e] == null)
                        a[e] = new Node(e);

                 a[a_i].next = a[e];
        }

            int[] visited = new int[n];
        int nodeCount=0;
        for(int i=0;i<n;i++){
                Node r = a[i];
                if(visited[r.id]==1)
                     continue;
                Node prev=null;
                int  k =i;
                int count=0;
                r.start = i;
                while(visited[r.id]==0){
                     count = count+1;
                     r.count=count;
                     visited[r.id]=1;
                     prev = r;
                     k = r.next.id;
                     r = r.next;
                     if(visited[r.id] == 0){r.start=i;}
                }
            //    int cnc=0;
                if(prev!=null & prev.start== r.start){
                     int   cnc = (prev.count - prev.next.count+1);
                        nodeCount = nodeCount+cnc;
                       // long pow = pw(2,cnc);
               //         long ansC=ModMath.sub(  pow[cnc] , 2 );

                        ans*=(pow[cnc]-2);
                        ans = ans +mod;
		            	ans%=mod;

                    //    ans=ModMath.mul(ans,ansC);
                }

        }
        long ansNC = pow[n-nodeCount];
       System.out.println(ModMath.mul(ans,ansNC));
  //      System.out.println(ans);
    }
}

    class Node{
  public int id;
  public Node next;
  public Node(int i){
        id=i;
         next=null;
  }
  public int count=-1;
  public int start=-1;

  @Override
  public String toString(){
              return (id+1)+"->"+(next.id+1);
   }
}


//package CF;
import java.io.*;
import java.util.*;
public class A{
    static int [] adjList;
    static int V, counter, SCC, dfs_num[], dfs_low[],size[];
    static boolean[] inSCC;
    static Stack<Integer> stack;
    static final int mod = (int)1e9 + 7;

    static void tarjanSCC()	 	//O(V + E)
    {
	for(int i = 0; i < V; ++i)
	    if(dfs_num[i] == 0)
		tarjanSCC(i);
    }

    static void tarjanSCC(int u)
    {
	dfs_num[u] = dfs_low[u] = ++counter;
	stack.push(u);
	int v = adjList[u];
	if(dfs_num[v] == 0)
	    tarjanSCC(v);
	if(!inSCC[v])
	    dfs_low[u] = Math.min(dfs_low[u], dfs_low[v]);
	if(dfs_num[u] == dfs_low[u])
	{
	    //SCC found
	    SCC++;
	    while(true)
	    {
		int x = stack.pop();
		inSCC[x] = true;
		size[u]++;
		if(x == u)
		    break;
	    }
	}
    }
    public static void main(String[] args) throws NumberFormatException, IOException
    {
	Scanner bf = new Scanner(System.in);
	PrintWriter out = new PrintWriter(System.out);
	int pow [] = new int[(int)1e6];
	pow[0] = 1;
	for (int i = 1; i < pow.length; i++)
	{
	    pow[i] = (pow[i-1] * 2) % mod;
	}
	V = bf.nextInt();
	adjList = new int[V];
	dfs_low = new int[V];
	dfs_num = new int[V];
	size = new int[V];
	inSCC = new boolean[V];
	stack = new Stack<Integer>();
	for (int i = 0; i < V; i++)
	{
	    adjList[i] = bf.nextInt()-1;
	}
	tarjanSCC();
	long ans = 1;
//	out.println(Arrays.toString(size));
	int tmp = 0;
	for (int i = 0; i < V; i++)
	{
	    if(size[i] > 1){
		ans *= pow[size[i]]-2;
		ans %= mod;
	    }
	    else if(size[i] == 1) tmp++;
	}
	ans *= pow[tmp];
	ans %= mod;
	out.println(ans);
	out.flush();
	out.close();
    }

    static class Scanner{
	BufferedReader bf;
	StringTokenizer st;
	public Scanner(InputStream i){
	    bf = new BufferedReader(new InputStreamReader(i));
	}
	public String next() throws IOException{
	    while(st == null || !st.hasMoreTokens())
		st = new StringTokenizer(bf.readLine());
	    return st.nextToken();
	}
	public int nextInt() throws NumberFormatException, IOException{
	    return Integer.parseInt(next());
	}
    }

}


import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Codecomp {

  final PrintStream out;
  final Scanner sc;

  public Codecomp(InputStream is, PrintStream ps) {
    this.sc = new Scanner(is);
    this.out = ps;
  }
  long mod = 1000000007;
  long exp(long base, long n) {
    long val = 1;
    while (n != 0) {
      if ((n & 1) == 1)val = (base * val) % mod;
      base = base * base % mod;
      n /= 2;
    }
    return val;
  }

  int n;
  int[] v;
  int[] u;
  void solve() {
    n = sc.nextInt();
    v = new int[n];
    u = new int[n];
    for (int i = 0; i < n; ++i) {
      v[i] = sc.nextInt() - 1;
    }
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < n; ++i) {
      int cur = i, s = 0;
      while (v[cur] >= 0) {
        int next = v[cur];
        u[cur] = s;
        v[cur] = -1 - i;
        cur = next;
        s++;
      }
      if (v[cur] == -1 - i) {
        list.add(s - u[cur]);
      }
    }
    list.sort(Integer::compareTo);
    int e = list.size() - 1;

    long ans = 1;
    int val = n;
    for (int a : list) {
      ans *= exp(2, a) - 2;
      ans = ans % mod;
      val -= a;
    }
    ans *= exp(2, val);
    ans = ans % mod;
    System.out.println(ans);
  }

  public static void main(String[] args) {
    new Codecomp(System.in, System.out).solve();
  }
}


import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Codecomp {

  final PrintStream out;
  final Scanner sc;

  public Codecomp(InputStream is, PrintStream ps) {
    this.sc = new Scanner(is);
    this.out = ps;
  }
  long mod = 1000000007;
  long exp(long base, long n) {
    long val = 1;
    while (n != 0) {
      if ((n & 1) == 1)val = (base * val) % mod;
      base = base * base % mod;
      n /= 2;
    }
    return val;
  }

  int n;
  int[] v;
  int[] u;
  void solve() {
    n = sc.nextInt();
    v = new int[n];
    u = new int[n];
    for (int i = 0; i < n; ++i) {
      v[i] = sc.nextInt() - 1;
    }
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < n; ++i) {
      int cur = i, s = 0;
      while (v[cur] >= 0) {
        int next = v[cur];
        u[cur] = s;
        v[cur] = -1 - i;
        cur = next;
        s++;
      }
      if (v[cur] == -1 - i) {
        list.add(s - u[cur]);
      }
    }
    list.sort(Integer::compareTo);
    int e = list.size() - 1;

    long nans = 0;
    for (int a : list) {
      nans += exp(2, n - a) * 2;
    }
    long ans = exp(2, n);
    ans -= nans;
    if (ans < 0)ans += mod;
    System.out.println(ans);
  }

  public static void main(String[] args) {
    new Codecomp(System.in, System.out).solve();
  }
}


import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Codecomp {

  final PrintStream out;
  final Scanner sc;

  public Codecomp(InputStream is, PrintStream ps) {
    this.sc = new Scanner(is);
    this.out = ps;
  }
  long mod = 1000000007;
  long exp(long base, long n) {
    long val = 1;
    while (n != 0) {
      if ((n & 1) == 1)val = (base * val) % mod;
      base = base * base % mod;
      n /= 2;
    }
    return val;
  }

  int n;
  int[] v;
  int[] u;
  void solve() {
    n = sc.nextInt();
    v = new int[n];
    u = new int[n];
    for (int i = 0; i < n; ++i) {
      v[i] = sc.nextInt() - 1;
    }
    ArrayList<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < n; ++i) {
      int cur = i, s = 0;
      while (v[cur] >= 0) {
        int next = v[cur];
        u[cur] = s;
        v[cur] = -1 - i;
        cur = next;
        s++;
      }
      if (v[cur] == -1 - i) {
        list.add(s - u[cur]);
      }
    }
    list.sort(Integer::compareTo);
    int e = list.size() - 1;

    long nans = 0;
    for (int a : list) {
      nans += exp(2, n - a) * 2;
    }
    nans = nans % mod;
    long ans = exp(2, n);
    ans -= nans;
    if (ans < 0)ans += mod;
    System.out.println(ans);
  }

  public static void main(String[] args) {
    new Codecomp(System.in, System.out).solve();
  }
}