output_description: Print the maximum possible number of i such that p_i = i after operations.
  
  * * *
input_description: 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
attempt: #include <bits/stdc++.h>
  
  #define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
  #define RFOR(i,a) for(int i=(a); i >= 0; --i)
  #define FOE(i,a) for(auto i : a)
  #define ALL(c) (c).begin(), (c).end()
  #define RALL(c) (c).rbegin(), (c).rend()
  #define DUMP(x)  cerr << #x << " = " << (x) << endl;
  #define SUM(x) std::accumulate(ALL(x), 0LL)
  #define MIN(v) *std::min_element(v.begin(), v.end())
  #define MAX(v) *std::max_element(v.begin(), v.end())
  #define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
  #define BIT(n) (1LL<<(n))
  #define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
  
  typedef long long LL;
  template<typename T> using V = std::vector<T>;
  template<typename T> using VV = std::vector<std::vector<T>>;
  template<typename T> using VVV = std::vector<std::vector<std::vector<T>>>;
  
  template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
  template<class T> inline void print(T x) { std::cout << x << std::endl; }
  template<class T> inline void print_vec(const std::vector<T> &v) { for (int i = 0; i < v.size(); ++i) {  if (i != 0) {std::cout << " ";} std::cout << v[i];} std::cout << "\n"; }
  template<class T> inline bool inside(T y, T x, T H, T W) {return 0 <= y and y < H and 0 <= x and x < W; }
  template<class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
  template<class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) { return abs(x1 - x2) + abs(y1 - y2); }
  
  const int INF = 1L << 30;
  const double EPS = 1e-9;
  const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
  const std::vector<int> dy4 = { 0, 1, 0, -1 }, dx4 = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）
  const std::vector<int> dy8 = { 0, -1, 0, 1, 1, -1, -1, 1 }, dx8 = { 1, 0, -1, 0, 1, 1, -1, -1 };
  
  using namespace std;
  
  class UnionFind {
  public:
      vector<int> parent;
      vector<int> setSize;
  
      UnionFind(unsigned int size) {
          parent.resize(size + 1);
          iota(parent.begin(), parent.end(), 0);
          setSize.resize(size + 1, 1);
      }
  
      // xとyが同じ集合に属するか
      bool isSameSet(int x, int y) {
          return findRoot(x) == findRoot(y);
      }
  
      // xとyの属する集合を併合
      void unionSet(int x, int y) {
          x = findRoot(x);
          y = findRoot(y);
          if (x == y) { return; }
  
          parent[x] = y;
          setSize[y] += setSize[x];
      }
  
  private:
      // 木の根を求める
      int findRoot(int x) {
          if (parent[x] == x) {
              return x;
          }
          else {
              return parent[x] = findRoot(parent[x]);
          }
      }
  };
  
  int main() {
      cin.tie(0);
      ios::sync_with_stdio(false);
  
      int N, M;
      cin >> N >> M;
      vector<int> P(N);
      vector<int> num_idx(N);
      FOR(i, 0, N) {
          cin >> P[i];
          P[i]--;
          num_idx[P[i]] = i;
      }
  
      UnionFind uf(N);
      FOR(i, 0, M) {
          int x, y;
          cin >> x >> y;
          uf.unionSet(x - 1, y - 1);
      }
  
  
      int ans = 0;
      FOR(i, 0, N) {
          if (P[i] == i) {
              ans++;
          }
          else {
              int idx = num_idx[i];
              ans += uf.isSameSet(i, idx);
          }
      }
      print(ans);
  
      return 0;
  }
problem_description: 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.
samples: [{"input": "5 2\n    5 3 1 4 2\n    1 3\n    5 4", "output": "2\n    \n\nIf we perform the operation by choosing j=1, p becomes `1 3 5 4 2`, which is\noptimal, so the answer is 2.\n\n* * *"}, {"input": "3 2\n    3 2 1\n    1 2\n    2 3", "output": "3\n    \n\nIf we perform the operation by, for example, choosing j=1, j=2, j=1 in this\norder, p becomes `1 2 3`, which is obviously optimal. Note that we may choose\nthe same j any number of times.\n\n* * *"}, {"input": "10 8\n    5 3 6 8 7 10 9 1 2 4\n    3 1\n    4 1\n    5 9\n    2 5\n    6 5\n    3 5\n    8 9\n    7 9", "output": "8\n    \n\n* * *"}, {"input": "5 1\n    1 2 3 4 5\n    1 5", "output": "5\n    \n\nWe do not have to perform the operation."}]