/*
 *1380E.Merging Towers
 *给出半径为1~n的n个盘子和m个塔，要求每个塔上盘子的半径始终从底向上递减
 *一次操作可以将一个塔上的任意个盘子移动到另一个塔的顶部。
 *令某一情形下的复杂度为将所有盘子移动到同一个塔上所需的最小操作数。
 *题目给出m-1次询问，每次询问时输出当前情形的复杂度并合并到两个塔的盘子到同一个塔上
  */
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
int t,n,m;
vector<int> g[maxn];
int a[maxn];
int father[maxn];
int findfather (int x) {
	int a=x;
	while (x!=father[x]) x=father[x];
	while (a!=father[a]) {
		int z=a;
		a=father[a];
		father[z]=x;
	}
	return x;
}
void Union (int x,int y) {
	for (auto i:g[y]) g[x].push_back(i);
	vector<int> wjm;
	g[y].swap(wjm);
	father[findfather(y)]=findfather(x);
}
int main () {
	int ans=0;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
		g[a[i]].push_back(i);
		if (i>1&&a[i]!=a[i-1]) ans++;
	}
	for (int i=1;i<=m;i++) father[i]=i;
	printf("%d\n",ans);
	for (int i=1;i<m;i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		int faU=findfather(u);
		int faV=findfather(v);
		vector<int> tt;
		if (g[faU].size()<g[faV].size()) swap(faU,faV);
		tt=g[faV];
		for (auto j:tt) {
			int u=j-1;
			if (u>=1&&u<=n)
				if (findfather(a[u])==faU) ans--;
			u=j+1;
			if (u>=1&&u<=n)
				if (findfather(a[u])==faU) ans--;
		}
		Union(u,v);
		printf("%d\n",ans);
	}
}


#include <iostream>
#include <list>
#include <cmath>
using namespace std;
void dfs(int , int , int , int [] , int[][21] , list<int>[]);
int LCA(int , int , int [] , int [][21]);
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n , m;
    cin >> n >> m;
    int lca[2 * m][21] = {0} ,
        k[n + 1] , anc[m + 1] ,
        depth[2 * m],
        val[m - 1] = {0};
    for (int i = 1 ; i <= m ; i++)
        anc[i] = i;
    list<int>adjlist[2 * m]; //tower

    for (int i = 1 ; i <= n ; i++)
        cin >> k[i];

    int ans = 0;
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++ans;
    }
    cout << ans << '\n';

    for (int i = 1 ; i < m ; i++){
        int a , b;
        cin >> a >> b;
        adjlist[m + i].push_back(anc[a]);
        adjlist[m + i].push_back(anc[b]);
        anc[a] = m + i;
    }

    dfs(2 * m - 1 , 0 , 0 , depth ,  lca , adjlist);

    for (int i = 1 ; i <= 20 ; i++){
        for (int j = 1 ; j < 2 * m ; j++)
            lca[j][i] = lca[lca[j][i - 1]][i - 1];
    }
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++val[LCA(k[i] , k[i + 1] , depth , lca) - m - 1];
    }
    for (int i = m + 1 ; i < 2 * m ; i++){
        ans -= val[i - m - 1];
        cout << ans << '\n';
    }
}
int LCA(int n1 , int n2 , int depth[] , int lca[][21]){
    if (depth[n1] < depth[n2])
        swap(n1 , n2);
    int d1 = depth[n1] , d2 = depth[n2];
    while(d1 > d2){
        n1 = lca[n1][(int)log2(d2 - d1)];
        d1 = depth[n1];
    }
    for (int i = 20 ; i >= 0 ; i--){
        if (lca[n1][i] != lca[n2][i])
            n1 = lca[n1][i] , n2 = lca[n2][i];
    }
    return lca[n1][0];
}
void dfs(int node , int d , int par , int depth[] ,  int lca[][21] , list<int> adjlist[]){
    lca[node][0] = par , depth[node] = d;
    for (int it : adjlist[node])
        dfs(it , d + 1 , node , depth , lca , adjlist);
}


#include <iostream>
#include <list>
#include <cmath>
using namespace std;
void dfs(int , int , int , int [] , int[][21] , list<int>[]);
int LCA(int , int , int [] , int [][21]);
int main(){
    int n , m;
    cin >> n >> m;
    int lca[2 * m][21] = {0} ,
        k[n + 1] , anc[m + 1] ,
        depth[2 * m],
        val[m - 1] = {0};
    for (int i = 1 ; i <= m ; i++)
        anc[i] = i;
    list<int>adjlist[2 * m]; //tower

    for (int i = 1 ; i <= n ; i++)
        cin >> k[i];

    int ans = 0;
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++ans;
    }
    cout << ans << '\n';

    for (int i = 1 ; i < m ; i++){
        int a , b;
        cin >> a >> b;
        adjlist[m + i].push_back(anc[a]);
        adjlist[m + i].push_back(anc[b]);
        anc[a] = m + i;
    }

    dfs(2 * m - 1 , 0 , 0 , depth ,  lca , adjlist);

    for (int i = 1 ; i <= 20 ; i++){
        for (int j = 1 ; j < 2 * m ; j++)
            lca[j][i] = lca[lca[j][i - 1]][i - 1];
    }
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++val[LCA(k[i] , k[i + 1] , depth , lca) - m - 1];
    }
    for (int i = m + 1 ; i < 2 * m ; i++){
        ans -= val[i - m - 1];
        cout << ans << '\n';
    }
}
int LCA(int n1 , int n2 , int depth[] , int lca[][21]){
    if (depth[n1] < depth[n2])
        swap(n1 , n2);
    int d1 = depth[n1] , d2 = depth[n2];
    while(d1 > d2){
        n1 = lca[n1][(int)log2(d2 - d1)];
        d1 = depth[n1];
    }
    for (int i = 20 ; i >= 0 ; i--){
        if (lca[n1][i] != lca[n2][i])
            n1 = lca[n1][i] , n2 = lca[n2][i];
    }
    return lca[n1][0];
}
void dfs(int node , int d , int par , int depth[] ,  int lca[][21] , list<int> adjlist[]){
    lca[node][0] = par , depth[node] = d;
    for (int it : adjlist[node])
        dfs(it , d + 1 , node , depth , lca , adjlist);
}


#include <cstdio>
#include <list>
#include <cmath>
using namespace std;
void dfs(int , int , int , int [] , int[][21] , list<int>[]);
int LCA(int , int , int [] , int [][21]);
int main(){
    int n , m;
    scanf("%d%d" , &n , &m);
    int lca[2 * m][21] = {0} ,
        k[n + 1] , anc[m + 1] ,
        depth[2 * m],
        val[m - 1] = {0};
    for (int i = 1 ; i <= m ; i++)
        anc[i] = i;
    list<int>adjlist[2 * m]; //tower

    for (int i = 1 ; i <= n ; i++)
        scanf("%d" , k + i);

    int ans = 0;
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++ans;
    }
    printf("%d\n" , ans);

    for (int i = 1 ; i < m ; i++){
        int a , b;
        scanf("%d%d" , &a , &b);
        adjlist[m + i].push_back(anc[a]);
        adjlist[m + i].push_back(anc[b]);
        anc[a] = m + i;
    }

    dfs(2 * m - 1 , 0 , 0 , depth ,  lca , adjlist);

    for (int i = 1 ; i <= 20 ; i++){
        for (int j = 1 ; j < 2 * m ; j++)
            lca[j][i] = lca[lca[j][i - 1]][i - 1];
    }
    for (int i = 1 ; i < n ; i++){
        if (k[i] != k[i + 1])
            ++val[LCA(k[i] , k[i + 1] , depth , lca) - m - 1];
    }
    for (int i = m + 1 ; i < 2 * m ; i++){
        ans -= val[i - m - 1];
        printf("%d\n" , ans);
    }
}
int LCA(int n1 , int n2 , int depth[] , int lca[][21]){
    if (depth[n1] < depth[n2])
        swap(n1 , n2);
    int d1 = depth[n1] , d2 = depth[n2];
    while(d1 > d2){
        n1 = lca[n1][(int)log2(d1 - d2)];
        d1 = depth[n1];
    }
    for (int i = 20 ; i >= 0 ; i--){
        if (lca[n1][i] != lca[n2][i])
            n1 = lca[n1][i] , n2 = lca[n2][i];
    }
    return lca[n1][0];
}
void dfs(int node , int d , int par , int depth[] ,  int lca[][21] , list<int> adjlist[]){
    lca[node][0] = par , depth[node] = d;
    for (int it : adjlist[node])
        dfs(it , d + 1 , node , depth , lca , adjlist);
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int N = 2e5 + 5;

set <int> s[N];

int par[N];
int n,m,ans;

int getpar(int u)
{
    return (par[u] < 0) ? u : (par[u] = getpar(par[u]));
}

void join(int u, int v)
{
    u = getpar(u);
    v = getpar(v);
    if (u == v) return;
    if (par[u] > par[v]) swap(u, v);
    par[u] += par[v];
    par[v] = u;
    //==========================
    for (int x : s[v])
    {
        if (s[u].find(x + 1) != s[u].end()) ans--;
        if (s[u].find(x - 1) != s[u].end()) ans--;
    }
    s[u].insert(s[v].begin(), s[v].end());
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("file.inp","r",stdin);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        s[x].insert(i);
    }
    ans = n - 1;
    for (int i = 1; i <= m; i++)
    {
        par[i] = -1;
        for (int x : s[i])
        {
            if (s[i].find(x + 1) != s[i].end()) ans--;
        }
    }
    cout << ans << "\n";
    for (int i = 1; i < m; i++)
    {
        int u,v;
        cin >> u >> v;
        join(u, v);
        cout << ans << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int N = 1e5 + 5;

set <int> s[N];

int par[N];
int n,m,ans;

int getpar(int u)
{
    return (par[u] < 0) ? u : (par[u] = getpar(par[u]));
}

void join(int u, int v)
{
    u = getpar(u);
    v = getpar(v);
    if (u == v) return;
    if (par[u] > par[v]) swap(u, v);
    par[u] += par[v];
    par[v] = u;
    //==========================
    for (int x : s[v])
    {
        if (s[u].find(x + 1) != s[u].end()) ans--;
        if (s[u].find(x - 1) != s[u].end()) ans--;
    }
    s[u].insert(s[v].begin(), s[v].end());
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("file.inp","r",stdin);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        s[x].insert(i);
    }
    ans = n - 1;
    for (int i = 1; i <= m; i++)
    {
        par[i] = -1;
        for (int x : s[i])
        {
            if (s[i].find(x + 1) != s[i].end()) ans--;
        }
    }
    cout << ans << "\n";
    for (int i = 1; i < m; i++)
    {
        int u,v;
        cin >> u >> v;
        join(u, v);
        cout << ans << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
const int N = 1e5 + 5;

set <int> s[N];

int par[N];
int n,m,ans;

int getpar(int u)
{
    return (par[u] < 0) ? u : (par[u] = getpar(par[u]));
}

void join(int u, int v)
{
    u = getpar(u);
    v = getpar(v);
    if (u == v) return;
    if (par[u] > par[v]) swap(u, v);
    par[u] += par[v];
    par[v] = u;
    //==========================
    for (int x : s[v])
    {
        if (s[u].find(x + 1) != s[u].end()) ans--;
        if (s[u].find(x - 1) != s[u].end()) ans--;
        s[u].insert(x);
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("file.inp","r",stdin);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        s[x].insert(i);
    }
    ans = n - 1;
    for (int i = 1; i <= m; i++)
    {
        par[i] = -1;
        for (int x : s[i])
        {
            if (s[i].find(x + 1) != s[i].end()) ans--;
        }
    }
    cout << ans << "\n";
    for (int i = 1; i < m; i++)
    {
        int u,v;
        cin >> u >> v;
        join(u, v);
        cout << ans << "\n";
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			cin>>tmp;
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			debug(i);
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				debug(tv[i][j]);
				debug(tv[i][k-1]);
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			debug(i.size());
			ans += i.size();
		}
		cout<<ans<<endl;
		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				int a,b;
				cin>>a>>b;
				a--,b--;
				ans -= vec[b].size();
				ans -= vec[a].size();
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					auto ori = vec[a].upper_bound(p);
					if(x==5)
					{
						debug(ori->first);
					}
					auto ri = ori;
					ori--;
					auto li = ori;
					// auto li = ri-1;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(ri!=vec[a].begin())
						{
							if(li->second==x-1)
							{
								vec[a].insert({ri->first,y});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						// debug(x);
						// debug(y);
						vec[a].insert({x,y});
					}
					debug(p.first);
					debug(p.second);
					for(auto tp : vec[a])
				{
					debug(tp.first);
					debug(tp.second);
				}
				}
				ans += vec[a].size();

				debug(vec[a].size());
				cout<<ans<<endl;
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			cin>>tmp;
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			debug(i);
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				debug(tv[i][j]);
				debug(tv[i][k-1]);
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			debug(i.size());
			ans += i.size();
		}
		cout<<ans<<endl;
		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				int a,b;
				cin>>a>>b;
				a--,b--;
				ans -= vec[b].size();
				ans -= vec[a].size();
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					auto ori = vec[a].upper_bound(p);

					auto ri = ori;
					ori--;
					auto li = ori;
					if(x==2)
					{
						debug(ori->first);
					}
					// auto li = ri-1;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(x==2)
						{
							debug(ri->first);
							debug(T+1);
						}
						if(ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							debug(x);
							debug(ri->second);
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						if(x==8)
						{
							debug(T);
						}
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						debug(x);
						debug(y);
						vec[a].insert({x,y});
					}
					debug(p.first);
					debug(p.second);
					for(auto tp : vec[a])
				{
					debug(tp.first);
					debug(tp.second);
				}
				}
				ans += vec[a].size();

				debug(vec[a].size());
				cout<<ans<<endl;
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			scanf("%d",&tmp);
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			ans += i.size();
		}
		cout<<ans<<endl;
		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				int a,b;
				cin>>a>>b;
				a--,b--;
				ans -= vec[b].size();
				ans -= vec[a].size();
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					auto ori = vec[a].upper_bound(p);
					auto ri = ori;
					ori--;
					auto li = ori;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						vec[a].insert({x,y});
					}
				}
				ans += vec[a].size();
				printf("%d\n",ans);
				// cout<<ans<<endl;
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			scanf("%d",&tmp);
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			ans += i.size();
		}
		cout<<ans<<endl;
		map<int,int> mp;

		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				debug(m);
				debug(t);
				int a,b;
				cin>>a>>b;
				a--,b--;
				// if(mp.count(a)) a = mp[a];
				// if(mp.count(b)) b = mp[b];
				// if(vec[a].size()<vec[b].size())
				// {
				// 	mp[a] = b;
				// 	// mp[b] = a;
				// 	swap(a,b);
				// }
				ans -= vec[b].size();
				ans -= vec[a].size();
				debug(vec[b].size());
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					debug(x);
					auto ori = vec[a].upper_bound(p);

					auto ri = ori;
					if(ori!=vec[a].begin())
						ori--;
															debug(x);

					auto li = ori;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(li!=ri&&ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						vec[a].insert({x,y});
					}

				}
				ans += vec[a].size();
				printf("%d\n",ans);
				debug(t);
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			scanf("%d",&tmp);
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			ans += i.size();
		}
		cout<<ans<<endl;
		map<int,int> mp;

		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				debug(m);
				debug(t);
				int a,b;
				cin>>a>>b;
				a--,b--;
				if(mp.count(a)) a = mp[a];
				if(mp.count(b)) b = mp[b];
				if(vec[a].size()<vec[b].size())
				{
					mp[a] = b;
					// mp[b] = a;
					swap(a,b);
				}
				ans -= vec[b].size();
				ans -= vec[a].size();
				debug(vec[b].size());
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					debug(x);
					auto ori = vec[a].upper_bound(p);

					auto ri = ori;
					if(ori!=vec[a].begin())
						ori--;
															debug(x);

					auto li = ori;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(li!=ri&&ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						vec[a].insert({x,y});
					}

				}
				ans += vec[a].size();
				printf("%d\n",ans);
				debug(t);
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			cin>>tmp;
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			debug(i);
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				debug(tv[i][j]);
				debug(tv[i][k-1]);
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			debug(i.size());
			ans += i.size();
		}
		cout<<ans<<endl;
		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				int a,b;
				cin>>a>>b;
				a--,b--;
				ans -= vec[b].size();
				ans -= vec[a].size();
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					auto ori = vec[a].upper_bound(p);
					auto ri = ori;
					ori--;
					auto li = ori;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						vec[a].insert({x,y});
					}
				}
				ans += vec[a].size();
				cout<<ans<<endl;
			}

		}

	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cstdlib>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 17;
const int MOD = 1e9 + 7;
int main(int argc, char const *argv[])
{
#ifdef xzp
	freopen("Input.txt", "r", stdin);
	freopen("Output.txt", "w", stdout);
#endif
	int T;
	// cin>>T;
	T = 1;
	while(T--)
	{
		int n,m;
		cin>>n>>m;

		vector<set<pair<int,int> > > vec(m);
		vector<vector<int > > tv(m);
		for (size_t i = 0; i < n; i++)
		{
			int tmp;
			scanf("%d",&tmp);
			tv[tmp-1].push_back(i+1);
		}
		for (size_t i = 0; i < m; i++)
		{
			sort(tv[i].begin(),tv[i].end());
			for (size_t j = 0; j < tv[i].size(); j++)
			{
				int k = j+1;
				while(k<tv[i].size()&&tv[i][k]==tv[i][k-1]+1)
				{
					k++;
				}
				vec[i].insert({tv[i][j],tv[i][k-1]});
				j = k-1;
			}
		}
		int ans = -1;
		for(auto i : vec)
		{
			ans += i.size();
		}
		cout<<ans<<endl;
		map<int,int> mp,mpb;
		for(int i=0;i<m;++i) mpb[i] = i;
		mp.clear();
		for (size_t t = 1; t < m; t++)
		{
			if(t)
			{
				debug(m);
				debug(t);
				int a,b;
				cin>>a>>b;
				a--,b--;
				if(mp.count(a)) a = mp[a];
				if(mp.count(b)) b = mp[b];
				if(vec[a].size()<vec[b].size())
				{
					mp[mpb[a]] = b;
					mpb[b] = mpb[a];
					// mp[b] = a;
					swap(a,b);
				}
				ans -= vec[b].size();
				ans -= vec[a].size();
				debug(vec[b].size());
				for(auto p:vec[b])
				{
					int x = p.first,y = p.second;
					debug(x);
					auto ori = vec[a].upper_bound(p);

					auto ri = ori;
					if(ori!=vec[a].begin())
						ori--;
					auto li = ori;
					if(ri!=vec[a].end()&&ri->first==y+1)
					{
						if(li!=ri&&ri!=vec[a].begin()&&li->second==x-1)
						{
							{
								vec[a].insert({li->first,ri->second});
								vec[a].erase(li);
							}
						}
						else
						{
							vec[a].insert({x,ri->second});
						}
						vec[a].erase(ri);
					}
					else if(ri!=vec[a].begin()&&li->second==x-1)
					{
						--ri;
						{
							vec[a].insert({ri->first,y});
							vec[a].erase(ri);
						}
					}
					else
					{
						vec[a].insert({x,y});
					}

				}
				ans += vec[a].size();
				printf("%d\n",ans);
				debug(t);
			}

		}

	}

	return 0;
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int fid (int par) {
	if (p[par] != par) {
		p[par] = fid (p[par]);
	}
	return p[par];
}

int main () {
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		fid (a), fid (b);
		if (ma[p[a]].size () < ma[p[b]].size ()) {
			swap (a, b);
		}
		int pa = fid (a), pb = fid (b);
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			int pp = fid (x.first);
			if (pp == pa) {
				su -= 2 * x.second;
			}
			else if (pp != pb)  {
				ma[pa][pp] += x.second;
			}
		}
		p[pb] = pa;
		vector<int> v;
		for (auto x : ma[pa]) {
			int pp = fid (x.first);
			if (pp == pa) {
				v.push_back (x.first);
			}
		}
		for (int  x : v) {
			ma[pa].erase (ma[pa].find (x));
		}
		cout << su / 2 << "\n";
	}
}


#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

int n, m;
vector<int> p;
vector<vector<int>> val;
vector<int> who;

int getp(int a){
 return a == p[a] ? a : p[a] = getp(p[a]);
}

int main(){
 scanf("%d%d", &n, &m);
 p.resize(m);
 val.resize(m);
 who.resize(n);
 int ans = n - 1;
 forn(i, m)
  p[i] = i;
 forn(i, n){
  int x;
  scanf("%d", &x);
  --x;
  who[i] = x;
  ans -= (i && who[i] == who[i - 1]);
  val[who[i]].push_back(i);
 }
 printf("%d\n", ans);
 forn(i, m - 1){
  int v, u;
  scanf("%d%d", &v, &u);
  v = getp(v - 1), u = getp(u - 1);
  if (val[v].size() < val[u].size())
   swap(v, u);
  for (int x : val[u]){
   if (x) ans -= who[x - 1] == v;
   if (x < n - 1) ans -= who[x + 1] == v;
  }
  for (int x : val[u]){
   val[v].push_back(x);
   who[x] = v;
  }
  p[u] = v;
  printf("%d\n", ans);
 }
 return 0;
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int fid (int par) {
	if (p[par] != par) {
		p[par] = fid (p[par]);
	}
	return p[par];
}

int main () {
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		if (ma[p[a]].size () < ma[p[b]].size ()) {
			swap (a, b);
		}
		int pa = fid (a), pb = fid (b);
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			if (fid (x.first) == pa) {
				su -= 2 * x.second;
			}
			else {
				ma[pa][fid (x.first)] += x.second;
			}
		}
		p[b] = pa;
		cout << su / 2 << "\n";
	}
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int fid (int par) {
	if (p[par] != par) {
		p[par] = fid (p[par]);
	}
	return p[par];
}

int main () {
	ios_base :: sync_with_stdio (false);
	cin.tie (nullptr);
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		fid (a), fid (b);
		int pa = fid (a), pb = fid (b);
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			int pp = fid (x.first);
			if (pp == pa) {
				su -= 2 * x.second;
			}
			else if (pp != pb)  {
				ma[pa][pp] += x.second;
			}
		}
		p[pb] = pa;
		cout << su / 2 << "\n";
	}
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int main () {
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			si[ar[i]]++;
			si[ar[i - 1]]++;
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		if (ma[p[a]].size () < ma[p[b]].size ()) {
			swap (a, b);
		}
		int pa = p[a], pb = p[b];
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			if (p[x.first] == pa) {
				su -= 2 * x.second;
			}
			else {
				ma[pa][p[x.first]] += x.second;
			}
		}
		p[b] = pa;
		cout << su / 2 << "\n";
	}
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int fid (int par) {
	if (p[par] != par) {
		p[par] = fid (p[par]);
	}
	return p[par];
}

int main () {
	ios_base :: sync_with_stdio (false);
	cin.tie (nullptr);
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		fid (a), fid (b);
		if (ma[p[a]].size () < ma[p[b]].size ()) {
			swap (a, b);
		}
		int pa = fid (a), pb = fid (b);
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			int pp = fid (x.first);
			if (pp == pa) {
				su -= 2 * x.second;
			}
			else if (pp != pb)  {
				ma[pa][pp] += x.second;
			}
		}
		p[pb] = pa;
		cout << su / 2 << "\n";
	}
}


#include <bits/stdc++.h>
#define MAX (ll)(2e5 + 7)
#define INF (ll)(1e18)
#define MOD (ll)(1e9)

using namespace std;
using ll = long long;
using cd = complex<double>;

int p[MAX], si[MAX], su = 0;
map<int, int> ma[MAX];

int fid (int par) {
	if (p[par] != par) {
		p[par] = fid (p[par]);
	}
	return p[par];
}

int main () {
	int n, m;
	cin >> n >> m;
	int ar[n];
	for (int i = 0; i < m; i++) {
		p[i + 1] = i + 1;
	}
	for (int i = 0; i < n; i++) {
		cin >> ar[i];
	}
	for (int i = 1; i < n; i++) {
		if (ar[i] != ar[i - 1]) {
			ma[ar[i]][ar[i - 1]]++;
			ma[ar[i - 1]][ar[i]]++;
			su += 2;
		}
	}
	cout << su / 2 << "\n";
	for (int i = 1; i < m; i++) {
		int a, b;
		cin >> a >> b;
		fid (a), fid (b);
		if (ma[p[a]].size () < ma[p[b]].size ()) {
			swap (a, b);
		}
		int pa = fid (a), pb = fid (b);
		if (pa == pb) {
			continue;
		}
		for (auto x : ma[pb]) {
			int pp = fid (x.first);
			if (pp == pa) {
				su -= 2 * x.second;
			}
			else if (pp != pb)  {
				ma[pa][pp] += x.second;
			}
		}
		p[b] = pa;
		vector<int> v;
		for (auto x : ma[pa]) {
			int pp = fid (x.first);
			if (pp == pa) {
				v.push_back (x.first);
			}
		}
		for (int  x : v) {
			ma[pa].erase (ma[pa].find (x));
		}
		cout << su / 2 << "\n";
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
void solve(int countu){
	int n,m;
	cin>>n>>m;
	set<int> s[m+1];
	int ans=n-1;
	int par[m+1];
	repeat(i,1,m+1)
		par[i]=i;
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=par[a];
		b=par[b];
		if(s[a].size()<s[b].size()){
			setint_iterator it=s[a].begin();
			while(it!=s[a].end()){
				s[b].insert((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				if(s[a].count((*it)+1))
					ans++;
				s[a].erase(it++);
			}
			par[a]=b;
		}
		else{
			setint_iterator it=s[b].begin();
			while(it!=s[b].end()){
				s[a].insert((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				if(s[b].count((*it)+1))
					ans++;
				s[b].erase(it++);
			}
			par[b]=a;
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
void solve(int countu){
	int n,m;
	cin>>n>>m;
	set<int> s[m+1];
	int ans=n-1;
	int par[m+1];
	repeat(i,1,m+1)
		par[i]=i;
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=par[a];
		b=par[b];
		if(s[a].size()<s[b].size()){
			setint_iterator it=s[a].begin();
			while(it!=s[a].end()){
				s[b].insert((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				if(s[a].count((*it)+1))
					ans++;
				if(s[a].count((*it)-1))
					ans++;
				s[a].erase(it++);
			}
			par[a]=b;
		}
		else{
			setint_iterator it=s[b].begin();
			while(it!=s[b].end()){
				s[a].insert((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				if(s[b].count((*it)+1))
					ans++;
				if(s[b].count((*it)-1))
					ans++;
				s[b].erase(it++);
			}
			par[b]=a;
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
int a[200001];
int find(int x){
	if(a[x]==-1)
		return x;
	return find(a[x]);
}
set<int> s[200001];
void insert(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y)
		return;
	if(s[x].size()<=s[y].size()){
		a[x]=y;
		return;
	}
	a[y]=x;
}
void solve(int countu){
	int n,m;
	cin>>n>>m;
	int ans=n-1;
	memset(a,-1,sizeof(a));
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=find(a);
		b=find(b);
		if(s[a].size()<s[b].size()){
			set<int> s1=s[a];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[b].insert((*it));
				s[a].erase((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				if(s[a].count((*it)+1))
					ans++;
				if(s[a].count((*it)-1))
					ans++;
				it++;
			}
			insert(a,b);
			s[a].clear();
			s1.clear();
		}
		else{
			set<int> s1=s[b];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[a].insert((*it));
				s[b].erase((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				if(s[b].count((*it)+1))
					ans++;
				if(s[b].count((*it)-1))
					ans++;
				it++;
			}
			s[b].clear();
			s1.clear();
			insert(a,b);
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
void solve(int countu){
	int n,m;
	cin>>n>>m;
	set<int> s[m+1];
	int ans=n-1;
	int par[m+1];
	repeat(i,1,m+1)
		par[i]=i;
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=par[a];
		b=par[b];
		if(s[a].size()<s[b].size()){
			setint_iterator it=s[a].begin();
			while(it!=s[a].end()){
				s[b].insert((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				s[a].erase(it++);
			}
			par[a]=b;
		}
		else{
			setint_iterator it=s[b].begin();
			while(it!=s[b].end()){
				s[a].insert((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				s[b].erase(it++);
			}
			par[b]=a;
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
void solve(int countu){
	int n,m;
	cin>>n>>m;
	set<int> s[m+1];
	int ans=n-1;
	int par[m+1];
	repeat(i,1,m+1)
		par[i]=i;
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=par[a];
		b=par[b];
		if(s[a].size()<s[b].size()){
			set<int> s1=s[a];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[b].insert((*it));
				s[a].erase((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				if(s[a].count((*it)+1))
					ans++;
				if(s[a].count((*it)-1))
					ans++;
				it++;
			}
			par[a]=b;
			s[a].clear();
			s1.clear();
		}
		else{
			set<int> s1=s[b];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[a].insert((*it));
				s[b].erase((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				if(s[b].count((*it)+1))
					ans++;
				if(s[b].count((*it)-1))
					ans++;
				it++;
			}
			s[b].clear();
			s1.clear();
			par[b]=a;
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define mod 1000000007
#include<string.h>
#define inf 1000000000000000000
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
#define PI 3.14159265359
#define endl '\n'
#define mapint_iterator map<int,int> :: iterator
#define mapll_iterator map<ll,ll> :: iterator
#define setint_iterator set<int> :: iterator
#define setll_iterator set<ll> :: iterator
#define setpint_iterator set<pint> :: iterator
#define setpll_iterator set<pll> :: iterator
#define cout1(a) cout<<a<<endl
#define cout2(a,b) cout<<a<<' '<<b<<endl
#define cout3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
#define cout4(a,b,c,d) cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl
#define vcout(v,i) cout<<v[i].fi<<" "<<v[i].se<<endl
typedef priority_queue<pair<pll,pll>,vector<pair<pll,pll> >,greater<pair<pll,pll> > > pqset;
typedef priority_queue<pll,vector<pll>,greater<pll> > pqset_ll;
#define pb push_back
#define pf push_front
#define fi first
#define mkp make_pair
#define se second
ll dxk[]={0,0,1,-1,1,1,-1,-1};
ll dyk[]={1,-1,0,0,1,-1,1,-1};
#include <ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> os;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update> os_pair;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repeat(i,start,n) for(ll i=start;i<n;i++)
ll ll_max(ll a,ll b,ll c){return max(a,max(b,c));}
int int_max(int a,int b,int c){return max(a,max(b,c));}
ll ll_min(ll a,ll b,ll c){return min(a,min(b,c));}
int int_min(int a,int b,int c){return min(a,min(b,c));}
ll max(int a,ll b){ return max((ll)a,b);}
ll min(int a,ll b){ return min((ll)a,b);}
ll min(ll a,int b){ return min(a,(ll)b);}
ll max(ll a,int b){ return max(a,(ll)b);}
ll dx[]={0,0,1,-1};
ll dy[]={1,-1,0,0};
ll power(ll a,ll b){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod)
			res%=mod;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod)
		res%=mod;
	return res;
}
ll power(ll a,ll b,ll mod1){
	if(a==1)
		return 1;
	if(b==0)
		return 1;
	ll c=power(a,b/2,mod1);
	ll res=1;
	if(b%2){
		res=c*c;
		if(res>=mod1)
			res%=mod1;
		res*=a;
	}
	else
		res=c*c;
	if(res>=mod1)
		res%=mod1;
	return res;
}
ll modInv(ll a){return power(a,mod-2);}
ll fact[1],inv[1];
void factorial(ll n){
	fact[0]=1;
	for(ll i=1;i<=n;i++){
		fact[i]=fact[i-1]*i;
		if(fact[i]>=mod)
			fact[i]%=mod;
	}
}
void InvFactorial(ll n){
	inv[0]=1;
	for(ll i=1;i<=n;i++)
		inv[i]=modInv(fact[i]);
}
ll ncr(ll n,ll r){
	if(n<r||n<0||r<0)
		return 0;
	ll b=inv[n-r];
	ll c=inv[r];
	ll a=fact[n]*b;
	if(a>=mod)
		a%=mod;
	a*=c;
	if(a>=mod)
		a%=mod;
	return a;
}
bool prime[1];
vector<int> primes;
void remove_duplicates(vector<int> &v){sort(v.begin(),v.end());int _size=unique(v.begin(),v.end())-v.begin();v.resize(_size);}
ll gcdll(ll u, ll v){
    ll shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctzll(u | v);
    u >>= __builtin_ctzll(u);
    do {
        v >>= __builtin_ctzll(v);
        if (u > v) {
            ll t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
unsigned int gcd(unsigned int u, unsigned int v){
    unsigned int shift;
    if (u == 0) return v;
    if (v == 0) return u;
    shift = __builtin_ctz(u | v);
    u >>= __builtin_ctz(u);
    do {
        v >>= __builtin_ctz(v);
        if (u > v) {
            unsigned int t = v;
            v = u;
            u = t;
        }
        v = v - u;
    } while (v != 0);
    return u << shift;
}
void sieve(ll n){
    memset(prime,true,sizeof(prime));
	prime[1]=false;
    for (ll p=2;p*p<=n;p++){
        if (prime[p]){
            for (ll i=p*p;i<=n;i+=p)
                prime[i]=false;
        }
    }
    repeat(i,2,n+1)
    	if(prime[i])
    		primes.pb(i);
}
//ifstream cin("b_read_on.txt"); ofstream cout("output.txt");
//Use (<<) for multiplication
//Use (>>) for division
// find_by_order -> value at index
// order_of_key -> index of value
// in Floyd-Warshall Algo, k is outer loop
//__gcd(0,0) gives runtime error
//power(a,b) == power(a,b%phi(a)) Fermet's Theorem
//never use "=" operator in compare function
//For checking odd cycles, check bipartite
//Range in iterative segment tree [a,b)
// no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) , (sqrt(10^9),3409) ;
int a[200001];
int find(int x){
	if(a[x]==-1)
		return x;
	return find(a[x]);
}
set<int> s[200001];
void insert(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y)
		return;
	if(s[x].size()<=s[y].size()){
		a[x]=y;
		return;
	}
	a[y]=x;
}
void solve(int countu){
	int n,m;
	cin>>n>>m;
	int ans=n-1;
	memset(a,-1,sizeof(a));
	rep(i,n){
		int a;
		cin>>a;
		s[a].insert(i);
		if(s[a].count(i+1))
			ans--;
		if(s[a].count(i-1))
			ans--;
	}
	m--;
	cout1(ans);
	while(m--){
		int a,b;
		cin>>a>>b;
		a=find(a);
		b=find(b);
		if(s[a].size()<s[b].size()){
			set<int> s1=s[a];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[b].insert((*it));
				s[a].erase((*it));
				if(s[b].count((*it)+1))
					ans--;
				if(s[b].count((*it)-1))
					ans--;
				if(s[a].count((*it)+1))
					ans++;
				it++;
			}
			insert(a,b);
			s[a].clear();
			s1.clear();
		}
		else{
			set<int> s1=s[b];
			setint_iterator it=s1.begin();
			while(it!=s1.end()){
				s[a].insert((*it));
				s[b].erase((*it));
				if(s[a].count((*it)+1))
					ans--;
				if(s[a].count((*it)-1))
					ans--;
				if(s[b].count((*it)+1))
					ans++;
				it++;
			}
			s[b].clear();
			s1.clear();
			insert(a,b);
		}
		cout1(ans);
	}
}
int main(){
	cin.tie(NULL);cout.tie(NULL);cin.sync_with_stdio(0);cout.sync_with_stdio(0);cout<<fixed;
	srand(time(0));
	//cout.precision(9);
	int t=1;
	//cin>>t;
	int countu=1;
	for(int i=1;i<=t;i++){
		solve(countu);
		countu++;
	}
}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    set<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].insert(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }
    m-- ;
    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(auto j:in[b])
        {

            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(auto j:in[b]) { ar[j]=a ; in[a].insert(j) ;  }

       // in[b].clear() ;

    }
    cout<<ans<<endl ;

}


#include<bits/stdc++.h>
//#define int long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const int N=200001 ;
int main()
{
    fast ;
    int n,m ;
    cin>>n>>m ;
    vector<int>in[m+1] ;
    int ar[n+1] ;
    for(int i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    int ans=0 ;
    for(int i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    int a,b ;
    m-- ;
    while(m--)
    {
        cout<<ans<<endl ;
        cin>>a>>b ;

        for(int j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(int j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

        in[b].clear() ;
    }
    cout<<ans<<endl ;

}


#include<bits/stdc++.h>
//#define int long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const int N=200001 ;
int main()
{
    fast ;
    int n,m ;
    cin>>n>>m ;
    vector<int>in[m+1] ;
    int ar[n+1] ;
    for(int i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    int ans=0 ;
    for(int i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    int a,b ;
    m-- ;
    while(m--)
    {
        cout<<ans<<endl ;
        cin>>a>>b ;

        for(int j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(int j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

        in[b].clear() ;
    }

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    set<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].insert(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(auto j:in[b])
        {

            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(auto j:in[b]) { ar[j]=a ; in[a].insert(j) ;  }

    }

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    vector<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(ll j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(ll j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

        in[b].clear() ;
    }

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    set<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].insert(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }
    m-- ;
    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        if(in[a].size()<in[b].size()) in[a].swap(in[b]) ;

        for(auto j:in[b])
        {

            if(in[a].find(j-1)!=in[a].end()) ans-- ;

            if(in[a].find(j+1)!=in[a].end()) ans-- ;
        }

        for(auto j:in[b]) { ar[j]=a ; in[a].insert(j) ;  }

        in[b].clear() ;

    }
    cout<<ans<<endl ;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    vector<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(ll j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        in[b].clear() ;

        for(ll j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

    }

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    vector<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    ll ans=0 ;
    for(ll i=0;i<n-1;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(ll j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(ll j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

        in[b].clear() ;
    }

}


#include<bits/stdc++.h>
//#define int long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const int N=200001 ;
int main()
{
    fast ;
    int n,m ;
    cin>>n>>m ;
    vector<int>in[m+1] ;
    int ar[n+1] ;
    for(int i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].push_back(i) ;
    }
    int ans=0 ;
    for(int i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    int a,b ;
    while(m--)
    {
        cout<<ans<<endl ;
        cin>>a>>b ;

        for(int j:in[b])
        {
            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(int j:in[b]) { ar[j]=a ; in[a].push_back(j) ; }

        in[b].clear() ;
    }

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    set<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].insert(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }
    m-- ;
    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(auto j:in[b])
        {

            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(auto j:in[b]) { ar[j]=a ; in[a].insert(j) ;  }

        in[b].clear() ;

    }
    cout<<ans<<endl ;

}


#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define ff first
#define ss second
#define all(x) x.begin(),x.end()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL);
using namespace std ;
const ll N=200001 ;
int main()
{
    fast ;
    ll n,m ;
    cin>>n>>m ;
    set<ll>in[m+1] ;
    ll ar[n+1] ;
    for(ll i=1;i<=n;i++)
    {
        cin>>ar[i] ;
        in[ar[i]].insert(i) ;
    }
    ll ans=0 ;
    for(ll i=1;i<n;i++)
    {
        if(ar[i]!=ar[i+1]) ans++ ;
    }

    while(m--)
    {
        cout<<ans<<endl ;
        ll a,b ;
        cin>>a>>b ;

        for(auto j:in[b])
        {

            if(j-1>=1&&ar[j-1]==a) ans-- ;

            if(j+1<=n&&ar[j+1]==a) ans-- ;
        }

        for(auto j:in[b]) { ar[j]=a ; in[a].insert(j) ;  }

        in[b].clear() ;

    }

}


#include<bits/stdc++.h>
#define ll  long long
#define pb push_back
#define  line cout<<endl
#define FAST_IO std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pii pair<int,int>
using namespace std;

// priority_queue<ll, vector<ll>, less<ll>>pq;     // Max Heap
// priority_queue<ll, vector<ll>, greater<ll>>pq;

//FOR FINDING PRIME NO TO A LIMIT IN O(N*LOG(LOG(N))
// const int max_n = 2e5 + 1;

// vector <int> isPrime(max_n,1);

// void sieve(vector <int> &isPrime){
//   isPrime[0] = 0;
//   isPrime[1] = 0;
//   for(ll i = 2;i < max_n;i++){
//     if(isPrime[i])
//       for(ll j = i*i;j < max_n;j+=i){
//         isPrime[j] = 0;
//       }
//   }
// }

void solve()
{
 int n,m,t,a,b,g,h;
 cin>>n>>m;
 map<int,int> mp[m+1];
 vector<int> size(m+1);

//  for(int i=1;i<=m;i++)
//  root[i]=i;

 //vector<int> t(n);
 int cnt=0;
 for(int i=1;i<=n;i++){
     cin>>t;
     mp[t][i]++;
     size[t]++;
     if(mp[t][i-1])
     cnt++;
 }

//  for(int i=1;i<=m;i++){
//     for(auto p:mp[i]){
//         if()
//     }
//  }
cout<<n-1-cnt<<endl;
for(int i=1;i<m;i++){
    cin>>g>>h;
    if(size[g]<=size[h]){
        b=g;
        a=h;
    }
    else
    {
        b=h;
        a=g;
    }
   // cout<<a<<" "<<b<<" ";

    for(auto p:mp[b]){
        if(p.second){
        if(mp[a][p.first-1])
        cnt++;
        if(mp[a][p.first+1])
        cnt++;

    }
    }
    for(auto p:mp[h]){
        if(p.second){
        mp[g][p.first]++;
    }

    }
    // for(auto p:mp[a])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    // for(auto p:mp[b])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    cout<<n-1-cnt<<endl;
    size[g]+=size[h];
}

// for(auto i:size)
// cout<<i;

    return ;
}

int main()
{
    FAST_IO
 int t=1;
//cin>>t;
 while(t--){
 solve();
 }
   return 0;
}


#include<bits/stdc++.h>
#define ll  long long
#define pb push_back
#define  line cout<<endl
#define FAST_IO std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pii pair<int,int>
using namespace std;

// priority_queue<ll, vector<ll>, less<ll>>pq;     // Max Heap
// priority_queue<ll, vector<ll>, greater<ll>>pq;

//FOR FINDING PRIME NO TO A LIMIT IN O(N*LOG(LOG(N))
// const int max_n = 2e5 + 1;

// vector <int> isPrime(max_n,1);

// void sieve(vector <int> &isPrime){
//   isPrime[0] = 0;
//   isPrime[1] = 0;
//   for(ll i = 2;i < max_n;i++){
//     if(isPrime[i])
//       for(ll j = i*i;j < max_n;j+=i){
//         isPrime[j] = 0;
//       }
//   }
// }
vector<int> root;
int get(int a){
    return a==root[a]?a:root[a]=get(root[a]);
}

void solve()
{
 int n,m,t,a,b,g,h;
 cin>>n>>m;
 //map<int,int> mp[m+1];
 set<int> mp[m+1];
 vector<int> size(m+1);
 root.resize(m+1);

 for(int i=1;i<=m;i++)
 root[i]=i;

 //vector<int> t(n);
 int cnt=0;
 for(int i=1;i<=n;i++){
     cin>>t;
     mp[t].insert(i);
     size[t]++;
     if(mp[t].count(i-1))
     cnt++;
 }

//  for(int i=1;i<=m;i++){
//     for(auto p:mp[i]){
//         if()
//     }
//  }
cout<<n-1-cnt<<endl;

for(int i=1;i<m;i++){
    cin>>g>>h;
    a=get(g);
    b=get(h);

    if(size[a]<=size[b]){
        swap(a,b);
    }

   // cout<<a<<" "<<b<<" ";

    for(auto p:mp[b]){

        if(mp[a].count(p-1))
        cnt++;
        if(mp[a].count(p+1))
        cnt++;

    }

    for(auto p:mp[b]){
        mp[a].insert(p);
    }

    root[b]=a;
    // for(auto p:mp[a])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    // for(auto p:mp[b])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    cout<<n-1-cnt<<endl;
    size[a]+=size[b];
    mp[b].clear();
}

// for(auto i:size)
// cout<<i;

    return ;
}

int main()
{
    FAST_IO
 int t=1;
//cin>>t;
 while(t--){
 solve();
 }
   return 0;
}


#include<bits/stdc++.h>
#define ll  long long
#define pb push_back
#define  line cout<<endl
#define FAST_IO std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pii pair<int,int>
using namespace std;

// priority_queue<ll, vector<ll>, less<ll>>pq;     // Max Heap
// priority_queue<ll, vector<ll>, greater<ll>>pq;

//FOR FINDING PRIME NO TO A LIMIT IN O(N*LOG(LOG(N))
// const int max_n = 2e5 + 1;

// vector <int> isPrime(max_n,1);

// void sieve(vector <int> &isPrime){
//   isPrime[0] = 0;
//   isPrime[1] = 0;
//   for(ll i = 2;i < max_n;i++){
//     if(isPrime[i])
//       for(ll j = i*i;j < max_n;j+=i){
//         isPrime[j] = 0;
//       }
//   }
// }

void solve()
{
 int n,m,t,a,b,g,h;
 cin>>n>>m;
 //map<int,int> mp[m+1];
 set<int> mp[m+1];
 vector<int> size(m+1);

//  for(int i=1;i<=m;i++)
//  root[i]=i;

 //vector<int> t(n);
 int cnt=0;
 for(int i=1;i<=n;i++){
     cin>>t;
     mp[t].insert(i);
     size[t]++;
     if(mp[t].count(i-1))
     cnt++;
 }

//  for(int i=1;i<=m;i++){
//     for(auto p:mp[i]){
//         if()
//     }
//  }
cout<<n-1-cnt<<endl;
for(int i=1;i<m;i++){
    cin>>g>>h;
    if(size[g]<=size[h]){
        b=g;
        a=h;
    }
    else
    {
        b=h;
        a=g;
    }
   // cout<<a<<" "<<b<<" ";

    for(auto p:mp[b]){

        if(mp[a].count(p-1))
        cnt++;
        if(mp[a].count(p+1))
        cnt++;

    }
    for(auto p:mp[h]){

        mp[g].insert(p);
    }
    // for(auto p:mp[a])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    // for(auto p:mp[b])
    // cout<<p.first<<" "<<p.second<<endl;
    // line;
    cout<<n-1-cnt<<endl;
    size[g]+=size[h];
}

// for(auto i:size)
// cout<<i;

    return ;
}

int main()
{
    FAST_IO
 int t=1;
//cin>>t;
 while(t--){
 solve();
 }
   return 0;
}


#include<bits/stdc++.h>
#define ll  long long
#define pb push_back
#define  line cout<<endl
#define FAST_IO std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pii pair<int,int>
using namespace std;

// priority_queue<ll, vector<ll>, less<ll>>pq;     // Max Heap
// priority_queue<ll, vector<ll>, greater<ll>>pq;

//FOR FINDING PRIME NO TO A LIMIT IN O(N*LOG(LOG(N))
// const int max_n = 2e5 + 1;

// vector <int> isPrime(max_n,1);

// void sieve(vector <int> &isPrime){
//   isPrime[0] = 0;
//   isPrime[1] = 0;
//   for(ll i = 2;i < max_n;i++){
//     if(isPrime[i])
//       for(ll j = i*i;j < max_n;j+=i){
//         isPrime[j] = 0;
//       }
//   }
// }

void solve()
{
 int n,m,t,a,b,g,h;
 cin>>n>>m;
 //map<int,int> mp[m+1];
 set<int> mp[m+1];
 vector<int> size(m+1);

 int cnt=0;
 for(int i=1;i<=n;i++){
     cin>>t;
     mp[t].insert(i);
     size[t]++;
     if(mp[t].count(i-1))
     cnt++;
 }

cout<<n-1-cnt<<endl;
for(int i=1;i<m;i++){
    cin>>g>>h;
    if(size[g]<=size[h]){
        b=g;
        a=h;
    }
    else
    {
        b=h;
        a=g;
    }

    for(auto p:mp[b]){

        if(mp[a].count(p-1))
        cnt++;
        if(mp[a].count(p+1))
        cnt++;

    }
    for(auto p:mp[h]){

        mp[g].insert(p);
    }

    cout<<n-1-cnt<<endl;
    size[g]+=size[h];
    mp[h].clear();
}

    return ;
}

int main()
{
    FAST_IO
 int t=1;
//cin>>t;
 while(t--){
 solve();
 }
   return 0;
}


#include<bits/stdc++.h>
#define rep(i,x,y) for(auto i=(x);i<=(y);++i)
#define dep(i,x,y) for(auto i=(x);i>=(y);--i)
#define fr first
#define sc second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,ll>pil;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
const int N=1e5+10;
const int inf=1e9;
int mo=998244353;
int arr[N],pos[N],cnt[N];
vector<int> vec[N];
int main(){
    //freopen("D:\\in.txt","r",stdin);
    //freopen("D:\\out.txt","w",stdout);
	int n,m,tmp;
	cin>>n>>m;
	rep(i,1,n) {
		cin>>arr[i];
		vec[arr[i]].push_back(i);
	}
	rep(i,1,m) pos[i]=i;
	int ans=-1;
	int a,b;
	rep(i,1,m){
		rep(j,1,vec[i].size()){
			if(j==1||vec[i][j-1]!=vec[i][j-2]+1){
				ans++;
				cnt[i]++;
			}
		}
	}
	cout<<ans<<endl;
	rep(i,1,m-1){
		cin>>a>>b;
		int pa=pos[a],pb=pos[b];
		if(vec[pa].size()<vec[pb].size()){
			swap(pos[a],pos[b]);
			swap(pa,pb);
		}
		rep(j,1,vec[pb].size()){
			int cur=vec[pb][j-1];
			vec[pa].push_back(cur);
			ans++; cnt[pa]++;
			if(cur>1&&arr[cur-1]==pa) {
				ans--; cnt[pa]--;
			}
			if(cur<n&&arr[cur+1]==pa) {
				ans--; cnt[pa]--;
			}
			arr[cur]=pa;
		}
		ans-=cnt[pb];
		vec[pb].clear();
		cout<<ans<<endl;
	}

    return 0;
}


#include<bits/stdc++.h>
#define rep(i,x,y) for(auto i=(x);i<=(y);++i)
#define dep(i,x,y) for(auto i=(x);i>=(y);--i)
#define fr first
#define sc second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,ll>pil;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
const int N=2e5+10;
const int inf=1e9;
int mo=998244353;
int arr[N],pos[N],cnt[N];
vector<int> vec[N];
int main(){
    //freopen("D:\\in.txt","r",stdin);
    //freopen("D:\\out.txt","w",stdout);
	int n,m,tmp;
	cin>>n>>m;
	rep(i,1,n) {
		cin>>arr[i];
		vec[arr[i]].push_back(i);
	}
	rep(i,1,m) pos[i]=i;
	int ans=-1;
	int a,b;
	rep(i,1,m){
		rep(j,1,vec[i].size()){
			if(j==1||vec[i][j-1]!=vec[i][j-2]+1){
				ans++;
				cnt[i]++;
			}
		}
	}
	cout<<ans<<endl;
	rep(i,1,m-1){
		cin>>a>>b;
		int pa=pos[a],pb=pos[b];
		if(vec[pa].size()<vec[pb].size()){
			swap(pos[a],pos[b]);
			swap(pa,pb);
		}
		rep(j,1,vec[pb].size()){
			int cur=vec[pb][j-1];
			vec[pa].push_back(cur);
			ans++; cnt[pa]++;
			if(cur>1&&arr[cur-1]==pa) {
				ans--; cnt[pa]--;
			}
			if(cur<n&&arr[cur+1]==pa) {
				ans--; cnt[pa]--;
			}
			arr[cur]=pa;
		}
		ans-=cnt[pb];
		vec[pb].clear();
		cout<<ans<<endl;
	}

    return 0;
}


#include<bits/stdc++.h>
#define rep(i,x,y) for(auto i=(x);i<=(y);++i)
#define dep(i,x,y) for(auto i=(x);i>=(y);--i)
#define fr first
#define sc second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,ll>pil;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
const int N=4e5+10;
const int inf=1e9;
const int mo=998244353;
int fa[N][22]={0},depth[N]={0};
int lg2[N]={0};
struct Edge{
	int to,nex;
}e[2*N];
int head[N],tot=0;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nex=head[x];
	head[x]=tot;
}
void initlg2(){
	rep(i,1,N-1)
		lg2[i]=lg2[i-1]+(1<<lg2[i-1]==i);
}
void dfs(int cur,int fath){
	depth[cur]=depth[fath]+1;
	fa[cur][0]=fath;
	rep(i,1,lg2[depth[cur]]){
		fa[cur][i]=fa[fa[cur][i-1]][i-1];
	}
	for(int i=head[cur];i;i=e[i].nex)
		if(e[i].to!=fath) dfs(e[i].to,cur);
}
int LCA(int a,int b){
	if(depth[a]<depth[b]) swap(a,b);
	while(depth[a]>depth[b])
		a=fa[a][lg2[depth[a]-depth[b]]-1];
	if(a==b) return a;
	dep(i,lg2[depth[a]],0){
		if(fa[a][i]!=fa[b][i])
			a=fa[a][i],b=fa[b][i];
	}
	return fa[a][0];
}
int anc[N],b[N];
int main(){
    //freopen("D:\\in.txt","r",stdin);
    //freopen("D:\\out.txt","w",stdout);
	initlg2();
	rep(i,1,N) anc[i]=i;
	int n,m,x,y; cin>>n>>m;
	rep(i,1,n) cin>>b[i];
	rep(i,m+1,m*2-1){
		cin>>x>>y;
		add(i,anc[x]); add(i,anc[y]);
		anc[x]=i;
	}
	dfs(m*2-1,0);
	int pfix[N]={0};
	rep(i,2,n){
		pfix[LCA(b[i],b[i-1])]++;
	}
	rep(i,1,2*m) pfix[i]+=pfix[i-1];
	rep(i,m,2*m-1){
		cout<<n-1-pfix[i]<<endl;
	}
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 200043;
const int L = 20;

vector<int> g[2 * N];
int p[2 * N];
int up[2 * N][L];
int idx[N];
int psum[N];
int cur[N];
int tin[2 * N];
int tout[2 * N];
int T = 0;

void dfs(int x, int y)
{
	tin[x] = T++;
	p[x] = y;
	up[x][0] = y;
	for(int i = 1; i < L; i++)
		up[x][i] = up[up[x][i - 1]][i - 1];
	for(auto z : g[x])
		dfs(z, x);
	tout[x] = T++;
}

bool is_ancestor(int x, int y)
{
	return tin[x] <= tin[y] && tout[x] >= tout[y];
}

int lca(int x, int y)
{
	if(is_ancestor(x, y))
		return x;
	for(int i = L - 1; i >= 0; i--)
		if(!is_ancestor(up[x][i], y))
			x = up[x][i];
	return p[x];
}

int main()
{
	int n, m;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &idx[i]);
		idx[i]--;
	}
	for(int i = 0; i < m; i++)
		cur[i] = i;
	for(int i = 0; i < m - 1; i++)
	{
		int x, y;
		scanf("%d %d", &x, &y);
		--x;
		--y;
		int nidx = m + i;
		g[nidx].push_back(cur[x]);
		g[nidx].push_back(cur[y]);
		cur[x] = nidx;
	}
	int root = m * 2 - 2;
	dfs(root, root);
	for(int i = 0; i < n - 1; i++)
	{
		int t = lca(idx[i], idx[i + 1]);
		if(t < m)
			psum[0]++;
		else
			psum[t - m + 1]++;
	}
	for(int i = 0; i < m - 1; i++)
		psum[i + 1] += psum[i];
	for(int i = 0; i < m; i++)
		printf("%d\n", n - 1 - psum[i]);
}


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <math.h>
#include <array>
#include <functional>
#include <numeric>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef long double ld;

#define LL_MAX 9223372036854775807
#define LL_MIN -9223372036854775806
#define read(to, thresh) for(int i=0; i < thresh; ++i) cin >> to[i];

template<class T>
void smin(T &a, T b) {a = min(a, b);}
template<class T>
void smax(T &a, T b) {a = max(a, b);}
template<class T>
T min(vector<T> &a) {return *min_element(a.begin(), a.end());}
template<class T>
T max(vector<T> &a) {return *max_element(a.begin(), a.end());}
template<class T>
void print(vector<T> &a, string sep) {for(T el: a) cout << el << sep; cout << endl;}

// pair<int, int> surrounding(set<int>::iterator it, set<int> s) {
//     pair<int, int> p;
//     if(it == s.begin()) {
//         cout << *it << endl;
//         p.first = -1;
//     }
//     else {
//         --it;
//         p.first = *it;
//         ++it;
//     }

//     it++;
//     if(it == s.end()) {
//         p.second = -1;
//     }
//     else {
//         p.second = *it;
//     }
//     return p;
// }

void solve() {
	int n, m; cin >> n >> m;
    vector<set<int>> t(m, set<int>());
    for(int i=1; i <= n; i++) {
        int x; cin >> x;
        t[x-1].insert(i);
    }
    int difficulty = 0;
    for(auto el: t) {
        int prev = -1;
        for(auto it = el.begin(); it != el.end(); it++) {
            if(prev != -1) {
                if(*it > prev + 1) {
                    difficulty++;
                }
            }
            prev = *it;
        }
        auto it = el.end();
        it--;
        if(*it != n) difficulty++;
    }

    cout << difficulty << endl;

    for(int k=1; k < m; k++) {
        int a, b; cin >> a >> b;
        a--; b--;
        int l = t[a].size() <= t[b].size() ? a : b;
        int r = (a+b) - l;

        for(auto it = t[l].begin(); it != t[l].end(); it++) {
            t[r].insert(*it);
            pair<int, int> nums;
            if(it == t[l].begin()) {
                nums.first = -1;
            }
            else {
                --it;
                nums.first = *it;
                ++it;
            }

            it++;
            if(it == t[l].end()) {
                nums.second = -1;
            }
            else {
                nums.second = *it;
            }
            it--;

            if(
                nums.first != -1 && nums.second != -1
                && nums.first + 1 == *it
                && nums.second - 1 == *it
            ) {
                continue;
            }

            // we should consider it
            if(nums.first == -1) {
                auto itr = t[r].find(*it);
                if(itr != t[r].begin()){
                    itr--;
                    if(*itr == *it - 1) {
                        difficulty--;
                    }
                }
                itr++;
                if(nums.second == -1) {
                    itr++;
                    if(itr != t[r].end() && *itr == *it + 1) {
                        difficulty--;
                    }
                    itr--;
                }
            }
            else if(nums.second == -1) {
                auto itr = t[r].find(*it);
                itr++;
                if(itr != t[r].end() && *itr == *it + 1) {
                    difficulty--;
                }
                else if(itr == t[r].end()) {
                    difficulty--;
                }
                itr--; itr--;
                if(*itr + 1 == *it && *itr != nums.first) {
                    difficulty--;
                }
                itr++;
            }
            else {
                auto itr = t[r].find(*it);
                itr--;
                int prevnum = *itr;
                itr++; itr++;
                int nextnum = *itr;
                itr--;
                if(prevnum + 1 == *it && prevnum != nums.first) difficulty--;
                if(nextnum - 1 == *it) difficulty--;
                if(prevnum + 1 == *it && *it == nextnum - 1 && prevnum != nums.first) {
                    difficulty--;
                }
            }
        }

        if(a != r) swap(t[a], t[r]);

        cout << difficulty << endl;
    }

}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    // int t; cin >> t;

    // while(t--) {
        solve();
    // }
}


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <math.h>
#include <array>
#include <functional>
#include <numeric>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef long double ld;

#define LL_MAX 9223372036854775807
#define LL_MIN -9223372036854775806
#define read(to, thresh) for(int i=0; i < thresh; ++i) cin >> to[i];

template<class T>
void smin(T &a, T b) {a = min(a, b);}
template<class T>
void smax(T &a, T b) {a = max(a, b);}
template<class T>
T min(vector<T> &a) {return *min_element(a.begin(), a.end());}
template<class T>
T max(vector<T> &a) {return *max_element(a.begin(), a.end());}
template<class T>
void print(vector<T> &a, string sep) {for(T el: a) cout << el << sep; cout << endl;}

// pair<int, int> surrounding(set<int>::iterator it, set<int> s) {
//     pair<int, int> p;
//     if(it == s.begin()) {
//         cout << *it << endl;
//         p.first = -1;
//     }
//     else {
//         --it;
//         p.first = *it;
//         ++it;
//     }

//     it++;
//     if(it == s.end()) {
//         p.second = -1;
//     }
//     else {
//         p.second = *it;
//     }
//     return p;
// }

void solve() {
	int n, m; cin >> n >> m;
    vector<set<int>> t(m, set<int>());
    for(int i=1; i <= n; i++) {
        int x; cin >> x;
        t[x-1].insert(i);
    }
    int difficulty = 0;
    for(auto el: t) {
        int prev = -1;
        for(auto it = el.begin(); it != el.end(); it++) {
            if(prev != -1) {
                if(*it > prev + 1) {
                    difficulty++;
                }
            }
            prev = *it;
        }
        auto it = el.end();
        it--;
        if(*it != n) difficulty++;
    }

    cout << difficulty << endl;

    for(int k=1; k < m; k++) {
        int a, b; cin >> a >> b;
        a--; b--;
        int l = t[a].size() <= t[b].size() ? a : b;
        int r = (a+b) - l;

        for(auto it = t[l].begin(); it != t[l].end(); it++) {
            t[r].insert(*it);
            pair<int, int> nums;
            if(it == t[l].begin()) {
                nums.first = -1;
            }
            else {
                --it;
                nums.first = *it;
                ++it;
            }

            it++;
            if(it == t[l].end()) {
                nums.second = -1;
            }
            else {
                nums.second = *it;
            }
            it--;

            if(
                nums.first != -1 && nums.second != -1
                && nums.first + 1 == *it
                && nums.second - 1 == *it
            ) {
                continue;
            }

            // we should consider it
            if(nums.first == -1) {
                auto itr = t[r].find(*it);
                if(itr != t[r].begin()){
                    itr--;
                    if(*itr == *it - 1) {
                        difficulty--;
                    }
                    itr++;
                }
                if(nums.second == -1) {
                    // cout << "DEBUG " << *it << endl;
                    itr++;
                    if(itr != t[r].end() && *itr == *it + 1) {
                        difficulty--;
                    }
                    itr--;
                }
            }
            else if(nums.second == -1) {
                auto itr = t[r].find(*it);
                itr++;
                if(itr != t[r].end() && *itr == *it + 1) {
                    difficulty--;
                }
                else if(itr == t[r].end()) {
                    difficulty--;
                }
                itr--; itr--;
                if(*itr + 1 == *it && *itr != nums.first) {
                    difficulty--;
                }
                itr++;
            }
            else {
                auto itr = t[r].find(*it);
                itr--;
                int prevnum = *itr;
                itr++; itr++;
                int nextnum = *itr;
                itr--;
                if(prevnum + 1 == *it && prevnum != nums.first) difficulty--;
                if(nextnum - 1 == *it) difficulty--;
                if(prevnum + 1 == *it && *it == nextnum - 1 && prevnum != nums.first) {
                    difficulty--;
                }
            }
        }

        if(a != r) swap(t[a], t[r]);

        cout << difficulty << endl;
    }

}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    // int t; cin >> t;

    // while(t--) {
        solve();
    // }
}