In general, if all of the positions that direct a cow to position $p$ are known to eventually contain no cows, then position $p$ will also not contain any cows.

We start by keeping track of, for every position $p$, how many positions there are which still could contain cows forever and direct them to position $p$ after exactly one shuffle. After we've computed these quantities, we start a queue of positions which are now known never to contain any cows after some number of shuffles. Any such position cannot contribute cows to the position it directs to, so we need to decrement the counter for that position and possibly enqueue it. We'll keep processing positions in the queue until it's empty, and the answer is the number of elements which were never enqueued.

import java.io.*; import java.util.*; public class shuffle { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("shuffle.in")); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("shuffle.out"))); int n = Integer.parseInt(br.readLine()); int[] to = new int[n]; int[] parent = new int[n]; StringTokenizer st = new StringTokenizer(br.readLine()); for(int i = 0; i < n; i++) { to[i] = Integer.parseInt(st.nextToken())-1; parent[to[i]]++; } int ret = n; LinkedList<Integer> q = new LinkedList<Integer>(); for(int i = 0; i < n; i++) { if(parent[i] == 0) { q.add(i); ret--; } } while(!q.isEmpty()) { int curr = q.removeFirst(); if(--parent[to[curr]] == 0) { q.add(to[curr]); ret--; } } pw.println(ret); pw.close(); } }