import std.stdio, std.algorithm, std.string, std.conv, std.array, std.range, std.math;
import core.memory : GC;
int readint() { return readln.chomp.to!int; }
int[] readints() { return readln.split.to!(int[]); }
 
void main() {
    GC.disable();
    int n, m; readf("%d %d\n", &n,&m);
    int[] ps = readints();
 
    auto uf = new UnionFind(n);
    foreach (_; 0..m) {
        int[] xy = readints();
        uf.unite(xy[0] - 1, xy[1] - 1);
    }
 
    //iota(n).filter!(i => uf.same(i, ps[i] - 1)).array.length.writeln;
    int cnt;
    foreach (i; 0..n) cnt += uf.same(i, ps[i] - 1);
    writeln(cnt);
    string _ = readln;
}
 
class UnionFind {
    import std.algorithm.mutation;
    int[] p;
    this(int n) {
        p.length = n;
        p[0..$] = -1;
    }
    bool unite(int u, int v){
        u = root(u); v = root(v);
        if (u == v) return false;
        if (p[u] > p[v]) swap(u, v);
        p[u] += p[v]; p[v] = u;
        return true;
    }
    bool same(int u, int v){ return root(u) == root(v); }
    int root(int u){ return p[u] < 0 ? u : (p[u] = root(p[u])); }
    int size(int u){ return -p[u]; }
}
