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 JavaScript (node.js v5.12) (judge verdict: Wrong Answer)

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// parameter "input" gets all data
function Equals(input) {
    // the first line is assigned to input[0], the second line is assigned to input[1] similarly.
    var _a = parseInput(input), N = _a.N, p = _a.p, xy = _a.xy;
    var sets = DisjointSets.buildFrom(N, xy);
    //output
    var count = p.filter(function (num, i) { return sets.areInSameSet(num, i + 1); }).length;
    console.log(2);
    return count;
}
exports.Equals = Equals;
var DisjointSets = /** @class */ (function () {
    function DisjointSets(trees) {
        this.trees = trees;
    }
    DisjointSets.buildFrom = function (N, xy) {
        var trees = Array.apply(this, Array(N + 1)).map(function () { return new DisjointSetTree(); });
        xy.forEach(function (_a) {
            var x = _a.x, y = _a.y;
            return trees[x].union(trees[y]);
        });
        return new DisjointSets(trees);
    };
    DisjointSets.prototype.areInSameSet = function (num1, num2) {
        return this.trees[num1].isSameSetAs(this.trees[num2]);
    };
    return DisjointSets;
}());
var DisjointSetTree = /** @class */ (function () {
    function DisjointSetTree() {
        this.parent = this;
        this.rank = 0;
    }
    DisjointSetTree.prototype.isSameSetAs = function (other) {
        return this.find() === other.find();
    };
    // union by rank
    DisjointSetTree.prototype.union = function (other) {
        var _a;
        var xRoot = this.find();
        var yRoot = other.find();
        if (xRoot !== yRoot) {
            if (xRoot.rank < yRoot.rank) {
                _a = [yRoot, xRoot], xRoot = _a[0], yRoot = _a[1];
            }
            yRoot.parent = xRoot;
            if (yRoot.rank === xRoot.rank) {
                xRoot.rank = xRoot.rank + 1;
            }
        }
    };
    DisjointSetTree.prototype.find = function () {
        if (this.parent !== this) {
            this.parent = this.parent.find();
        }
        return this.parent;
    };
    return DisjointSetTree;
}());
function parseInput(input) {
    var _a = input.split("\n"), line0 = _a[0], line1 = _a[1], lines = _a.slice(2);
    var _b = parseSpaceSeparatedInts(line0), N = _b[0], M = _b[1];
    var p = parseSpaceSeparatedInts(line1);
    var xy = lines.map(function (line) {
        var _a = parseSpaceSeparatedInts(line), x = _a[0], y = _a[1];
        return { x: x, y: y };
    });
    return { N: N, M: M, p: p, xy: xy };
}
function parseSpaceSeparatedInts(line) {
    return line.split(" ").map(Number);
}
// Don't edit this line!
try {
    Equals(require("fs").readFileSync("/dev/stdin", "utf8"));
}
catch (e) {
    // ignore
}
//# sourceMappingURL=Equals.js.map