#include<iostream>
#include<vector>
#include<set>
#include<stack>
#include<iterator>
#include<unordered_map>

using namespace std;
struct path{
  long x;
  long y;
};



class Node{
public:
  long val;
  set<Node*> nodes;
  int mark;
  Node* getNonVisitNode()
  {
	int ii;

	for(Node* node : nodes){
	  if(node->mark == 0){
		return node;
	  }
	}
	
	return NULL;
  }
};



struct Ret{
  set<Node*> *nodes;
  set<long>  *vals;
};

unordered_map<long,Ret*> map;
Ret* fRet;

Ret* getIsland(Node* start,long val){

  fRet = (Ret*)malloc(sizeof(Ret));
  fRet->nodes = new set<Node*>();
  fRet->vals  = new set<long>();
  
  stack<Node*> stack;
  start->mark = 1;
  stack.push(start);
  Node *node,*child;
  
  while(! stack.empty()){

	node = stack.top();

	fRet->nodes->insert(node);
	fRet->vals->insert(node->val);
	
	//cout << "node:" << node->val << endl;

	if(node->val == val){
	  //return true;
	}
	
	else{
	  child = node->getNonVisitNode();
	  if(child == NULL){
		stack.pop();
	  }
	  else{
		//cout << "val:" << child->val << endl;
		child->mark = 1;
		stack.push(child);
	  }
	}
  }
  
  return fRet;
}

bool isReach(Node* start,long val){

  stack<Node*> stack;
  start->mark = 1;
  stack.push(start);
  Node *node,*child;

  while(! stack.empty()){

	node = stack.top();
	//cout << "node:" << node->val << endl;

	if(node->val == val){
	  return true;
	}
	
	else{
	  child = node->getNonVisitNode();
	  if(child == NULL){
		stack.pop();
	  }
	  else{
		//cout << "val:" << child->val << endl;
		child->mark = 1;
		stack.push(child);
	  }
	}
  }
  
  return false;
}

int main(){

  long n,m;
  long ii,jj;
  vector<long> edge;
  vector<struct path> path;
  vector<vector <long>> paths;
  vector<Node> nodes;
  vector<struct Ret*>  rets;
  int cnt = 0;
  //1. 入力
  cin >> n >> m;

  edge.resize(n+1);
  path.resize(m+1);
  paths.resize(n+1);
  nodes.resize(n+1);

  for(ii=1; ii <= n ;ii++){
	cin >> edge[ii];
	nodes[ii].val = edge[ii];
	nodes[ii].mark = 0;
  }

  for(ii=1; ii <= m ; ii++){

	cin >> path[ii].x;
	cin >> path[ii].y;

	nodes[path[ii].x].nodes.insert(&nodes[path[ii].y]);
	nodes[path[ii].y].nodes.insert(&nodes[path[ii].x]);
  }

  Ret* ret;
  for(ii=1; ii <= n ; ii++){
	if(nodes[ii].mark != 1){
	  ret = getIsland(&nodes[ii],-1);
	  rets.push_back(ret);
	  for(long l : *(ret->vals)){
		map[l] = ret;
	  }
	}
  }

  Ret* ret2;
  //探索
  for(ii = 1; ii <= n; ii++){
	ret2 = map[nodes[ii].val];
	if(ret2->vals->find(ii) != ret2->vals->end()){
	  cnt++;
	}
	
//	for(Ret ret : rets){
//
//	  if(ret.nodes.find(&nodes[ii]) != ret.nodes.end()){
//		//		cout << ret.nodes.size() << endl;
//		//		for(long hval : ret.vals){
//		//		  cout << "hval" << hval << endl;
//		//		}
//		if(ret.vals.find(ii) != ret.vals.end()){
//		  //		  cout << "ii:" << ii << " nodeval:" << nodes[ii].val << endl;
//		  cnt += 1;
//		}
//	  }
//	  
//	}
	
  }


  //1.5 print node
  //for(ii = 1; ii <= n ;ii++){
  //	for(Node* node : nodes[ii].nodes){
  //	  cout << "from:"  << ii << "to:" << node->val << endl;
  //	}
  //}
  //2.ノードの探索
  
  //  for(ii=1; ii <= n ; ii++){
  //  	if(isReach(&nodes[ii],ii)){
  //  	  //cout << ii << endl;
  //  	  cnt += 1;
  //  	}
  //  
  //  	for(jj=1; jj <= n; jj++){
  //  	  nodes[jj].mark = 0;
  //  	}
  //  }
  
  //if(isReach(&nodes[1],1)){
  //	cout << "get" << endl;
  //}
  cout << cnt << endl;
  return 0;
}


Measured memory_bytes: 50968