# ABC097D - Equals (ARC097D)

class UnionFind:  # O(α(N))

    def __init__(self, N):  # construct a Union-Find tree (1-idx)

        self.parent = [i for i in range(N + 1)]

        self.rank = [0] * (N + 1)



    def find(self, x):  # find the group (root) of a vertex

        if self.parent[x] == x:

            return x

        self.parent[x] = self.find(self.parent[x])

        return self.parent[x]



    def is_same(self, x, y):  # check two vertices are in the same group

        return self.find(x) == self.find(y)



    def unite(self, x, y):  # unite two groups

        x, y = self.find(x), self.find(y)

        if x == y:  # the same group

            return

        # unite a small one to a bigger one to balance trees

        if self.rank[x] < self.rank[y]:

            self.parent[x] = y

        else:

            self.parent[y] = x

            if self.rank[x] == self.rank[y]:

                self.rank[x] += 1





def main():

    # check i and Pi are connected components or not

    N, M, *A = list(map(int, open(0).read().split()))

    P, E = A[:N], A[N:]

    U = UnionFind(N)  # construct a Union-Find tree (1-idx)

    for v, u in zip(*[iter(E)] * 2):  # connected components are in the same group

        U.unite(v, u)

    ans = sum(U.is_same(i, p) for i, p in enumerate(P, 1))

    print(ans)





if __name__ == "__main__":

    main()
# ABC097D - Equals (ARC097D)

class UnionFind:

    __slots__ = ["_data_size", "_first_index", "_parents"]



    def __init__(self, data_size: int, is_zero_indexed: bool = True) -> None:

        self._data_size = data_size

        self._first_index = 0 if is_zero_indexed else 1

        self._parents = [-1] * (data_size + self._first_index)



    def find(self, x: int) -> int:

        """Find the group (root) of vertex x"""

        if self._parents[x] < 0:

            return x

        self._parents[x] = self.find(self._parents[x])

        return self._parents[x]



    def is_same(self, x: int, y: int) -> bool:

        """Return whether two vertices x and y are in the same group or not."""

        return self.find(x) == self.find(y)



    def unite(self, x: int, y: int) -> None:

        """Unite two groups of vertices x and y."""

        x, y = self.find(x), self.find(y)

        if x == y:

            return

        if self._parents[x] > self._parents[y]:

            x, y = y, x

        self._parents[x] += self._parents[y]

        self._parents[y] = x





def main():

    N, _, *PXY = list(map(int, open(0).read().split()))

    P, XY = PXY[:N], PXY[N:]

    uf = UnionFind(N, is_zero_indexed=False)

    for x, y in zip(*[iter(XY)] * 2):

        uf.unite(x, y)

    ans = sum(uf.is_same(i, p) for i, p in enumerate(P, 1))

    print(ans)





if __name__ == "__main__":

    main()

# ABC097D - Equals (ARC097D)
class UnionFind:  # O(α(N))
    def __init__(self, N):  # construct a Union-Find tree (1-idx)
        self.parent = [i for i in range(N + 1)]
        self.rank = [0] * (N + 1)

    def find(self, x):  # find the group (root) of a vertex
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def is_same(self, x, y):  # check two vertices are in the same group
        return self.find(x) == self.find(y)

    def unite(self, x, y):  # unite two groups
        x, y = self.find(x), self.find(y)
        if x == y:  # the same group
            return
        # unite a small one to a bigger one to balance trees
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


def main():
    # check i and Pi are connected components or not
    N, M, *A = list(map(int, open(0).read().split()))
    P, E = A[:N], A[N:]
    U = UnionFind(N)  # construct a Union-Find tree (1-idx)
    for v, u in zip(*[iter(E)] * 2):  # connected components are in the same group
        U.unite(v, u)
    ans = sum(U.is_same(i, p) for i, p in enumerate(P, 1))
    print(ans)


if __name__ == "__main__":
    main()

# ABC097D - Equals (ARC097D)
class UnionFind:
    __slots__ = ["_data_size", "_first_index", "_parents"]

    def __init__(self, data_size: int, is_zero_indexed: bool = True) -> None:
        self._data_size = data_size
        self._first_index = 0 if is_zero_indexed else 1
        self._parents = [-1] * (data_size + self._first_index)

    def find(self, x: int) -> int:
        """Find the group (root) of vertex x"""
        if self._parents[x] < 0:
            return x
        self._parents[x] = self.find(self._parents[x])
        return self._parents[x]

    def is_same(self, x: int, y: int) -> bool:
        """Return whether two vertices x and y are in the same group or not."""
        return self.find(x) == self.find(y)

    def unite(self, x: int, y: int) -> None:
        """Unite two groups of vertices x and y."""
        x, y = self.find(x), self.find(y)
        if x == y:
            return
        if self._parents[x] > self._parents[y]:
            x, y = y, x
        self._parents[x] += self._parents[y]
        self._parents[y] = x


def main():
    N, _, *PXY = list(map(int, open(0).read().split()))
    P, XY = PXY[:N], PXY[N:]
    uf = UnionFind(N, is_zero_indexed=False)
    for x, y in zip(*[iter(XY)] * 2):
        uf.unite(x, y)
    ans = sum(uf.is_same(i, p) for i, p in enumerate(P, 1))
    print(ans)


if __name__ == "__main__":
    main()

-class UnionFind:  # O(α(N)) -    def __init__(self, N):  # construct a Union-Find tree (1-idx) -        self.parent = [i for i in range(N + 1)] -        self.rank = [0] * (N + 1) +class UnionFind: +    __slots__ = ["_data_size", "_first_index", "_parents"] -    def find(self, x):  # find the group (root) of a vertex -        if self.parent[x] == x: +    def __init__(self, data_size: int, is_zero_indexed: bool = True) -> None: +        self._data_size = data_size +        self._first_index = 0 if is_zero_indexed else 1 +        self._parents = [-1] * (data_size + self._first_index) + +    def find(self, x: int) -> int: +        """Find the group (root) of vertex x""" +        if self._parents[x] < 0: -        self.parent[x] = self.find(self.parent[x]) -        return self.parent[x] +        self._parents[x] = self.find(self._parents[x]) +        return self._parents[x] -    def is_same(self, x, y):  # check two vertices are in the same group +    def is_same(self, x: int, y: int) -> bool: +        """Return whether two vertices x and y are in the same group or not.""" -    def unite(self, x, y):  # unite two groups +    def unite(self, x: int, y: int) -> None: +        """Unite two groups of vertices x and y.""" -        if x == y:  # the same group +        if x == y: -        # unite a small one to a bigger one to balance trees -        if self.rank[x] < self.rank[y]: -            self.parent[x] = y -        else: -            self.parent[y] = x -            if self.rank[x] == self.rank[y]: -                self.rank[x] += 1 +        if self._parents[x] > self._parents[y]: +            x, y = y, x +        self._parents[x] += self._parents[y] +        self._parents[y] = x -    # check i and Pi are connected components or not -    N, M, *A = list(map(int, open(0).read().split())) -    P, E = A[:N], A[N:] -    U = UnionFind(N)  # construct a Union-Find tree (1-idx) -    for v, u in zip(*[iter(E)] * 2):  # connected components are in the same group -        U.unite(v, u) -    ans = sum(U.is_same(i, p) for i, p in enumerate(P, 1)) +    N, _, *PXY = list(map(int, open(0).read().split())) +    P, XY = PXY[:N], PXY[N:] +    uf = UnionFind(N, is_zero_indexed=False) +    for x, y in zip(*[iter(XY)] * 2): +        uf.unite(x, y) +    ans = sum(uf.is_same(i, p) for i, p in enumerate(P, 1))