Problem: PolandBall lives in a forest with his family. There are some trees in the forest. Trees are undirected acyclic graphs with k vertices and k - 1 edges, where k is some integer. Note that one vertex is a valid tree.

There is exactly one relative living in each vertex of each tree, they have unique ids from 1 to n. For each Ball i we know the id of its most distant relative living on the same tree. If there are several such vertices, we only know the value of the one with smallest id among those.

How many trees are there in the forest?

Input

The first line contains single integer n (1 ≤ n ≤ 104) — the number of Balls living in the forest.

The second line contains a sequence p1, p2, ..., pn of length n, where (1 ≤ pi ≤ n) holds and pi denotes the most distant from Ball i relative living on the same tree. If there are several most distant relatives living on the same tree, pi is the id of one with the smallest id.

It's guaranteed that the sequence p corresponds to some valid forest.

Hacking: To hack someone, you should provide a correct forest as a test. The sequence p will be calculated according to the forest and given to the solution you try to hack as input. Use the following format:

In the first line, output the integer n (1 ≤ n ≤ 104) — the number of Balls and the integer m (0 ≤ m < n) — the total number of edges in the forest. Then m lines should follow. The i-th of them should contain two integers ai and bi and represent an edge between vertices in which relatives ai and bi live. For example, the first sample is written as follows:
    
    
      
    5 3  
    1 2  
    3 4  
    4 5  
    

Output

You should output the number of trees in the forest where PolandBall lives.

Interaction

From the technical side, this problem is interactive. However, it should not affect you (except hacking) since there is no interaction.

Examples

Input

5
2 1 5 3 3

Output

2

Input

1
1


Output

1

Note

In the first sample testcase, possible forest is: 1-2 3-4-5. 

There are 2 trees overall.

In the second sample testcase, the only possible graph is one vertex and no edges. Therefore, there is only one tree.

Solution (in JAVA):

Solution:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;

public class C_special6
{
    private static BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
    private static StringTokenizer stringTokenizer = null;
    private static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

    private static String next() throws IOException
    {
        while ((stringTokenizer == null) || (!stringTokenizer.hasMoreTokens()))
        {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine());
        }
        return stringTokenizer.nextToken();
    }

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

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

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

    public static String nextLine() throws IOException
    {
        return bufferedReader.readLine();
    }

    public static void close()
    {
        out.close();
    }

    public static final long[] POWER2 = generatePOWER2();


    static class Array<Type> implements Iterable<Type>
    {
        private Object[] array;

        public Array(int size)
        {
            this.array = new Object[size];
        }

        public Array(int size, Type element)
        {
            this(size);
            Arrays.fill(this.array, element);
        }

        public Array(Array<Type> array, Type element)
        {
            this(array.size() + 1);
            for (int index = 0; index < array.size(); index++)
            {
                set(index, array.get(index));
            }
            set(size() - 1, element);
        }

        public Array(List<Type> list)
        {
            this(list.size());
            int index = 0;
            for (Type element: list)
            {
                set(index, element);
                index += 1;
            }
        }

        public Type get(int index)
        {
            return (Type)this.array[index];
        }
        public Array set(int index, Type value)
        {
            this.array[index] = value;
            return this;
        }

        public int size()
        {
            return this.array.length;
        }

        public List<Type> toList()
        {
            List<Type> result = new ArrayList<>();
            for (Type element: this)
            {
                result.add(element);
            }
            return result;
        }

        @Override
        public Iterator<Type> iterator()
        {
            return new Iterator<Type>()
            {
                int index = 0;

                @Override
                public boolean hasNext()
                {
                    return this.index < size();
                }

                @Override
                public Type next()
                {
                    Type result = Array.this.get(index);
                    index += 1;
                    return result;
                }
            };
        }
    }

    interface BiFunctionResult<Type0, Type1, TypeResult>
    {
        TypeResult apply(Type0 x0, Type1 x1, TypeResult x2);
    }

    static abstract class Edge<TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>>
    {
        public final TypeVertex vertex0;
        public final TypeVertex vertex1;

        public Edge(TypeVertex vertex0, TypeVertex vertex1, boolean bidirectional)
        {
            this.vertex0 = vertex0;
            this.vertex1 = vertex1;
            this.vertex0.edges.add(getThis());
            if (bidirectional)
            {
                this.vertex1.edges.add(getThis());
            }
        }

        private TypeVertex other(Vertex<TypeVertex, TypeEdge> vertex)
        {
            TypeVertex result;
            if (vertex0 == vertex)
            {
                result = vertex1;
            }
            else
            {
                result = vertex0;
            }
            return result;
        }

        public TypeVertex from(Vertex<TypeVertex, TypeEdge> to)
        {
            return other(to);
        }

        public TypeVertex to(Vertex<TypeVertex, TypeEdge> from)
        {
            return other(from);
        }

        public abstract TypeEdge getThis();
    }

    public static class EdgeDefault<TypeVertex extends Vertex<TypeVertex, EdgeDefault<TypeVertex>>> extends Edge<TypeVertex, EdgeDefault<TypeVertex>>
    {
        public EdgeDefault(TypeVertex vertex0, TypeVertex vertex1, boolean bidirectional)
        {
            super(vertex0, vertex1, bidirectional);
        }

        @Override
        public EdgeDefault<TypeVertex> getThis()
        {
            return this;
        }
    }

    public static class Vertex<TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>> implements Comparable<Vertex<? super TypeVertex, ? super TypeEdge>>
    {
        public final int index;
        public final List<TypeEdge> edges;

        public Vertex(int index)
        {
            this.index = index;
            this.edges = new ArrayList<>();
        }

        public static <TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>, TypeResult> TypeResult depthFirstSearch(
                BiFunctionResult<TypeVertex, TypeEdge, TypeResult> function,
                TypeVertex vertex,
                TypeEdge edge,
                TypeResult result,
                Array<Boolean> visited
        )
        {
            if (!visited.get(vertex.index))
            {
                visited.set(vertex.index, true);
                result = function.apply(vertex, edge, result);
                for (TypeEdge edgeNext: vertex.edges)
                {
                    TypeVertex vertexNext = edge.to(vertex);
                    result = depthFirstSearch(function, vertexNext, edgeNext, result, visited);
                }
            }
            return result;
        }

        public static <TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>, TypeResult> TypeResult depthFirstSearch(
                Array<TypeVertex> vertices,
                int indexVertexStart,
                BiFunctionResult<TypeVertex, TypeEdge, TypeResult> function,
                TypeResult result
        )
        {
            Array<Boolean> visited = new Array(vertices.size(), false);
            return depthFirstSearch(function, vertices.get(indexVertexStart), null, result, visited);
        }

        public static <TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>, TypeResult> TypeResult breadthFirstSearch(
                TypeVertex vertex,
                TypeEdge edge,
                BiFunctionResult<TypeVertex, TypeEdge, TypeResult> function,
                Array<Boolean> visited,
                LIFO<TypeVertex> verticesNext,
                LIFO<TypeEdge> edgesNext,
                TypeResult result
        )
        {
            if (!visited.get(vertex.index))
            {
                visited.set(vertex.index, true);
                result = function.apply(vertex, edge, result);
                for (TypeEdge edgeNext: vertex.edges)
                {
                    TypeVertex vertexNext = edgeNext.to(vertex);
                    if (!visited.get(vertexNext.index))
                    {
                        verticesNext.push(vertexNext);
                        edgesNext.push(edgeNext);
                    }
                }
            }
            return result;
        }

        public static <TypeVertex extends Vertex<TypeVertex, TypeEdge>, TypeEdge extends Edge<TypeVertex, TypeEdge>, TypeResult> TypeResult breadthFirstSearch(
                Array<TypeVertex> vertices,
                int indexVertexStart,
                BiFunctionResult<TypeVertex, TypeEdge, TypeResult> function,
                TypeResult result
        )
        {
            Array<Boolean> visited = new Array(vertices.size(), false);
            LIFO<TypeVertex> verticesNext = new LIFO<>();
            verticesNext.push(vertices.get(indexVertexStart));
            LIFO<TypeEdge> edgesNext = new LIFO<>();
            edgesNext.push(null);
            while (!verticesNext.isEmpty())
            {
                result = breadthFirstSearch(verticesNext.pop(), edgesNext.pop(), function, visited, verticesNext, edgesNext, result);
            }
            return result;
        }

        @Override
        public int compareTo(Vertex<? super TypeVertex, ? super TypeEdge> that)
        {
            return Integer.compare(this.index, that.index);
        }
    }

    public static class VertexDefault<TypeEdge extends Edge<VertexDefault<TypeEdge>, TypeEdge>> extends Vertex<VertexDefault<TypeEdge>, TypeEdge>
    {
        public VertexDefault(int index)
        {
            super(index);
        }
    }

    public static class Tuple2<Type0, Type1>
    {
        public final Type0 v0;
        public final Type1 v1;

        public Tuple2(Type0 v0, Type1 v1)
        {
            this.v0 = v0;
            this.v1 = v1;
        }
    }

    public static class Tuple2Comparable<Type0 extends Comparable<? super Type0>, Type1 extends Comparable<? super Type1>> extends Tuple2<Type0, Type1> implements Comparable<Tuple2Comparable<Type0, Type1>>
    {
        public Tuple2Comparable(Type0 v0, Type1 v1)
        {
            super(v0, v1);
        }

        @Override
        public int compareTo(Tuple2Comparable<Type0, Type1> that)
        {
            int result = this.v0.compareTo(that.v0);
            if (result == 0)
            {
                result = this.v1.compareTo(that.v1);
            }
            return result;
        }
    }

    public static class SingleLinkedList<Type>
    {
        public final Type element;
        public SingleLinkedList<Type> next;

        public SingleLinkedList(Type element, SingleLinkedList<Type> next)
        {
            this.element = element;
            this.next = next;
        }

        public void toCollection(Collection<Type> collection)
        {
            if (this.next != null)
            {
                this.next.toCollection(collection);
            }
            collection.add(this.element);
        }
    }

    public static class LIFO<Type>
    {
        public SingleLinkedList<Type> start;
        public SingleLinkedList<Type> end;

        public LIFO()
        {
            this.start = null;
            this.end = null;
        }

        public void push(Type element)
        {
            SingleLinkedList<Type> list = new SingleLinkedList<>(element, null);
            if (this.start == null)
            {
                this.start = list;
                this.end = list;
            }
            else
            {
                this.end.next = list;
                this.end = list;
            }
        }

        public Type pop()
        {
            Type result = this.start.element;
            this.start = this.start.next;
            return result;
        }

        public boolean isEmpty()
        {
            return this.start == null;
        }
    }

    public static class MapCount extends TreeMap<Long, Long>
    {
        private int size;

        public MapCount()
        {
            this.size = 0;
        }

        public MapCount(Comparator<? super Long> comparator)
        {
            super(comparator);
        }

        public long add(Long key, Long delta)
        {
            long result;
            if (delta > 0)
            {
                Long value = get(key);
                if (value == null)
                {
                    value = delta;
                }
                else
                {
                    value += delta;
                }
                put(key, value);
                result = delta;
            }
            else
            {
                result = 0;
            }
            this.size += result;
            return result;
        }

        public long remove(Long key, Long delta)
        {
            long result;
            if (delta > 0)
            {
                Long value = get(key) - delta;
                if (value <= 0)
                {
                    result = delta + value;
                    remove(key);
                }
                else
                {
                    result = delta;
                    put(key, value);
                }
            }
            else
            {
                result = 0;
            }
            this.size -= result;
            return result;
        }

        public int size()
        {
            return this.size;
        }
    }

    public static class MapSet<TypeKey extends Comparable<? super TypeKey>, TypeValue> extends TreeMap<TypeKey, TreeSet<TypeValue>> implements Iterable<TypeValue>
    {
        private int size;
        private Comparator<? super TypeValue> comparatorValue;

        public MapSet()
        {
            this(null);
        }

        public MapSet(Comparator<? super TypeValue> comparatorValue)
        {
            super();
            this.size = 0;
            this.comparatorValue = comparatorValue;
        }

        public TypeValue firstValue()
        {
            TypeValue result;
            Map.Entry<TypeKey, TreeSet<TypeValue>> firstEntry = firstEntry();
            if (firstEntry == null)
            {
                result = null;
            }
            else
            {
                result = firstEntry.getValue().first();
            }
            return result;
        }

        public Iterator<TypeValue> iterator()
        {
            return new Iterator<TypeValue>()
            {
                Iterator<TreeSet<TypeValue>> iteratorValues = values().iterator();
                Iterator<TypeValue> iteratorValue = null;

                @Override
                public boolean hasNext()
                {
                    return iteratorValues.hasNext() || (iteratorValue != null && iteratorValue.hasNext());
                }

                @Override
                public TypeValue next()
                {
                    if (iteratorValue == null || !iteratorValue.hasNext())
                    {
                        iteratorValue = iteratorValues.next().iterator();
                    }
                    return iteratorValue.next();
                }
            };
        }

        public TypeValue lastValue()
        {
            TypeValue result;
            Map.Entry<TypeKey, TreeSet<TypeValue>> lastEntry = lastEntry();
            if (lastEntry == null)
            {
                result = null;
            }
            else
            {
                result = lastEntry.getValue().last();
            }
            return result;
        }

        public boolean add(TypeKey key, TypeValue value)
        {
            TreeSet<TypeValue> set = get(key);
            if (set == null)
            {
                if (comparatorValue == null)
                {
                    set = new TreeSet<>();
                }
                else
                {
                    set = new TreeSet<>(comparatorValue);
                }
                put(key, set);
            }
            boolean result = set.add(value);
            if (result)
            {
                this.size += 1;
            }
            return result;
        }

        public boolean remove(TypeKey key, TypeValue value)
        {
            boolean result;
            TreeSet<TypeValue> set = get(key);
            if (set == null)
            {
                result = false;
            }
            else
            {
                result = set.remove(value);
                if (set.size() == 0)
                {
                    remove(key);
                }
                if (result)
                {
                    this.size -= 1;
                }
            }
            return result;
        }

        @Override
        public int size()
        {
            return this.size;
        }
    }

    public static int binarySearchMinimum(Function<Integer, Boolean> filter, int start, int end)
    {
        int result;
        if (start == end)
        {
            result = end;
        }
        else
        {
            int middle = start + (end - start) / 2;
            if (filter.apply(middle))
            {
                result = binarySearchMinimum(filter, start, middle);
            }
            else
            {
                result = binarySearchMinimum(filter, middle + 1, end);
            }
        }
        return result;
    }

    public static int binarySearchMaximum(Function<Integer, Boolean> filter, int start, int end)
    {
        return -binarySearchMinimum(x -> filter.apply(-x), -end, -start);
    }

    public static long divideCeil(long x, long y)
    {
        return (x + y - 1) / y;
    }

    public static long faculty(int n)
    {
        long result = 1;
        for (int index = 2; index <= n; index++)
        {
            result *= index;
        }
        return result;
    }

    public static int gcd(int a, int b)
    {
        // TODO: slow
        int result = 1;
        int min = Math.min(a, b);
        int max = Math.max(a, b);
        for (int test = 2; result == 1 && test <= min; test++)
        {
            if (min % test == 0 && max % test == 0)
            {
                result *= test * gcd(min / test, max / test);
            }
        }
        return result;
    }

    public static long[] generatePOWER2()
    {
        long[] result = new long[63];
        for (int x = 0; x < result.length; x++)
        {
            result[x] = 1L << x;
        }
        return result;
    }

    public static int lcm(int a, int b)
    {
        return a * b / gcd(a, b);
    }

    public static <T> List<T> permutation(long p, List<T> x)
    {
        List<T> copy = new ArrayList<>();
        for (int index = 0; index < x.size(); index++)
        {
            copy.add(x.get(index));
        }
        List<T> result = new ArrayList<>();
        for (int indexTo = 0; indexTo < x.size(); indexTo++)
        {
            int indexFrom = (int) p % copy.size();
            p = p / copy.size();
            result.add(copy.remove(indexFrom));
        }
        return result;
    }

    public static <Type> void println(Iterator<Type> iterator)
    {
        if (iterator.hasNext())
        {
            out.print(iterator.next());
        }
        while (iterator.hasNext())
        {
            out.print(" " + iterator.next());
        }
        out.println();
    }

    public static <Type> void println(Iterable<Type> iterable)
    {
        println(iterable.iterator());
    }

    public static void main(String[] args)
    {
        try
        {
            solve();
        } catch (IOException exception)
        {
            exception.printStackTrace();
        }
        close();
    }

    public static void solve() throws IOException
    {
        int n = nextInt();
        int result = 0;
        Set<Integer> nodesMostDistant = new TreeSet<>();
        for (int index = 0; index < n; index++)
        {
            int p = nextInt() - 1;
            if (p == index)
            {
                result += 1;
            }
            else
            {
                nodesMostDistant.add(p);
            }
        }
        result += nodesMostDistant.size() / 2;
        out.println(result);
    }
}