Problem:
Score : 400 points

Problem Statement

We have a permutation of the integers from 1 through N, p_1, p_2, .., p_N.
We also have M pairs of two integers between 1 and N (inclusive), represented as (x_1,y_1), (x_2,y_2), .., (x_M,y_M).
AtCoDeer the deer is going to perform the following operation on p as many times as desired so that the number of i (1 ≤ i ≤ N) such that p_i = i is maximized:

Choose j such that 1 ≤ j ≤ M, and swap p_{x_j} and p_{y_j}.

Find the maximum possible number of i such that p_i = i after operations.

Constraints

2 ≤ N ≤ 10^5

1 ≤ M ≤ 10^5

p is a permutation of integers from 1 through N.

1 ≤ x_j,y_j ≤ N

x_j ≠ y_j

If i ≠ j, \{x_i,y_i\} ≠ \{x_j,y_j\}.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
p_1 p_2 .. p_N
x_1 y_1
x_2 y_2
:
x_M y_M

Output

Print the maximum possible number of i such that p_i = i after operations.

Sample Input 1

5 2
5 3 1 4 2
1 3
5 4

Sample Output 1

2

If we perform the operation by choosing j=1, p becomes 1 3 5 4 2, which is optimal, so the answer is 2.

Sample Input 2

3 2
3 2 1
1 2
2 3

Sample Output 2

3

If we perform the operation by, for example, choosing j=1, j=2, j=1 in this order, p becomes 1 2 3, which is obviously optimal.
Note that we may choose the same j any number of times.

Sample Input 3

10 8
5 3 6 8 7 10 9 1 2 4
3 1
4 1
5 9
2 5
6 5
3 5
8 9
7 9

Sample Output 3

8

Sample Input 4

5 1
1 2 3 4 5
1 5

Sample Output 4

5

We do not have to perform the operation.

Solution in Perl (v5.18.2) (judge verdict: Accepted)

use strict;
use warnings;
use utf8;
use v5.18;

package UnionFind {

    sub new {
        my $class = shift;
        my %param = @_;

        my @parent = map { $_ } ( 0 .. $param{N} - 1 );
        my @rank = map { 0 } ( 0 .. $param{N} - 1 );

        my $self = bless {
            N      => $param{N},
            parent => \@parent,
            rank   => \@rank
          },
          $class;
        return $self;
    }

    sub find {
        my ( $self, $x ) = @_;

        # warn "debug: $self->{parent}->[$x], $x";
        return $x if $self->{parent}->[$x] == $x;

        $self->{parent}->[$x] = $self->find( $self->{parent}->[$x] );
        $self->{parent}->[$x];
    }

    sub unite {
        my ( $self, $x, $y ) = @_;
        $x = $self->find($x);
        $y = $self->find($y);
        return if $x == $y;

        my $rank   = $self->{rank};
        my $parent = $self->{parent};

        if ( $rank->[$x] < $rank->[$y] ) {
            $parent->[$x] = $y;
        }
        else {
            $parent->[$y] = $x;
            if ( $rank->[$x] == $rank->[$y] ) {
                $rank->[$x]++;
            }
        }
    }

    sub same {
        my ( $self, $x, $y ) = @_;
        $self->find($x) == $self->find($y);
    }
}

my ( $N, $M ) = split( / /, <STDIN> );
my @p = map { $_ - 1 } split( / /, <STDIN> );
my @x;
my @y;
for ( 1 .. $M ) {
    my ( $a, $b ) = split( / /, <STDIN> );
    push @x => $a - 1;
    push @y => $b - 1;
}

my $uf = UnionFind->new( N => $N );
for ( 0 .. $M - 1 ) {
    $uf->unite( $x[$_], $y[$_] );
}

my $ans = 0;
for ( 0 .. $N - 1 ) {
    $ans++ if $_ == $p[$_] or $uf->same( $_, $p[$_] );
}

print "$ans\n";