#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include<bits/stdc++.h>
#include<x86intrin.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I __attribute__((always_inline))inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
#define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define UC unsigned char
#define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=200007,Br=112,B=Br+3,BC=N/Br+7;

std::set<int>p[N];
int n,m,blo,bc,s[N],su[N],lst[N],cnt[N];

int gmax[BC];

struct cv_t
{
	int maxv,tcnt,ans;
}cv[BC][B];

//final max is known -> gmax
//each (t,tcnt) before
//1. should tcnt be count -> if yes, max(??, tcnt)
//2. final tcnt
//3. ans in middle

const int B8=(B+7)/8+1,BU=B8*8;
//int maxv[B],tcnt[B],ans[B];
//__m256i _maxv[B8],_tcnt[B8],_ans[B8];
//int*maxv=(int*)_maxv,*tcnt=(int*)_tcnt,*ans=(int*)_ans;
__attribute__((__aligned__(32))) int maxv[BU],tcnt[BU],ans[BU];
__m256i*_maxv=(__m256i*)maxv,*_tcnt=(__m256i*)tcnt,*_ans=(__m256i*)ans;

//int UFLAG;

void build(int x)
{
	//assert(reinterpret_cast<ull>(ans)%32==0);
	//out,"build:",x,'\n';
	int l=x*blo-blo+1,r=min(n,x*blo);
	int tmax=l-1,lsumd=l-1;
	fo(i,0,r+1-l)tcnt[i]=ans[i]=0,maxv[i]=-1;
	int le8=(r+2-l+7)/8;
	//assert((r+1-l+7)/8<le8);
	//assert(le8<=B8);
	fo(i,l,r)
	{
		if(!su[i])continue;
		//out,"process:",i,'\n';
		repr(tmax,lst[su[i]]);
		int C=cnt[su[i]];
		//out,C,'\n';
		__m256i cnt8=_mm256_set_epi32(C,C,C,C,C,C,C,C);
		//fo(j,l,r+1)repr(tcnt[j-l],cnt[su[i]]);
		//fo(j,l,r+1)repr(tcnt[j-l],C);
		//int tcnt2[B];
		//fo0(j,r+2-l)tcnt2[j]=max(tcnt[j],C);
		//fo0(j,r+2-l)repr(tcnt[j],C);
		fo0(j,le8)_tcnt[j]=_mm256_max_epi32(_tcnt[j],cnt8);
		//out,'/',le8,'\n';
		//fo0(j,r+2-l)assert(tcnt2[j]==tcnt[j]);
		//if(x==1){fo0(j,r+1-l)out,tcnt[j],' ';out,'\n';}
		if(tmax==i)
		{
			int L,R;

			//L=0,R=lsumd-l+1;
			//while(R&7)R--,ans[R]+=tcnt[R];
			//if(R)fo0(j,R>>3)_ans[j]=_mm256_add_epi32(_ans[j],_tcnt[j]);
			fo(j,l,lsumd)ans[j-l]+=tcnt[j-l];
			//while(R--)ans[R]+=tcnt[R];

			L=lsumd-l+1,R=i-l+1;
			while(L&7)maxv[L]=tcnt[L],L++;
			while(R&7)R--,maxv[L]=tcnt[R];
			fo(j,L>>3,(R>>3)-1)_maxv[j]=_tcnt[j];
			//fo(j,lsumd+1,i)maxv[j-l]=tcnt[j-l];

			L=0,R=i-l+1;
			while(R&7)R--,tcnt[R]=0;
			fo0(j,R>>3)_tcnt[j]=_mm256_setzero_si256();
			//fo(j,l,i)tcnt[j-l]=0;

			/*fo(j,l,lsumd)
			{
				ans[j-l]+=tcnt[j-l];
				tcnt[j-l]=0;
			}
			fo(j,lsumd+1,i)
			{
				maxv[j-l]=tcnt[j-l];
				tcnt[j-l]=0;
			}*/
			lsumd=i;
		}
		//UFLAG++;
		//fo(j,0,r+1-l)out,maxv[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,ans[j],' ';out,'\n';
	}
	//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
	//out,1,'\n';
	fo(i,0,r+1-l)
	{
		cv[x][i]=(cv_t){maxv[i],tcnt[i],ans[i]};
		//out,maxv[i],' ',tcnt[i],' ',ans[i],'\n';
	}
	gmax[x]=tmax;
}

inline int get_ans()
{
	int t=0,tcnt=0,ans=0;
	fo1(i,bc)
	{
		int l=i*blo-blo+1,r=min(n,i*blo);
		if(t>r)
		{
			repr(t,gmax[i]);
			repr(tcnt,cv[i][r+1-l].tcnt);
			//out,"/a ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		repr(t,l);
		if(cv[i][t-l].maxv==-1)
		{
			repr(tcnt,cv[i][t-l].tcnt);
			repr(t,gmax[i]);
			//out,'@',i,' ',t-l,' ',cv[i][t-l].tcnt,'\n';
			//out,"/b ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		//out,'@',t-l,'\n';
		ans+=max(cv[i][t-l].maxv,tcnt);
		ans+=cv[i][t-l].ans;
		tcnt=cv[i][t-l].tcnt;
		repr(t,gmax[i]);
		//out,"/c ",i,' ',t,' ',tcnt,' ',ans,'\n';
	}
	return ans;
}

inline int geb(int x)
{
	return (x-1)/blo+1;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	in,n,m;
	//blo=sqrt(n);
	//blo=pow((lf)n,1./3);
	blo=Br;
	bc=(n+blo-1)/blo;
	//out,'/',blo,' ',bc,'\n';
	//blo=2;
	repr(blo,1),repl(blo,n);
	fo1(i,n)in,s[i];
	fo1(i,n)
	{
		if(!lst[s[i]])su[i]=s[i];
		lst[s[i]]=i,cnt[s[i]]++;
		p[s[i]].insert(i);
	}
	fo0(i,N)if(lst[i])su[lst[i]]=i;
	fo1(i,bc)build(i);
	//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
	//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
	//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
	out,n-get_ans(),'\n';
	fo0(i,m)
	{
		int x,y;
		in,x,y;
		//out,'@',x,' ',y,'\n';
		std::set<int>reb;
		if(s[x]!=y)
		{
			int a=s[x],xl=*p[a].begin(),xr=*p[a].rbegin();
			cnt[a]--;
			p[a].erase(x);
			if(!p[a].size())
			{
				reb.insert(geb(xl));
				su[xl]=0;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				if(nxl!=xl)reb.insert(geb(xl)),su[xl]=0,su[nxl]=a;
				if(nxr!=xr)reb.insert(geb(xr)),su[xr]=0,su[nxr]=a;
				lst[a]=nxr;
				reb.insert(geb(nxl)),reb.insert(geb(nxr));
			}
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			//out,'@',x,' ',y,'\n';
			a=s[x]=y;
			cnt[a]++;
			if(!p[a].size())
			{
				p[a].insert(x);
				reb.insert(geb(x));
				su[x]=a;
				lst[a]=x;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				p[a].insert(x);
				int xl=*p[a].begin(),xr=*p[a].rbegin();
				//out,"====",xl,' ',xr,' ',nxl,' ',nxr,'\n';
				if(nxl!=xl)reb.insert(geb(nxl)),su[xl]=a,nxl==nxr?0:su[nxl]=0;
				if(nxr!=xr)reb.insert(geb(nxr)),su[xr]=a,nxl==nxr?0:su[nxr]=0;
				lst[a]=xr;
				reb.insert(geb(xl)),reb.insert(geb(xr));
			}
			//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
			//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
			//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			foe(j,reb)build(*j);
		}
		out,n-get_ans(),'\n';
	}
	//while(1);
}


#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include<bits/stdc++.h>
#include<x86intrin.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I __attribute__((always_inline))inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
#define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define UC unsigned char
#define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=200007,Br=112,B=Br+3,BC=N/Br+7;

std::set<int>p[N];
int n,m,blo,bc,s[N],su[N],lst[N],cnt[N];

int gmax[BC];

struct cv_t
{
	int maxv,tcnt,ans;
}cv[BC][B];

//final max is known -> gmax
//each (t,tcnt) before
//1. should tcnt be count -> if yes, max(??, tcnt)
//2. final tcnt
//3. ans in middle

const int B8=(B+7)/8+1,BU=B8*8;
//int maxv[B],tcnt[B],ans[B];
//__m256i _maxv[B8],_tcnt[B8],_ans[B8];
//int*maxv=(int*)_maxv,*tcnt=(int*)_tcnt,*ans=(int*)_ans;
__attribute__((__aligned__(32))) int maxv[BU],tcnt[BU],ans[BU];
//__m256i*_maxv=(__m256i*)maxv,*_tcnt=(__m256i*)tcnt,*_ans=(__m256i*)ans;

//int UFLAG;

void build(int x)
{
	//assert(reinterpret_cast<ull>(ans)%32==0);
	//out,"build:",x,'\n';
	int l=x*blo-blo+1,r=min(n,x*blo);
	int tmax=l-1,lsumd=l-1;
	fo(i,0,r+1-l)tcnt[i]=ans[i]=0,maxv[i]=-1;
	int le8=(r+2-l+7)/8;
	//assert((r+1-l+7)/8<le8);
	//assert(le8<=B8);
	fo(i,l,r)
	{
		if(!su[i])continue;
		//out,"process:",i,'\n';
		repr(tmax,lst[su[i]]);
		int C=cnt[su[i]];
		//out,C,'\n';
		//__m256i cnt8=_mm256_set_epi32(C,C,C,C,C,C,C,C);
		//fo(j,l,r+1)repr(tcnt[j-l],cnt[su[i]]);
		//fo(j,l,r+1)repr(tcnt[j-l],C);
		//int tcnt2[B];
		//fo0(j,r+2-l)tcnt2[j]=max(tcnt[j],C);
		fo0(j,r+2-l)repr(tcnt[j],C);
		//fo0(j,le8)_tcnt[j]=_mm256_max_epi32(_tcnt[j],cnt8);
		//out,'/',le8,'\n';
		//fo0(j,r+2-l)assert(tcnt2[j]==tcnt[j]);
		//if(x==1){fo0(j,r+1-l)out,tcnt[j],' ';out,'\n';}
		if(tmax==i)
		{
			int L,R;

			//L=0,R=lsumd-l+1;
			//while(R&7)R--,ans[R]+=tcnt[R];
			//if(R)fo0(j,R>>3)_ans[j]=_mm256_add_epi32(_ans[j],_tcnt[j]);
			fo(j,l,lsumd)ans[j-l]+=tcnt[j-l];
			//while(R--)ans[R]+=tcnt[R];

			//L=lsumd-l+1,R=i-l+1;
			//while(L&7)maxv[L]=tcnt[L],L++;
			//while(R&7)R--,maxv[L]=tcnt[R];
			//fo(j,L>>3,(R>>3)-1)_maxv[j]=_tcnt[j];
			fo(j,lsumd+1,i)maxv[j-l]=tcnt[j-l];

			//L=0,R=i-l+1;
			//while(R&7)R--,tcnt[R]=0;
			//fo0(j,R>>3)_tcnt[j]=_mm256_setzero_si256();
			fo(j,l,i)tcnt[j-l]=0;

			/*fo(j,l,lsumd)
			{
				ans[j-l]+=tcnt[j-l];
				tcnt[j-l]=0;
			}
			fo(j,lsumd+1,i)
			{
				maxv[j-l]=tcnt[j-l];
				tcnt[j-l]=0;
			}*/
			lsumd=i;
		}
		//UFLAG++;
		//fo(j,0,r+1-l)out,maxv[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,ans[j],' ';out,'\n';
	}
	//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
	//out,1,'\n';
	fo(i,0,r+1-l)
	{
		cv[x][i]=(cv_t){maxv[i],tcnt[i],ans[i]};
		//out,maxv[i],' ',tcnt[i],' ',ans[i],'\n';
	}
	gmax[x]=tmax;
}

inline int get_ans()
{
	int t=0,tcnt=0,ans=0;
	fo1(i,bc)
	{
		int l=i*blo-blo+1,r=min(n,i*blo);
		if(t>r)
		{
			repr(t,gmax[i]);
			repr(tcnt,cv[i][r+1-l].tcnt);
			//out,"/a ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		repr(t,l);
		if(cv[i][t-l].maxv==-1)
		{
			repr(tcnt,cv[i][t-l].tcnt);
			repr(t,gmax[i]);
			//out,'@',i,' ',t-l,' ',cv[i][t-l].tcnt,'\n';
			//out,"/b ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		//out,'@',t-l,'\n';
		ans+=max(cv[i][t-l].maxv,tcnt);
		ans+=cv[i][t-l].ans;
		tcnt=cv[i][t-l].tcnt;
		repr(t,gmax[i]);
		//out,"/c ",i,' ',t,' ',tcnt,' ',ans,'\n';
	}
	return ans;
}

inline int geb(int x)
{
	return (x-1)/blo+1;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	in,n,m;
	//blo=sqrt(n);
	//blo=pow((lf)n,1./3);
	blo=Br;
	bc=(n+blo-1)/blo;
	//out,'/',blo,' ',bc,'\n';
	//blo=2;
	repr(blo,1),repl(blo,n);
	fo1(i,n)in,s[i];
	fo1(i,n)
	{
		if(!lst[s[i]])su[i]=s[i];
		lst[s[i]]=i,cnt[s[i]]++;
		p[s[i]].insert(i);
	}
	fo0(i,N)if(lst[i])su[lst[i]]=i;
	fo1(i,bc)build(i);
	//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
	//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
	//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
	out,n-get_ans(),'\n';
	fo0(i,m)
	{
		int x,y;
		in,x,y;
		//out,'@',x,' ',y,'\n';
		std::set<int>reb;
		if(s[x]!=y)
		{
			int a=s[x],xl=*p[a].begin(),xr=*p[a].rbegin();
			cnt[a]--;
			p[a].erase(x);
			if(!p[a].size())
			{
				reb.insert(geb(xl));
				su[xl]=0;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				if(nxl!=xl)reb.insert(geb(xl)),su[xl]=0,su[nxl]=a;
				if(nxr!=xr)reb.insert(geb(xr)),su[xr]=0,su[nxr]=a;
				lst[a]=nxr;
				reb.insert(geb(nxl)),reb.insert(geb(nxr));
			}
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			//out,'@',x,' ',y,'\n';
			a=s[x]=y;
			cnt[a]++;
			if(!p[a].size())
			{
				p[a].insert(x);
				reb.insert(geb(x));
				su[x]=a;
				lst[a]=x;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				p[a].insert(x);
				int xl=*p[a].begin(),xr=*p[a].rbegin();
				//out,"====",xl,' ',xr,' ',nxl,' ',nxr,'\n';
				if(nxl!=xl)reb.insert(geb(nxl)),su[xl]=a,nxl==nxr?0:su[nxl]=0;
				if(nxr!=xr)reb.insert(geb(nxr)),su[xr]=a,nxl==nxr?0:su[nxr]=0;
				lst[a]=xr;
				reb.insert(geb(xl)),reb.insert(geb(xr));
			}
			//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
			//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
			//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			foe(j,reb)build(*j);
		}
		out,n-get_ans(),'\n';
	}
	//while(1);
}


#define __AVX__ 1
#define __AVX2__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include<bits/stdc++.h>
#include<x86intrin.h>

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef double lf;
typedef long double llf;
typedef std::pair<int,int> pii;

#define xx first
#define yy second

template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline bool repr(T &a,T b){return a<b?a=b,1:0;}
template<typename T> inline bool repl(T &a,T b){return a>b?a=b,1:0;}
template<typename T> inline T gcd(T a,T b){T t;if(a<b){while(a){t=a;a=b%a;b=t;}return b;}else{while(b){t=b;b=a%b;a=t;}return a;}}
template<typename T> inline T sqr(T x){return x*x;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
#define I __attribute__((always_inline))inline
#define mset(a,b) memset(a,b,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

#define fo0(i,n) for(int i=0,i##end=n;i<i##end;i++)
#define fo1(i,n) for(int i=1,i##end=n;i<=i##end;i++)
#define fo(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define fd0(i,n) for(int i=(n)-1;~i;i--)
#define fd1(i,n) for(int i=n;i;i--)
#define fd(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define foe(i,x)for(__typeof((x).end())i=(x).begin();i!=(x).end();++i)
#define fre(i,x)for(__typeof((x).rend())i=(x).rbegin();i!=(x).rend();++i)

struct Cg{I char operator()(){return getchar();}};
struct Cp{I void operator()(char x){putchar(x);}};
#define OP operator
#define RT return *this;
#define UC unsigned char
#define RX x=0;UC t=P();while((t<'0'||t>'9')&&t!='-')t=P();bool f=0;\
if(t=='-')t=P(),f=1;x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define RL if(t=='.'){lf u=0.1;for(t=P();t>='0'&&t<='9';t=P(),u*=0.1)x+=u*(t-'0');}if(f)x=-x
#define RU x=0;UC t=P();while(t<'0'||t>'9')t=P();x=t-'0';for(t=P();t>='0'&&t<='9';t=P())x=x*10+t-'0'
#define TR *this,x;return x;
I bool IS(char x){return x==10||x==13||x==' ';}template<typename T>struct Fr{T P;I Fr&OP,(int&x)
{RX;if(f)x=-x;RT}I OP int(){int x;TR}I Fr&OP,(ll &x){RX;if(f)x=-x;RT}I OP ll(){ll x;TR}I Fr&OP,(char&x)
{for(x=P();IS(x);x=P());RT}I OP char(){char x;TR}I Fr&OP,(char*x){char t=P();for(;IS(t);t=P());if(~t){for(;!IS
(t)&&~t;t=P())*x++=t;}*x++=0;RT}I Fr&OP,(lf&x){RX;RL;RT}I OP lf(){lf x;TR}I Fr&OP,(llf&x){RX;RL;RT}I OP llf()
{llf x;TR}I Fr&OP,(uint&x){RU;RT}I OP uint(){uint x;TR}I Fr&OP,(ull&x){RU;RT}I OP ull(){ull x;TR}};Fr<Cg>in;
#define WI(S) if(x){if(x<0)P('-'),x=-x;UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
#define WL if(y){lf t=0.5;for(int i=y;i--;)t*=0.1;if(x>=0)x+=t;else x-=t,P('-');*this,(ll)(abs(x));P('.');if(x<0)\
x=-x;while(y--){x*=10;x-=floor(x*0.1)*10;P(((int)x)%10+'0');}}else if(x>=0)*this,(ll)(x+0.5);else *this,(ll)(x-0.5);
#define WU(S) if(x){UC s[S],c=0;while(x)s[c++]=x%10+'0',x/=10;while(c--)P(s[c]);}else P('0')
template<typename T>struct Fw{T P;I Fw&OP,(int x){WI(10);RT}I Fw&OP()(int x){WI(10);RT}I Fw&OP,(uint x){WU(10);RT}
I Fw&OP()(uint x){WU(10);RT}I Fw&OP,(ll x){WI(19);RT}I Fw&OP()(ll x){WI(19);RT}I Fw&OP,(ull x){WU(20);RT}I Fw&OP()
(ull x){WU(20);RT}I Fw&OP,(char x){P(x);RT}I Fw&OP()(char x){P(x);RT}I Fw&OP,(const char*x){while(*x)P(*x++);RT}
I Fw&OP()(const char*x){while(*x)P(*x++);RT}I Fw&OP()(lf x,int y){WL;RT}I Fw&OP()(llf x,int y){WL;RT}};Fw<Cp>out;

const int N=200007,Br=112,B=Br+3,BC=N/Br+7;

std::set<int>p[N];
int n,m,blo,bc,s[N],su[N],lst[N],cnt[N];

int gmax[BC];

struct cv_t
{
	int maxv,tcnt,ans;
}cv[BC][B];

//final max is known -> gmax
//each (t,tcnt) before
//1. should tcnt be count -> if yes, max(??, tcnt)
//2. final tcnt
//3. ans in middle

const int B8=(B+7)/8+1,BU=B8*8;
//int maxv[B],tcnt[B],ans[B];
//__m256i _maxv[B8],_tcnt[B8],_ans[B8];
//int*maxv=(int*)_maxv,*tcnt=(int*)_tcnt,*ans=(int*)_ans;
__attribute__((__aligned__(32))) int maxv[BU],tcnt[BU],ans[BU];
__m256i*_maxv=(__m256i*)maxv,*_tcnt=(__m256i*)tcnt,*_ans=(__m256i*)ans;

//int UFLAG;

void build(int x)
{
	//assert(reinterpret_cast<ull>(ans)%32==0);
	//out,"build:",x,'\n';
	int l=x*blo-blo+1,r=min(n,x*blo);
	int tmax=l-1,lsumd=l-1;
	fo(i,0,r+1-l)tcnt[i]=ans[i]=0,maxv[i]=-1;
	int le8=(r+2-l+7)/8;
	//assert((r+1-l+7)/8<le8);
	//assert(le8<=B8);
	fo(i,l,r)
	{
		if(!su[i])continue;
		//out,"process:",i,'\n';
		repr(tmax,lst[su[i]]);
		int C=cnt[su[i]];
		//out,C,'\n';
		__m256i cnt8=_mm256_set_epi32(C,C,C,C,C,C,C,C);
		//fo(j,l,r+1)repr(tcnt[j-l],cnt[su[i]]);
		//fo(j,l,r+1)repr(tcnt[j-l],C);
		//int tcnt2[B];
		//fo0(j,r+2-l)tcnt2[j]=max(tcnt[j],C);
		fo0(j,r+2-l)repr(tcnt[j],C);
		//fo0(j,le8)_tcnt[j]=_mm256_max_epi32(_tcnt[j],cnt8);
		//out,'/',le8,'\n';
		//fo0(j,r+2-l)assert(tcnt2[j]==tcnt[j]);
		//if(x==1){fo0(j,r+1-l)out,tcnt[j],' ';out,'\n';}
		if(tmax==i)
		{
			int L,R;

			L=0,R=lsumd-l+1;
			//out,R,'\n';
			while(R&7)R--,ans[R]+=tcnt[R];
			//out,R,'\n';
			if(R)fo0(j,R>>3)_ans[j]=_mm256_add_epi32(_ans[j],_tcnt[j]);
			//fo(j,l,lsumd)ans[j-l]+=tcnt[j-l];
			//while(R--)ans[R]+=tcnt[R];

			L=lsumd-l+1,R=i-l+1;
			while(L&7)maxv[L]=tcnt[L],L++;
			while(R&7)R--,maxv[L]=tcnt[R];
			fo(j,L>>3,(R>>3)-1)_maxv[j]=_tcnt[j];
			//fo(j,lsumd+1,i)maxv[j-l]=tcnt[j-l];

			L=0,R=i-l+1;
			while(R&7)R--,tcnt[R]=0;
			fo0(j,R>>3)_tcnt[j]=_mm256_setzero_si256();
			//fo(j,l,i)tcnt[j-l]=0;

			/*fo(j,l,lsumd)
			{
				ans[j-l]+=tcnt[j-l];
				tcnt[j-l]=0;
			}
			fo(j,lsumd+1,i)
			{
				maxv[j-l]=tcnt[j-l];
				tcnt[j-l]=0;
			}*/
			lsumd=i;
		}
		//UFLAG++;
		//fo(j,0,r+1-l)out,maxv[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
		//fo(j,0,r+1-l)out,ans[j],' ';out,'\n';
	}
	//fo(j,0,r+1-l)out,tcnt[j],' ';out,'\n';
	//out,1,'\n';
	fo(i,0,r+1-l)
	{
		cv[x][i]=(cv_t){maxv[i],tcnt[i],ans[i]};
		//out,maxv[i],' ',tcnt[i],' ',ans[i],'\n';
	}
	gmax[x]=tmax;
}

inline int get_ans()
{
	int t=0,tcnt=0,ans=0;
	fo1(i,bc)
	{
		int l=i*blo-blo+1,r=min(n,i*blo);
		if(t>r)
		{
			repr(t,gmax[i]);
			repr(tcnt,cv[i][r+1-l].tcnt);
			//out,"/a ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		repr(t,l);
		if(cv[i][t-l].maxv==-1)
		{
			repr(tcnt,cv[i][t-l].tcnt);
			repr(t,gmax[i]);
			//out,'@',i,' ',t-l,' ',cv[i][t-l].tcnt,'\n';
			//out,"/b ",i,' ',t,' ',tcnt,' ',ans,'\n';
			continue;
		}
		//out,'@',t-l,'\n';
		ans+=max(cv[i][t-l].maxv,tcnt);
		ans+=cv[i][t-l].ans;
		tcnt=cv[i][t-l].tcnt;
		repr(t,gmax[i]);
		//out,"/c ",i,' ',t,' ',tcnt,' ',ans,'\n';
	}
	return ans;
}

inline int geb(int x)
{
	return (x-1)/blo+1;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	in,n,m;
	//blo=sqrt(n);
	//blo=pow((lf)n,1./3);
	blo=Br;
	bc=(n+blo-1)/blo;
	//out,'/',blo,' ',bc,'\n';
	//blo=2;
	repr(blo,1),repl(blo,n);
	fo1(i,n)in,s[i];
	fo1(i,n)
	{
		if(!lst[s[i]])su[i]=s[i];
		lst[s[i]]=i,cnt[s[i]]++;
		p[s[i]].insert(i);
	}
	fo0(i,N)if(lst[i])su[lst[i]]=i;
	fo1(i,bc)build(i);
	//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
	//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
	//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
	out,n-get_ans(),'\n';
	fo0(i,m)
	{
		int x,y;
		in,x,y;
		//out,'@',x,' ',y,'\n';
		std::set<int>reb;
		if(s[x]!=y)
		{
			int a=s[x],xl=*p[a].begin(),xr=*p[a].rbegin();
			cnt[a]--;
			p[a].erase(x);
			if(!p[a].size())
			{
				reb.insert(geb(xl));
				su[xl]=0;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				if(nxl!=xl)reb.insert(geb(xl)),su[xl]=0,su[nxl]=a;
				if(nxr!=xr)reb.insert(geb(xr)),su[xr]=0,su[nxr]=a;
				lst[a]=nxr;
				reb.insert(geb(nxl)),reb.insert(geb(nxr));
			}
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			//out,'@',x,' ',y,'\n';
			a=s[x]=y;
			cnt[a]++;
			if(!p[a].size())
			{
				p[a].insert(x);
				reb.insert(geb(x));
				su[x]=a;
				lst[a]=x;
			}
			else
			{
				int nxl=*p[a].begin(),nxr=*p[a].rbegin();
				p[a].insert(x);
				int xl=*p[a].begin(),xr=*p[a].rbegin();
				//out,"====",xl,' ',xr,' ',nxl,' ',nxr,'\n';
				if(nxl!=xl)reb.insert(geb(nxl)),su[xl]=a,nxl==nxr?0:su[nxl]=0;
				if(nxr!=xr)reb.insert(geb(nxr)),su[xr]=a,nxl==nxr?0:su[nxr]=0;
				lst[a]=xr;
				reb.insert(geb(xl)),reb.insert(geb(xr));
			}
			//out,"su:";fo1(j,n)out,su[j],' ';out,'\n';
			//out,"lst:";fo1(j,n)out,lst[j],' ';out,'\n';
			//out,"cnt:";fo1(j,n)out,cnt[j],' ';out,'\n';
			//out,"reb:";foe(j,reb)out,*j,' ';out,'\n';
			foe(j,reb)build(*j);
		}
		out,n-get_ans(),'\n';
	}
	//while(1);
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 200010;
const int MX = 1 << 18;

struct NOD {
	int mn, lazy, lmx, rmx, tmx, mxsum;
} seg[2 * MX];

int N;
int A[MAXN];
int cnt[MAXN], cvr[MAXN];
set<int> s[MAXN];

NOD mergenod(NOD &n1, NOD &n2, int l) {
	NOD r;
	r.mn = min(n1.mn, n2.mn) + l;
	r.lazy = l;
	r.lmx = n1.mn <= n2.mn ? n1.lmx : max(n1.tmx, n2.lmx);
	r.rmx = n2.mn <= n1.mn ? n2.rmx : max(n1.rmx, n2.tmx);
	r.tmx = max(n1.tmx, n2.tmx);
	if(n1.mn < n2.mn) r.mxsum = n1.mxsum - n1.rmx + r.rmx;
	else if(n1.mn > n2.mn) r.mxsum = r.lmx + n2.mxsum - n2.lmx;
	else r.mxsum = n1.mxsum - n1.rmx + n2.mxsum - n2.lmx + max(n1.rmx, n2.lmx);
	return r;
}

void updnod(int idx, int l) { seg[idx].lmx = seg[idx].tmx = seg[idx].mxsum = cnt[l]; }

void mkseg(int idx, int l, int r) {
	if(l == r) {
		seg[idx].mn = cvr[l];
		updnod(idx, l);
	}
	else {
		int m = (l + r) / 2;
		mkseg(idx * 2, l, m);
		mkseg(idx * 2 + 1, m + 1, r);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], 0);
	}
}

void updseg(int idx, int l, int r, int x, int y, int z) {
	if(l == r) updnod(idx, l);
	if(x <= l && r <= y) {
		seg[idx].mn += z;
		seg[idx].lazy += z;
	}
	else if(l <= y && x <= r) {
		int m = (l + r) / 2;
		updseg(idx * 2, l, m, x, y, z);
		updseg(idx * 2 + 1, m + 1, r, x, y, z);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], seg[idx].lazy);
	}
}
void updseg(int x, int y, int z) { updseg(1, 0, N - 1, x, y, z); }
void updcnt(int x) { updseg(1, 0, N - 1, x, x, 0); }

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	int Q;

	cin >> N >> Q;
	for(int i = 0; i < N; i++) cin >> A[i];

	for(int i = 0; i < N; i++) {
		if(!s[A[i]].empty()) {
			cvr[*prev(s[A[i]].end())]++;
			cvr[i]--;
		}
		s[A[i]].insert(i);
		cnt[*s[A[i]].begin()]++;
	}
	for(int i = 1; i < N; i++) cvr[i] += cvr[i - 1];
	mkseg(1, 0, N - 1);

	cout << N - seg[1].mxsum << "\n";
	while(Q--) {
		int x, y;
		cin >> x >> y;
		x--;

		s[A[x]].erase(x);
		if(!s[A[x]].empty()) {
			if(x < *s[A[x]].begin()) {
				cnt[*s[A[x]].begin()] = cnt[x] - 1;
				updseg(x, *s[A[x]].begin() - 1, -1);
			}
			else cnt[*s[A[x]].begin()]--;
			updcnt(*s[A[x]].begin());
			if(x > *prev(s[A[x]].end()))
				updseg(*prev(s[A[x]].end()), x - 1, -1);
		}
		A[x] = y;
		if(!s[y].empty()) {
			if(x < *s[y].begin()) {
				cnt[x] = cnt[*s[y].begin()] + 1;
				cnt[*s[y].begin()] = 0;
				updseg(x, *s[y].begin() - 1, 1);
			}
			else {
				cnt[x] = 0;
				cnt[*s[y].begin()]++;
			}
			updcnt(*s[y].begin());
			if(x > *prev(s[y].end()))
				updseg(*prev(s[y].end()), x - 1, 1);
		}
		else cnt[x] = 1;
		updcnt(x);
		s[y].insert(x);

		cout << N - seg[1].mxsum << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 200010;
const int MX = 1 << 18;

struct NOD {
	int mn, lazy, lmx, rmx, tmx, mxsum;
} seg[2 * MX];

int N;
int A[MAXN];
int cnt[MAXN], cvr[MAXN];
set<int> s[MAXN];

void pp(int i) {
	printf("seg[%d] = { mn = %d, lazy = %d, lmx = %d, rmx = %d, tmx = %d, mxsum = %d }\n", i, seg[i].mn, seg[i].lazy, seg[i].lmx, seg[i].rmx, seg[i].tmx, seg[i].mxsum); }

NOD mergenod(NOD &n1, NOD &n2, int l) {
	NOD r;
	r.mn = min(n1.mn, n2.mn) + l;
	r.lazy = l;
	r.lmx = n1.mn <= n2.mn ? n1.lmx : max(n1.tmx, n2.lmx);
	r.rmx = n2.mn <= n1.mn ? n2.rmx : max(n1.rmx, n2.tmx);
	r.tmx = max(n1.tmx, n2.tmx);
	if(n1.mn < n2.mn) r.mxsum = n1.mxsum - n1.rmx + r.rmx;
	else if(n1.mn > n2.mn) r.mxsum = r.lmx + n2.mxsum - n2.lmx;
	else r.mxsum = n1.mxsum - n1.rmx + n2.mxsum - n2.lmx + max(n1.rmx, n2.lmx);
	return r;
}

void updnod(int idx, int l) { seg[idx].lmx = seg[idx].tmx = seg[idx].mxsum = cnt[l]; }

void mkseg(int idx, int l, int r) {
	if(l == r) {
		seg[idx].mn = cvr[l];
		updnod(idx, l);
	}
	else {
		int m = (l + r) / 2;
		mkseg(idx * 2, l, m);
		mkseg(idx * 2 + 1, m + 1, r);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], 0);
	}
	//pp(idx);
}

void updseg(int idx, int l, int r, int x, int y, int z) {
	//if(idx == 1) printf("updseg(x = %d, y = %d, z = %d)\n", x, y, z);
	if(l == r) updnod(idx, l);
	if(x <= l && r <= y) {
		seg[idx].mn += z;
		seg[idx].lazy += z;
	}
	else if(l <= y && x <= r) {
		int m = (l + r) / 2;
		updseg(idx * 2, l, m, x, y, z);
		updseg(idx * 2 + 1, m + 1, r, x, y, z);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], seg[idx].lazy);
	}
	//pp(idx);
}
void updseg(int x, int y, int z) { updseg(1, 0, N - 1, x, y, z); }
void updcnt(int x) { updseg(1, 0, N - 1, x, x, 0); }

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	int Q;

	cin >> N >> Q;
	for(int i = 0; i < N; i++) cin >> A[i];

	for(int i = 0; i < N; i++) {
		if(!s[A[i]].empty()) {
			cvr[*prev(s[A[i]].end())]++;
			cvr[i]--;
		}
		s[A[i]].insert(i);
		cnt[*s[A[i]].begin()]++;
	}
	for(int i = 1; i < N; i++) cvr[i] += cvr[i - 1];
	mkseg(1, 0, N - 1);

	//for(int i = 0; i < N; i++) printf("%d ", cvr[i]);
	//printf("\n");

	cout << N - seg[1].mxsum << "\n";
	while(Q--) {
		int x, y;
		cin >> x >> y;
		x--;

		//printf("***********\n");
		s[A[x]].erase(x);
		if(!s[A[x]].empty()) {
			if(x < *s[A[x]].begin()) {
				cnt[*s[A[x]].begin()] = cnt[x] - 1;
				updseg(x, *s[A[x]].begin() - 1, -1);
			}
			else cnt[*s[A[x]].begin()]--;
			updcnt(*s[A[x]].begin());
			if(x > *prev(s[A[x]].end()))
				updseg(*prev(s[A[x]].end()), x - 1, -1);
		}
		/*
		printf("cnt : ");
		for(int i = 0; i < N; i++) printf("%d ", cnt[i]);
		printf("\n");
		*/
		A[x] = y;
		if(!s[y].empty()) {
			if(x < *s[y].begin()) {
				cnt[x] = cnt[*s[y].begin()] + 1;
				cnt[*s[y].begin()] = 0;
				updseg(x, *s[y].begin() - 1, 1);
			}
			else {
				cnt[x] = 0;
				cnt[*s[y].begin()]++;
			}
			updcnt(*s[y].begin());
			if(y > *prev(s[y].end()))
				updseg(*prev(s[y].end()), x - 1, 1);
		}
		else cnt[x] = 1;
		updcnt(x);
		s[y].insert(x);
		/*
		printf("cnt : ");
		for(int i = 0; i < N; i++) printf("%d ", cnt[i]);
		printf("\n");
		for(int i = 0; i < N; i++) printf("%d ", A[i]);
		printf("\n");
		printf("s :\n");
		for(int i = 1; i < 4; i++) {
			printf("i = %d : ", i);
			for(auto a : s[i]) printf("%d ", a);
			printf("\n");
		}
		*/
		cout << N - seg[1].mxsum << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 200010;
const int MX = 1 << 18;

struct NOD {
	int mn, lazy, lmx, rmx, tmx, mxsum;
} seg[2 * MX];

int N;
int A[MAXN];
int cnt[MAXN], cvr[MAXN];
set<int> s[MAXN];

void pp(int i) {
	printf("seg[%d] = { mn = %d, lazy = %d, lmx = %d, rmx = %d, tmx = %d, mxsum = %d }\n", i, seg[i].mn, seg[i].lazy, seg[i].lmx, seg[i].rmx, seg[i].tmx, seg[i].mxsum); }

NOD mergenod(NOD &n1, NOD &n2, int l) {
	NOD r;
	r.mn = min(n1.mn, n2.mn) + l;
	r.lazy = l;
	r.lmx = n1.mn <= n2.mn ? n1.lmx : max(n1.tmx, n2.lmx);
	r.rmx = n2.mn <= n1.mn ? n2.rmx : max(n1.rmx, n2.tmx);
	r.tmx = max(n1.tmx, n2.tmx);
	if(n1.mn < n2.mn) r.mxsum = n1.mxsum - n1.rmx + max(n1.rmx, n2.tmx);
	else if(n1.mn > n2.mn) r.mxsum = max(n1.tmx, n2.lmx) + n2.mxsum - n2.lmx;
	else r.mxsum = n1.mxsum - n1.rmx + n2.mxsum - n2.lmx + max(n1.rmx, n2.lmx);
	return r;
}

void updnod(int idx, int l) { seg[idx].lmx = seg[idx].tmx = seg[idx].mxsum = cnt[l]; }

void mkseg(int idx, int l, int r) {
	if(l == r) {
		seg[idx].mn = cvr[l];
		updnod(idx, l);
	}
	else {
		int m = (l + r) / 2;
		mkseg(idx * 2, l, m);
		mkseg(idx * 2 + 1, m + 1, r);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], 0);
	}
	//pp(idx);
}

void updseg(int idx, int l, int r, int x, int y, int z) {
	//if(idx == 1) printf("updseg(x = %d, y = %d, z = %d)\n", x, y, z);
	if(l == r) updnod(idx, l);
	if(x <= l && r <= y) {
		seg[idx].mn += z;
		seg[idx].lazy += z;
	}
	else if(l <= y && x <= r) {
		int m = (l + r) / 2;
		updseg(idx * 2, l, m, x, y, z);
		updseg(idx * 2 + 1, m + 1, r, x, y, z);
		seg[idx] = mergenod(seg[idx * 2], seg[idx * 2 + 1], seg[idx].lazy);
	}
	//pp(idx);
}
void updseg(int x, int y, int z) { updseg(1, 0, N - 1, x, y, z); }
void updcnt(int x) { updseg(1, 0, N - 1, x, x, 0); }

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

	cin >> N >> Q;
	for(int i = 0; i < N; i++) cin >> A[i];

	for(int i = 0; i < N; i++) {
		if(!s[A[i]].empty()) {
			cvr[*prev(s[A[i]].end())]++;
			cvr[i]--;
		}
		s[A[i]].insert(i);
		cnt[*s[A[i]].begin()]++;
	}
	for(int i = 1; i < N; i++) cvr[i] += cvr[i - 1];
	mkseg(1, 0, N - 1);

	//for(int i = 0; i < N; i++) printf("%d ", cvr[i]);
	//printf("\n");

	cout << N - seg[1].mxsum << "\n";
	while(Q--) {
		int x, y;
		cin >> x >> y;
		x--;

		//printf("***********\n");
		s[A[x]].erase(x);
		if(!s[A[x]].empty() && x < *s[A[x]].begin()) {
			//printf("#01\n");
			cnt[*s[A[x]].begin()] = cnt[x] - 1;
			updseg(x, *s[A[x]].begin() - 1, -1);
		}
		else if(!s[A[x]].empty()) cnt[*s[A[x]].begin()]--;
		if(!s[A[x]].empty()) updcnt(*s[A[x]].begin());
		if(!s[A[x]].empty() && x > *prev(s[A[x]].end()))
			updseg(*prev(s[A[x]].end()), x - 1, -1);
		/*
		printf("cnt : ");
		for(int i = 0; i < N; i++) printf("%d ", cnt[i]);
		printf("\n");
		*/
		A[x] = y;
		if(!s[y].empty() && x < *s[y].begin()) {
			//printf("#1\n");
			cnt[x] = cnt[*s[y].begin()] + 1;
			cnt[*s[y].begin()] = 0;
			updseg(x, *s[y].begin() - 1, 1);
		}
		else if(!s[y].empty()) {
			//printf("#2 : %d\n", *s[y].begin());
			cnt[x] = 0;
			cnt[*s[y].begin()]++;
		}
		else cnt[x] = 1;
		updcnt(x);
		if(!s[y].empty()) updcnt(*s[y].begin());
		if(!s[y].empty() && y > *prev(s[y].end()))
			updseg(*prev(s[y].end()), x - 1, 1);
		s[y].insert(x);
		/*
		printf("cnt : ");
		for(int i = 0; i < N; i++) printf("%d ", cnt[i]);
		printf("\n");
		for(int i = 0; i < N; i++) printf("%d ", A[i]);
		printf("\n");
		printf("s :\n");
		for(int i = 1; i < 4; i++) {
			printf("i = %d : ", i);
			for(auto a : s[i]) printf("%d ", a);
			printf("\n");
		}
		*/
		cout << N - seg[1].mxsum << "\n";
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<climits>
#include<set>

typedef long long LL;
const int maxn = 2e5 + 10;
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second

int read()
{
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)) { if(c == '-') f = 0; c = getchar(); }
	while(isdigit(c)) { x = (x * 10) + (c ^ 48); c = getchar(); }
	return f ? x : -x;
}

int a[maxn], tag[maxn << 2], mn[maxn << 2], lm[maxn << 2], rm[maxn << 2], mm[maxn << 2], val[maxn << 2];
set<int> p[maxn];

void pushdown(int o)
{
	if(!tag[o]) return ;
	tag[o << 1] += tag[o]; tag[o << 1 | 1] += tag[o];
 	mn[o << 1] += tag[o]; mn[o << 1 | 1] += tag[o];
	tag[o] = 0;
}

void pushup(int o)
{
	val[o] = max(val[o << 1], val[o << 1 | 1]);
	mn[o] = min(mn[o << 1], mn[o << 1 | 1]);
	if(mn[o << 1] < mn[o << 1 | 1])
	{
		rm[o] = max(rm[o << 1], val[o << 1 | 1]);
		lm[o] = lm[o << 1]; mm[o] = mm[o << 1];
		return ;
	}
	if(mn[o << 1] > mn[o << 1 | 1])
	{
		lm[o] = max(lm[o << 1 | 1], val[o << 1]);
		rm[o] = rm[o << 1 | 1]; mm[o] = mm[o << 1 | 1];
		return ;
	}
	lm[o] = lm[o << 1]; rm[o] = rm[o << 1 | 1]; mm[o] = mm[o << 1] + mm[o << 1 | 1] + max(rm[o << 1], lm[o << 1 | 1]);
}

void upt(int o, int l, int r, int x, int y, int v)
{
	if(l > r) return ;
	if(x <= l && r <= y) { mn[o] += v, tag[o] += v; return ; }
	pushdown(o);
	int mid = (l + r) >> 1;
	if(x <= mid) upt(o << 1, l, mid, x, y, v);
	if(y > mid) upt(o << 1 | 1, mid + 1, r, x, y, v);
	pushup(o);
}

void upt_max(int o, int l, int r, int x, int v)
{
	if(l > r) return ;
	if(l == r) { lm[o] = v; val[o] = v; return ; }
	pushdown(o);
	int mid = (l + r) >> 1;
	if(x <= mid) upt_max(o << 1, l, mid, x, v);
	else upt_max(o << 1 | 1, mid + 1, r, x, v);
	pushup(o);
}

int que() { return lm[1] + mm[1] + rm[1]; }

int main()
{

	int n = read(), Q = read();
	for(int i = 1; i <= n; ++i)
	{
		a[i] = read();
		p[a[i]].insert(i);
	}
	for(int i = 1; i <= 2e5; ++i) if(p[i].size())
		upt(1, 1, n, *p[i].begin(), *p[i].rbegin() - 1, 1), upt_max(1, 1, n, *p[i].begin(), p[i].size());

	printf("%d\n", n - que());
	while(Q--)
	{
		int x = read(), y = read();
		int z = a[x];
		upt(1, 1, n, *p[z].begin(), *p[z].rbegin() - 1, -1); upt_max(1, 1, n, *p[z].begin(), 0);
		p[z].erase(x);
		if(p[z].size()) upt(1, 1, n, *p[z].begin(), *p[z].rbegin() - 1, 1), upt_max(1, 1, n, *p[z].begin(), p[z].size());
		if(p[y].size()) upt(1, 1, n, *p[y].begin(), *p[y].rbegin() - 1, -1), upt_max(1, 1, n, *p[y].begin(), 0);
		p[y].insert(x);
		upt(1, 1, n, *p[y].begin(), *p[y].rbegin() - 1, 1); upt_max(1, 1, n, *p[y].begin(), p[y].size());
		printf("%d\n", n - que());
		a[x] = y;
	}

	return 0;
}


//#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<climits>
#include<set>

typedef long long LL;
const int maxn = 2e5 + 10;
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second

int read()
{
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)) { if(c == '-') f = 0; c = getchar(); }
	while(isdigit(c)) { x = (x * 10) + (c ^ 48); c = getchar(); }
	return f ? x : -x;
}

int a[maxn], id[maxn];
vector<pair<pair<int, int>, int> > vec[maxn << 2];
set<pair<pair<int, int>, int> > S;
set<int> p[maxn];

void upt(int o, int l, int r, int x, int y, pair<pair<int, int>, int> v)
{
	if(x <= l && r <= y) return (void)(vec[o].pb(v));
	int mid = (l + r) >> 1;
	if(x <= mid) upt(o << 1, l, mid, x, y, v);
	if(y > mid) upt(o << 1 | 1, mid + 1, r, x, y, v);
}

int n;//, tot;
void gao(int o, int l, int r, int ans)
{
	vector<pair<pair<int, int>, pair<int, int> > > opt;
	for(auto i : vec[o])
	{
		auto L = S.begin(), R = S.begin();
		int L1 = i.x.x, R1 = i.x.y, Mx = i.y;
		if(!S.size()) goto NXT;
		L = S.lower_bound(mp(mp(i.x.x + 1, i.x.x + 1), 0));
	   	if(L != S.begin()) { --L; if((*L).x.y < i.x.x) ++L; }
		if(L == S.end() || (*L).x.x > i.x.y) goto NXT;
		R = S.lower_bound(mp(mp(i.x.y + 1, i.x.y + 1), 0));
		if(R != S.begin()) --R;
		for(auto j = L; ; )
		{
			Mx = max((*j).y, Mx);
			L1 = min((*j).x.x, L1); R1 = max((*j).x.y, R1);
			ans -= (*j).y;
			if(j == R) { opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++); break; }
			opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++);
		//	++tot;
		}
		NXT:;
		ans += Mx;
		pair<pair<int, int>, int> tmp = mp(mp(L1, R1), Mx);
		S.insert(tmp); opt.pb(mp(tmp.x, mp(tmp.y, 1)));
		//cout << o << ' ' << S.size() << ' ' << tot << endl;
	}
	reverse(opt.begin(), opt.end());

	int mid = (l + r) >> 1;
	if(l == r) { printf("%d\n", n - ans); goto nxt; }
	gao(o << 1, l, mid, ans); gao(o << 1 | 1, mid + 1, r, ans);
	nxt:;
	for(auto i : opt)
	{
		if(i.y.y == 0) S.insert(mp(i.x, i.y.x));
		else S.erase(S.lower_bound(mp(i.x, i.y.x)));
	}
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	n = read(); int Q = read();
	for(int i = 1; i <= n; ++i)
	{
		a[i] = read();
		p[a[i]].insert(i);
	}
	for(int i = 1; i <= Q; ++i)
	{
		int x = read(), y = read();
		int A = a[x];
		upt(1, 0, Q, id[A], i - 1, mp(mp(*p[A].begin(), *p[A].rbegin()), p[A].size()));
		p[A].erase(x); id[A] = i;
		if(p[y].size()) upt(1, 0, Q, id[y], i - 1, mp(mp(*p[y].begin(), *p[y].rbegin()), p[y].size()));
		p[y].insert(x); id[y] = i;
		a[x] = y;
	}
	for(int i = 1; i <= 2e5; ++i) if(p[i].size())
		upt(1, 0, Q, id[i], Q, mp(mp(*p[i].begin(), *p[i].rbegin()), p[i].size()));

	gao(1, 0, Q, 0);

	return 0;
}


//#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<climits>
#include<set>

typedef long long LL;
const int maxn = 2e5 + 10;
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second

int read()
{
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)) { if(c == '-') f = 0; c = getchar(); }
	while(isdigit(c)) { x = (x * 10) + (c ^ 48); c = getchar(); }
	return f ? x : -x;
}

int a[maxn], id[maxn];
vector<pair<pair<int, int>, int> > vec[maxn << 2];
set<pair<pair<int, int>, int> > S;
set<int> p[maxn];

void upt(int o, int l, int r, int x, int y, pair<pair<int, int>, int> v)
{
	if(x <= l && r <= y) return (void)(vec[o].pb(v));
	int mid = (l + r) >> 1;
	if(x <= mid) upt(o << 1, l, mid, x, y, v);
	if(y > mid) upt(o << 1 | 1, mid + 1, r, x, y, v);
}

int n, tot;
void gao(int o, int l, int r, int ans)
{
	vector<pair<pair<int, int>, pair<int, int> > > opt;
	for(auto i : vec[o])
	{
		auto L = S.lower_bound(mp(mp(i.x.x + 1, i.x.x + 1), 0)); --L;
		auto R = S.lower_bound(mp(mp(i.x.y + 1, i.x.y + 1), 0)); --R;
		int L1 = i.x.x, R1 = i.x.y, Mx = i.y;
		tot = 0;
		//cout << S.size() << endl;
		for(auto j = L; ; )
		{
			Mx = max((*j).y, Mx);
			L1 = min((*j).x.x, L1); R1 = max((*j).x.y, R1);
			ans -= (*j).y;
			if(j == R) { opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++); break; }
			opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++);
			++tot;
		}
		ans += Mx;
		pair<pair<int, int>, int> tmp = mp(mp(L1, R1), Mx);
		S.insert(tmp); opt.pb(mp(tmp.x, mp(tmp.y, 1)));
		//cout << o << ' ' << S.size() << ' ' << tot << endl;
	}
	reverse(opt.begin(), opt.end());

	int mid = (l + r) >> 1;
	if(l == r) { printf("%d\n", n - ans); goto nxt; }
	gao(o << 1, l, mid, ans); gao(o << 1 | 1, mid + 1, r, ans);
	nxt:;
	for(auto i : opt)
	{
		if(i.y.y == 0) S.insert(mp(i.x, i.y.x));
		else S.erase(S.lower_bound(mp(i.x, i.y.x)));
	}
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	n = read(); int Q = read();
	for(int i = 1; i <= n; ++i)
	{
		a[i] = read();
		p[a[i]].insert(i);
	}
	for(int i = 1; i <= Q; ++i)
	{
		int x = read(), y = read();
		int A = a[x];
		upt(1, 0, Q, id[A], i - 1, mp(mp(*p[A].begin(), *p[A].rbegin()), p[A].size()));
		p[A].erase(x); id[A] = i;
		if(p[y].size()) upt(1, 0, Q, id[y], i - 1, mp(mp(*p[y].begin(), *p[y].rbegin()), p[y].size()));
		p[y].insert(x); id[y] = i;
		a[x] = y;
	}
	for(int i = 1; i <= 2e5; ++i) if(p[i].size())
		upt(1, 0, Q, id[i], Q, mp(mp(*p[i].begin(), *p[i].rbegin()), p[i].size()));

	//for(int i = 1; i <= n; ++i) S.insert(mp(mp(i, i), 1));
	S.insert(mp(mp(1, n), n));
	gao(1, 0, Q, n);
	cout << tot << endl;

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<climits>
#include<set>

typedef long long LL;
const int maxn = 2e5 + 10;
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second

int read()
{
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)) { if(c == '-') f = 0; c = getchar(); }
	while(isdigit(c)) { x = (x * 10) + (c ^ 48); c = getchar(); }
	return f ? x : -x;
}

int a[maxn], tag[maxn << 2], mn[maxn << 2], lm[maxn << 2], rm[maxn << 2], mm[maxn << 2], val[maxn << 2];
set<int> p[maxn];

void pushdown(int o)
{
	if(!tag[o]) return ;
	tag[o << 1] += tag[o]; tag[o << 1 | 1] += tag[o];
 	mn[o << 1] += tag[o]; mn[o << 1 | 1] += tag[o];
	tag[o] = 0;
}

void pushup(int o)
{
	val[o] = max(val[o << 1], val[o << 1 | 1]);
	mn[o] = min(mn[o << 1], mn[o << 1 | 1]);
	if(mn[o << 1] < mn[o << 1 | 1])
	{
		rm[o] = max(rm[o << 1], val[o << 1 | 1]);
		lm[o] = lm[o << 1]; mm[o] = mm[o << 1];
		return ;
	}
	if(mn[o << 1] > mn[o << 1 | 1])
	{
		lm[o] = max(lm[o << 1 | 1], val[o << 1]);
		rm[o] = rm[o << 1 | 1]; mm[o] = mm[o << 1 | 1];
		return ;
	}
	lm[o] = lm[o << 1]; rm[o] = rm[o << 1 | 1]; mm[o] = mm[o << 1] + mm[o << 1 | 1] + max(rm[o << 1], lm[o << 1 | 1]);
}

void upt(int o, int l, int r, int x, int y, int v)
{
	if(x > y) return ;
	if(x <= l && r <= y) { mn[o] += v, tag[o] += v; return ; }
	pushdown(o);
	int mid = (l + r) >> 1;
	if(x <= mid) upt(o << 1, l, mid, x, y, v);
	if(y > mid) upt(o << 1 | 1, mid + 1, r, x, y, v);
	pushup(o);
}

void upt_max(int o, int l, int r, int x, int v)
{
	if(l == r) { lm[o] = v; val[o] = v; return ; }
	pushdown(o);
	int mid = (l + r) >> 1;
	if(x <= mid) upt_max(o << 1, l, mid, x, v);
	else upt_max(o << 1 | 1, mid + 1, r, x, v);
	pushup(o);
}

int que() { return lm[1] + mm[1] + rm[1]; }

int main()
{

	int n = read(), Q = read();
	for(int i = 1; i <= n; ++i)
	{
		a[i] = read();
		p[a[i]].insert(i);
	}
	for(int i = 1; i <= 2e5; ++i) if(p[i].size())
		upt(1, 1, n, *p[i].begin(), *p[i].rbegin() - 1, 1), upt_max(1, 1, n, *p[i].begin(), p[i].size());

	printf("%d\n", n - que());
	while(Q--)
	{
		int x = read(), y = read();
		int z = a[x];
		upt(1, 1, n, *p[z].begin(), *p[z].rbegin() - 1, -1); upt_max(1, 1, n, *p[z].begin(), 0);
		p[z].erase(x);
		if(p[z].size()) upt(1, 1, n, *p[z].begin(), *p[z].rbegin() - 1, 1), upt_max(1, 1, n, *p[z].begin(), p[z].size());
		if(p[y].size()) upt(1, 1, n, *p[y].begin(), *p[y].rbegin() - 1, -1), upt_max(1, 1, n, *p[y].begin(), 0);
		p[y].insert(x);
		upt(1, 1, n, *p[y].begin(), *p[y].rbegin() - 1, 1); upt_max(1, 1, n, *p[y].begin(), p[y].size());
		printf("%d\n", n - que());
		a[x] = y;
	}

	return 0;
}


#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<climits>
#include<set>

typedef long long LL;
const int maxn = 2e5 + 10;
using namespace std;
#define pb push_back
#define mp make_pair
#define x first
#define y second

int read()
{
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)) { if(c == '-') f = 0; c = getchar(); }
	while(isdigit(c)) { x = (x * 10) + (c ^ 48); c = getchar(); }
	return f ? x : -x;
}

int a[maxn], id[maxn];
vector<pair<pair<int, int>, int> > vec[maxn << 2];
set<pair<pair<int, int>, int> > S;
set<int> p[maxn];

void upt(int o, int l, int r, int x, int y, pair<pair<int, int>, int> v)
{
	if(x <= l && r <= y) return (void)(vec[o].pb(v));
	int mid = (l + r) >> 1;
	if(x <= mid) upt(o << 1, l, mid, x, y, v);
	if(y > mid) upt(o << 1 | 1, mid + 1, r, x, y, v);
}

int n;
void gao(int o, int l, int r, int ans)
{
	vector<pair<pair<int, int>, pair<int, int> > > opt;
	for(auto i : vec[o])
	{
		auto L = S.lower_bound(mp(mp(i.x.x + 1, i.x.x + 1), 0)); --L;
		auto R = S.lower_bound(mp(mp(i.x.y + 1, i.x.y + 1), 0)); --R;
		int L1 = i.x.x, R1 = i.x.y, Mx = i.y;
		for(auto j = L; ; )
		{
			Mx = max((*j).y, Mx);
			L1 = min((*j).x.x, L1); R1 = max((*j).x.y, R1);
			ans -= (*j).y;
			if(j == R) { opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++); break; }
			opt.pb(mp((*j).x, mp((*j).y, 0))); S.erase(j++);
		}
		ans += Mx;
		pair<pair<int, int>, int> tmp = mp(mp(L1, R1), Mx);
		S.insert(tmp); opt.pb(mp(tmp.x, mp(tmp.y, 1)));
	}
	reverse(opt.begin(), opt.end());

	int mid = (l + r) >> 1;
	if(l == r) { printf("%d\n", n - ans); goto nxt; }
	gao(o << 1, l, mid, ans); gao(o << 1 | 1, mid + 1, r, ans);
	nxt:;
	for(auto i : opt)
	{
		if(i.y.y == 0) S.insert(mp(i.x, i.y.x));
		else S.erase(S.lower_bound(mp(i.x, i.y.x)));
	}
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif

	n = read(); int Q = read();
	for(int i = 1; i <= n; ++i)
	{
		a[i] = read();
		p[a[i]].insert(i);
	}
	for(int i = 1; i <= Q; ++i)
	{
		int x = read(), y = read();
		int A = a[x];
		upt(1, 0, Q, id[A], i - 1, mp(mp(*p[A].begin(), *p[A].rbegin()), p[A].size()));
		p[A].erase(x); id[A] = i;
		if(p[y].size()) upt(1, 0, Q, id[y], i - 1, mp(mp(*p[y].begin(), *p[y].rbegin()), p[y].size()));
		p[y].insert(x); id[y] = i;
		a[x] = y;
	}
	for(int i = 1; i <= 2e5; ++i) if(p[i].size())
		upt(1, 0, Q, id[i], Q, mp(mp(*p[i].begin(), *p[i].rbegin()), p[i].size()));

	for(int i = 1; i <= n; ++i) S.insert(mp(mp(i, i), 1));
	gao(1, 0, Q, n);

	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=200000;
const int MAXQ=200000;
const int MAXCOL=200000;

struct Q { int pos,col,id; Q() {} Q(int pos,int col,int id):pos(pos),col(col),id(id) {} };
struct State {
	int n,ncol;
	vector<int> col;
	vector<int> match;
	vector<int> sum;
	vector<int> mx;
	vector<int> cnt;
	vector<Q> q;
};

void printstate(const State &state) {
	REP(i,state.n) {
		int col=state.col[i];
		if(col!=-1) { printf(" %d",col); assert(state.match[i]==-1); continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			printf(" [sum=%d,mx=%d]",state.sum[i],state.mx[i]);
		} else if(i<state.match[i]) {
			printf(" [%d:sum=%d,mx=%d",i,state.sum[i],state.mx[i]);
		} else {
			printf(" :%d]",state.match[i]);
		}
	}
	REPSZ(i,state.q) printf(" (%d:%d=%d)",state.q[i].id,state.q[i].pos,state.q[i].col);
}

State reduce(State state,int l,int r) {
	//printf("\treduce(%d..%d):",l,r); printstate(state); puts("");
	vector<bool> done(state.ncol,true);
	vector<bool> used(state.n,false);
	FORE(i,l,r) { int pos=state.q[i].pos,ocol=state.col[pos],ncol=state.q[i].col; assert(ocol!=-1); done[ocol]=done[ncol]=false; used[pos]=true; }
	vector<int> fst(state.ncol,INT_MAX),lst(state.ncol,INT_MIN);
	REP(i,state.n) { int col=state.col[i]; if(col!=-1&&!used[i]) fst[col]=min(fst[col],i),lst[col]=max(lst[col],i); }
	//REP(i,state.ncol) if(state.cnt[i]!=0) printf("\t\t%d: %d %d %d %d\n",i,done[i]?1:0,fst[i],lst[i],state.cnt[i]);
	vector<bool> alive(state.n,true);
	REP(i,state.n) {
		int col=state.col[i];
		if(col==-1||used[i]) continue;
		if(i!=fst[col]&&i!=lst[col]) { alive[i]=false; continue; }
		if(!done[col]) continue;
		state.col[i]=-1;
		state.match[i]=fst[col]+lst[col]-i;
		if(i==fst[col]) state.sum[i]=state.mx[i]=state.cnt[col];
	}
	int bal=0,fstidx=-1,mx=0,cntalivebetween=0;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { if(bal!=0) ++cntalivebetween; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			if(bal==0) {
				//nothing
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		} else if(i<state.match[i]) {
			if(bal==0) {
				fstidx=i,mx=state.mx[i],cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
			++bal;
		} else {
			--bal;
			if(bal==0) {
				if(cntalivebetween==0) {
					state.match[fstidx]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
					alive[i]=false;
				} else {
					state.match[fstidx]=i,state.match[i]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
				}
				fstidx=-1,mx=0,cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		}
	}
	int reuseidx=-1;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { reuseidx=-1; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]!=i) { reuseidx=-1; continue; }
		if(reuseidx==-1) { reuseidx=i; continue; }
		state.mx[reuseidx]=max(state.mx[reuseidx],state.mx[i]);
		state.sum[reuseidx]+=state.sum[i];
		alive[i]=false;
	}

	State ret;
	vector<int> posmp(state.n,-1); ret.n=0; REP(i,state.n) if(alive[i]) posmp[i]=ret.n++;
	vector<int> colmp(state.ncol,-1); ret.ncol=0; REP(i,state.ncol) if(!done[i]) colmp[i]=ret.ncol++;
	ret.col=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.col[i]!=-1) ret.col[posmp[i]]=colmp[state.col[i]];
	ret.match=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1) ret.match[posmp[i]]=posmp[state.match[i]];
	ret.sum=ret.mx=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1&&i<=state.match[i]) ret.sum[posmp[i]]=state.sum[i],ret.mx[posmp[i]]=state.mx[i];
	FORE(i,l,r) { int pos=state.q[i].pos,col=state.q[i].col,id=state.q[i].id; ret.q.PB(Q(posmp[pos],colmp[col],id)); }
	REP(i,ret.n) if(ret.col[i]!=-1) ret.sum[i]=1;
	ret.cnt=vector<int>(ret.ncol,0); REP(i,state.ncol) if(!done[i]) ret.cnt[colmp[i]]=state.cnt[i];
	//printf("\t->"); printstate(ret); puts("");
	return ret;
}

void apply(State &state,const Q &q) {
	int pos=q.pos,ocol=state.col[pos],ncol=q.col; assert(ocol!=-1); state.col[pos]=ncol; --state.cnt[ocol],++state.cnt[ncol]; //printf("\tchange %d from %d to %d\n",pos,ocol,ncol);
}

int calc(State &state) {
	assert(state.n==1&&state.col[0]==-1);
	return state.sum[0];
}

int ans[MAXQ+1];

void rec(State &state) {
	//printf("rec:"); printstate(state); puts("");
	static int xxx=0; if(++xxx>=20) exit(0);
	if(SZ(state.q)==1) {
		if(state.q[0].id==0) {
			State tmp=reduce(state,0,-1);
			//printf("at start:"); printstate(tmp); puts("");
			ans[0]=calc(tmp);
		}
		apply(state,state.q[0]);
		State res=reduce(state,0,-1);
		//printf("after %d:",state.q[0].id); printstate(res); puts("");
		ans[state.q[0].id+1]=calc(res);
		return;
	}
	int m=SZ(state.q)/2;
	rec(reduce(state,0,m-1));
	REP(i,m) apply(state,state.q[i]);
	rec(reduce(state,m,SZ(state.q)-1));
}

State sstate;

void solve() {
	State state=sstate;
	rec(state);
	REPE(i,SZ(sstate.q)) ans[i]=sstate.n-ans[i];
}

void run() {
	int nq; scanf("%d%d",&sstate.n,&nq); sstate.ncol=MAXCOL;
	sstate.col=vector<int>(sstate.n); REP(i,sstate.n) { int col; scanf("%d",&col); --col; sstate.col[i]=col; }
	sstate.sum=sstate.match=sstate.mx=vector<int>(sstate.n,-1); sstate.cnt=vector<int>(MAXCOL,0); REP(i,sstate.n) ++sstate.cnt[sstate.col[i]];
	sstate.q.clear(); REP(i,nq) { int pos,col; scanf("%d%d",&pos,&col); --pos,--col; sstate.q.PB(Q(pos,col,i)); }
	solve();
	REPE(i,nq) printf("%d\n",ans[i]);
}

int main() {
	run();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=200000;
const int MAXQ=200000;
const int MAXCOL=200000;

struct Q { int pos,col,id; Q() {} Q(int pos,int col,int id):pos(pos),col(col),id(id) {} };
struct State {
	int n,ncol;
	vector<int> col;
	vector<int> match;
	vector<int> sum;
	vector<int> mx;
	vector<int> cnt;
	vector<Q> q;
};

void printstate(const State &state) {
	REP(i,state.n) {
		int col=state.col[i];
		if(col!=-1) { printf(" %d",col); assert(state.match[i]==-1); continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			printf(" [sum=%d,mx=%d]",state.sum[i],state.mx[i]);
		} else if(i<state.match[i]) {
			printf(" [%d:sum=%d,mx=%d",i,state.sum[i],state.mx[i]);
		} else {
			printf(" :%d]",state.match[i]);
		}
	}
	REPSZ(i,state.q) printf(" (%d:%d=%d)",state.q[i].id,state.q[i].pos,state.q[i].col);
}

State reduce(State state,int l,int r) {
	//printf("\treduce(%d..%d):",l,r); printstate(state); puts("");
	vector<bool> done(state.ncol,true);
	vector<bool> used(state.n,false);
	FORE(i,l,r) { int pos=state.q[i].pos,ocol=state.col[pos],ncol=state.q[i].col; assert(ocol!=-1); done[ocol]=done[ncol]=false; used[pos]=true; }
	vector<int> fst(state.ncol,INT_MAX),lst(state.ncol,INT_MIN);
	REP(i,state.n) { int col=state.col[i]; if(col!=-1&&!used[i]) fst[col]=min(fst[col],i),lst[col]=max(lst[col],i); }
	//REP(i,state.ncol) if(state.cnt[i]!=0) printf("\t\t%d: %d %d %d %d\n",i,done[i]?1:0,fst[i],lst[i],state.cnt[i]);
	vector<bool> alive(state.n,true);
	REP(i,state.n) {
		int col=state.col[i];
		if(col==-1||used[i]) continue;
		if(i!=fst[col]&&i!=lst[col]) { alive[i]=false; continue; }
		if(!done[col]) continue;
		state.col[i]=-1;
		state.match[i]=fst[col]+lst[col]-i;
		if(i==fst[col]) state.sum[i]=state.mx[i]=state.cnt[col];
	}
	int bal=0,fstidx=-1,mx=0,cntalivebetween=0;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { if(bal!=0) ++cntalivebetween; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			if(bal==0) {
				//nothing
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		} else if(i<state.match[i]) {
			if(bal==0) {
				fstidx=i,mx=state.mx[i],cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
			++bal;
		} else {
			--bal;
			if(bal==0) {
				if(cntalivebetween==0) {
					state.match[fstidx]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
					alive[i]=false;
				} else {
					state.match[fstidx]=i,state.match[i]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
				}
				fstidx=-1,mx=0,cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		}
	}
	int reuseidx=-1;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { reuseidx=-1; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]!=i) { reuseidx=-1; continue; }
		if(reuseidx==-1) { reuseidx=i; continue; }
		state.mx[reuseidx]=max(state.mx[reuseidx],state.mx[i]);
		state.sum[reuseidx]+=state.sum[i];
		alive[i]=false;
	}

	State ret;
	vector<int> posmp(state.n,-1); ret.n=0; REP(i,state.n) if(alive[i]) posmp[i]=ret.n++;
	vector<int> colmp(state.ncol,-1); ret.ncol=0; REP(i,state.ncol) if(!done[i]) colmp[i]=ret.ncol++;
	ret.col=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.col[i]!=-1) ret.col[posmp[i]]=colmp[state.col[i]];
	ret.match=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1) ret.match[posmp[i]]=posmp[state.match[i]];
	ret.sum=ret.mx=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1&&i<=state.match[i]) ret.sum[posmp[i]]=state.sum[i],ret.mx[posmp[i]]=state.mx[i];
	FORE(i,l,r) { int pos=state.q[i].pos,col=state.q[i].col,id=state.q[i].id; ret.q.PB(Q(posmp[pos],colmp[col],id)); }
	REP(i,ret.n) if(ret.col[i]!=-1) ret.sum[i]=1;
	ret.cnt=vector<int>(ret.ncol,0); REP(i,state.ncol) if(!done[i]) ret.cnt[colmp[i]]=state.cnt[i];
	//printf("\t->"); printstate(ret); puts("");
	return ret;
}

void apply(State &state,const Q &q) {
	int pos=q.pos,ocol=state.col[pos],ncol=q.col; assert(ocol!=-1); state.col[pos]=ncol; --state.cnt[ocol],++state.cnt[ncol]; //printf("\tchange %d from %d to %d\n",pos,ocol,ncol);
}

int calc(State &state) {
	assert(state.n==1&&state.col[0]==-1);
	return state.sum[0];
}

int ans[MAXQ+1];

void rec(State &state) {
	//printf("rec:"); printstate(state); puts("");
	//static int xxx=0; if(++xxx>=20) exit(0);
	if(SZ(state.q)==0) {
		State res=reduce(state,0,-1);
		ans[0]=calc(res);
		return;
	}
	if(SZ(state.q)==1) {
		if(state.q[0].id==0) {
			State tmp=reduce(state,0,-1);
			//printf("at start:"); printstate(tmp); puts("");
			ans[0]=calc(tmp);
		}
		apply(state,state.q[0]);
		State res=reduce(state,0,-1);
		//printf("after %d:",state.q[0].id); printstate(res); puts("");
		ans[state.q[0].id+1]=calc(res);
		return;
	}
	int m=SZ(state.q)/2;
	State lstate=reduce(state,0,m-1);
	rec(lstate);
	REP(i,m) apply(state,state.q[i]);
	State rstate=reduce(state,m,SZ(state.q)-1);
	rec(rstate);
}

State sstate;

void solve() {
	State state=sstate;
	rec(state);
	REPE(i,SZ(sstate.q)) ans[i]=sstate.n-ans[i];
}

void run() {
	int nq; scanf("%d%d",&sstate.n,&nq); sstate.ncol=MAXCOL;
	sstate.col=vector<int>(sstate.n); REP(i,sstate.n) { int col; scanf("%d",&col); --col; sstate.col[i]=col; }
	sstate.sum=sstate.match=sstate.mx=vector<int>(sstate.n,-1); sstate.cnt=vector<int>(MAXCOL,0); REP(i,sstate.n) ++sstate.cnt[sstate.col[i]];
	sstate.q.clear(); REP(i,nq) { int pos,col; scanf("%d%d",&pos,&col); --pos,--col; sstate.q.PB(Q(pos,col,i)); }
	solve();
	REPE(i,nq) printf("%d\n",ans[i]);
}

void stress() {
	int mxn=10,mxcol=10;
	REP(rep,1000) {
		sstate.n=rand()%mxn+1;
		sstate.ncol=rand()%mxcol+1;
		sstate.col=vector<int>(sstate.n); REP(i,sstate.n) sstate.col[i]=rand()%sstate.ncol;
		sstate.sum=sstate.match=sstate.mx=vector<int>(sstate.n,-1); sstate.cnt=vector<int>(sstate.ncol,0); REP(i,sstate.n) ++sstate.cnt[sstate.col[i]];
		sstate.q.clear();
		solve();
		printf(".");
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=200000;
const int MAXQ=200000;
const int MAXCOL=200000;

struct Q { int pos,col,id; Q() {} Q(int pos,int col,int id):pos(pos),col(col),id(id) {} };
struct State {
	int n,ncol;
	vector<int> col;
	vector<int> match;
	vector<int> sum;
	vector<int> mx;
	vector<int> cnt;
	vector<Q> q;
};

void printstate(const State &state) {
	REP(i,state.n) {
		int col=state.col[i];
		if(col!=-1) { printf(" %d",col); assert(state.match[i]==-1); continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			printf(" [sum=%d,mx=%d]",state.sum[i],state.mx[i]);
		} else if(i<state.match[i]) {
			printf(" [%d:sum=%d,mx=%d",i,state.sum[i],state.mx[i]);
		} else {
			printf(" :%d]",state.match[i]);
		}
	}
	REPSZ(i,state.q) printf(" (%d:%d=%d)",state.q[i].id,state.q[i].pos,state.q[i].col);
}

State reduce(State state,int l,int r) {
	//printf("\treduce(%d..%d):",l,r); printstate(state); puts("");
	vector<bool> done(state.ncol,true);
	vector<bool> used(state.n,false);
	FORE(i,l,r) { int pos=state.q[i].pos,ocol=state.col[pos],ncol=state.q[i].col; assert(ocol!=-1); done[ocol]=done[ncol]=false; used[pos]=true; }
	vector<int> fst(state.ncol,INT_MAX),lst(state.ncol,INT_MIN);
	REP(i,state.n) { int col=state.col[i]; if(col!=-1&&!used[i]) fst[col]=min(fst[col],i),lst[col]=max(lst[col],i); }
	//REP(i,state.ncol) if(state.cnt[i]!=0) printf("\t\t%d: %d %d %d %d\n",i,done[i]?1:0,fst[i],lst[i],state.cnt[i]);
	vector<bool> alive(state.n,true);
	REP(i,state.n) {
		int col=state.col[i];
		if(col==-1||used[i]) continue;
		if(i!=fst[col]&&i!=lst[col]) { alive[i]=false; continue; }
		if(!done[col]) continue;
		state.col[i]=-1;
		state.match[i]=fst[col]+lst[col]-i;
		if(i==fst[col]) state.sum[i]=state.mx[i]=state.cnt[col];
	}
	int bal=0,fstidx=-1,mx=0,cntalivebetween=0;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { if(bal!=0) ++cntalivebetween; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			if(bal==0) {
				//nothing
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		} else if(i<state.match[i]) {
			if(bal==0) {
				fstidx=i,mx=state.mx[i],cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
			++bal;
		} else {
			--bal;
			if(bal==0) {
				if(cntalivebetween==0) {
					state.match[fstidx]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
					alive[i]=false;
				} else {
					state.match[fstidx]=i,state.match[i]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
				}
				fstidx=-1,mx=0,cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		}
	}
	int reuseidx=-1;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { reuseidx=-1; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]!=i) { reuseidx=-1; continue; }
		if(reuseidx==-1) { reuseidx=i; continue; }
		state.mx[reuseidx]=max(state.mx[reuseidx],state.mx[i]);
		state.sum[reuseidx]+=state.sum[i];
		alive[i]=false;
	}

	State ret;
	vector<int> posmp(state.n,-1); ret.n=0; REP(i,state.n) if(alive[i]) posmp[i]=ret.n++;
	vector<int> colmp(state.ncol,-1); ret.ncol=0; REP(i,state.ncol) if(!done[i]) colmp[i]=ret.ncol++;
	ret.col=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.col[i]!=-1) ret.col[posmp[i]]=colmp[state.col[i]];
	ret.match=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1) ret.match[posmp[i]]=posmp[state.match[i]];
	ret.sum=ret.mx=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1&&i<=state.match[i]) ret.sum[posmp[i]]=state.sum[i],ret.mx[posmp[i]]=state.mx[i];
	FORE(i,l,r) { int pos=state.q[i].pos,col=state.q[i].col,id=state.q[i].id; ret.q.PB(Q(posmp[pos],colmp[col],id)); }
	REP(i,ret.n) if(ret.col[i]!=-1) ret.sum[i]=1;
	ret.cnt=vector<int>(ret.ncol,0); REP(i,state.ncol) if(!done[i]) ret.cnt[colmp[i]]=state.cnt[i];
	//printf("\t->"); printstate(ret); puts("");
	return ret;
}

void apply(State &state,const Q &q) {
	int pos=q.pos,ocol=state.col[pos],ncol=q.col; assert(ocol!=-1); state.col[pos]=ncol; --state.cnt[ocol],++state.cnt[ncol]; //printf("\tchange %d from %d to %d\n",pos,ocol,ncol);
}

int calc(State &state) {
	assert(state.n==1&&state.col[0]==-1);
	return state.sum[0];
}

int ans[MAXQ+1];

void rec(State &state) {
	//printf("rec:"); printstate(state); puts("");
	static int xxx=0; if(++xxx>=20) exit(0);
	if(SZ(state.q)==0) {
		State res=reduce(state,0,-1);
		ans[0]=calc(res);
		return;
	}
	if(SZ(state.q)==1) {
		if(state.q[0].id==0) {
			State tmp=reduce(state,0,-1);
			//printf("at start:"); printstate(tmp); puts("");
			ans[0]=calc(tmp);
		}
		apply(state,state.q[0]);
		State res=reduce(state,0,-1);
		//printf("after %d:",state.q[0].id); printstate(res); puts("");
		ans[state.q[0].id+1]=calc(res);
		return;
	}
	int m=SZ(state.q)/2;
	State lstate=reduce(state,0,m-1);
	rec(lstate);
	REP(i,m) apply(state,state.q[i]);
	State rstate=reduce(state,m,SZ(state.q)-1);
	rec(rstate);
}

State sstate;

void solve() {
	State state=sstate;
	rec(state);
	REPE(i,SZ(sstate.q)) ans[i]=sstate.n-ans[i];
}

void run() {
	int nq; scanf("%d%d",&sstate.n,&nq); sstate.ncol=MAXCOL;
	sstate.col=vector<int>(sstate.n); REP(i,sstate.n) { int col; scanf("%d",&col); --col; sstate.col[i]=col; }
	sstate.sum=sstate.match=sstate.mx=vector<int>(sstate.n,-1); sstate.cnt=vector<int>(MAXCOL,0); REP(i,sstate.n) ++sstate.cnt[sstate.col[i]];
	sstate.q.clear(); REP(i,nq) { int pos,col; scanf("%d%d",&pos,&col); --pos,--col; sstate.q.PB(Q(pos,col,i)); }
	solve();
	REPE(i,nq) printf("%d\n",ans[i]);
}

int main() {
	run();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=200000;
const int MAXQ=200000;
const int MAXCOL=200000;

struct Q { int pos,col,id; Q() {} Q(int pos,int col,int id):pos(pos),col(col),id(id) {} };
struct State {
	int n,ncol;
	vector<int> col;
	vector<int> match;
	vector<int> sum;
	vector<int> mx;
	vector<int> cnt;
	vector<Q> q;
};

void printstate(const State &state) {
	REP(i,state.n) {
		int col=state.col[i];
		if(col!=-1) { printf(" %d",col); assert(state.match[i]==-1); continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			printf(" [sum=%d,mx=%d]",state.sum[i],state.mx[i]);
		} else if(i<state.match[i]) {
			printf(" [%d:sum=%d,mx=%d",i,state.sum[i],state.mx[i]);
		} else {
			printf(" :%d]",state.match[i]);
		}
	}
	REPSZ(i,state.q) printf(" (%d:%d=%d)",state.q[i].id,state.q[i].pos,state.q[i].col);
}

State reduce(State state,int l,int r) {
	//printf("\treduce(%d..%d):",l,r); printstate(state); puts("");
	vector<bool> done(state.ncol,true);
	vector<bool> used(state.n,false);
	FORE(i,l,r) { int pos=state.q[i].pos,ocol=state.col[pos],ncol=state.q[i].col; assert(ocol!=-1); done[ocol]=done[ncol]=false; used[pos]=true; }
	vector<int> fst(state.ncol,INT_MAX),lst(state.ncol,INT_MIN);
	REP(i,state.n) { int col=state.col[i]; if(col!=-1&&!used[i]) fst[col]=min(fst[col],i),lst[col]=max(lst[col],i); }
	//REP(i,state.ncol) if(state.cnt[i]!=0) printf("\t\t%d: %d %d %d %d\n",i,done[i]?1:0,fst[i],lst[i],state.cnt[i]);
	vector<bool> alive(state.n,true);
	REP(i,state.n) {
		int col=state.col[i];
		if(col==-1||used[i]) continue;
		if(i!=fst[col]&&i!=lst[col]) { alive[i]=false; continue; }
		if(!done[col]) continue;
		state.col[i]=-1;
		state.match[i]=fst[col]+lst[col]-i;
		if(i==fst[col]) state.sum[i]=state.mx[i]=state.cnt[col];
	}
	int bal=0,fstidx=-1,mx=0,cntalivebetween=0;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { if(bal!=0) ++cntalivebetween; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]==i) {
			if(bal==0) {
				//nothing
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		} else if(i<state.match[i]) {
			if(bal==0) {
				fstidx=i,mx=state.mx[i],cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
			++bal;
		} else {
			--bal;
			if(bal==0) {
				if(cntalivebetween==0) {
					state.match[fstidx]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
					alive[i]=false;
				} else {
					state.match[fstidx]=i,state.match[i]=fstidx,state.sum[fstidx]=state.mx[fstidx]=mx;
				}
				fstidx=-1,mx=0,cntalivebetween=0;
			} else {
				mx=max(mx,state.mx[i]);
				alive[i]=false;
			}
		}
	}
	int reuseidx=-1;
	REP(i,state.n) if(alive[i]) {
		if(state.col[i]!=-1) { reuseidx=-1; continue; }
		assert(state.match[i]!=-1);
		if(state.match[i]!=i) { reuseidx=-1; continue; }
		if(reuseidx==-1) { reuseidx=i; continue; }
		state.mx[reuseidx]=max(state.mx[reuseidx],state.mx[i]);
		state.sum[reuseidx]+=state.sum[i];
		alive[i]=false;
	}

	State ret;
	vector<int> posmp(state.n,-1); ret.n=0; REP(i,state.n) if(alive[i]) posmp[i]=ret.n++;
	vector<int> colmp(state.ncol,-1); ret.ncol=0; REP(i,state.ncol) if(!done[i]) colmp[i]=ret.ncol++;
	ret.col=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.col[i]!=-1) ret.col[posmp[i]]=colmp[state.col[i]];
	ret.match=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1) ret.match[posmp[i]]=posmp[state.match[i]];
	ret.sum=ret.mx=vector<int>(ret.n,-1); REP(i,state.n) if(alive[i]&&state.match[i]!=-1&&i<=state.match[i]) ret.sum[posmp[i]]=state.sum[i],ret.mx[posmp[i]]=state.mx[i];
	FORE(i,l,r) { int pos=state.q[i].pos,col=state.q[i].col,id=state.q[i].id; ret.q.PB(Q(posmp[pos],colmp[col],id)); }
	REP(i,ret.n) if(ret.col[i]!=-1) ret.sum[i]=1;
	ret.cnt=vector<int>(ret.ncol,0); REP(i,state.ncol) if(!done[i]) ret.cnt[colmp[i]]=state.cnt[i];
	//printf("\t->"); printstate(ret); puts("");
	return ret;
}

void apply(State &state,const Q &q) {
	int pos=q.pos,ocol=state.col[pos],ncol=q.col; assert(ocol!=-1); state.col[pos]=ncol; --state.cnt[ocol],++state.cnt[ncol]; //printf("\tchange %d from %d to %d\n",pos,ocol,ncol);
}

int calc(State &state) {
	assert(state.n==1&&state.col[0]==-1);
	return state.sum[0];
}

int ans[MAXQ+1];

void rec(State &state) {
	//printf("rec:"); printstate(state); puts("");
	static int xxx=0; if(++xxx>=20) exit(0);
	if(SZ(state.q)==1) {
		if(state.q[0].id==0) {
			State tmp=reduce(state,0,-1);
			//printf("at start:"); printstate(tmp); puts("");
			ans[0]=calc(tmp);
		}
		apply(state,state.q[0]);
		State res=reduce(state,0,-1);
		//printf("after %d:",state.q[0].id); printstate(res); puts("");
		ans[state.q[0].id+1]=calc(res);
		return;
	}
	int m=SZ(state.q)/2;
	State lstate=reduce(state,0,m-1);
	rec(lstate);
	REP(i,m) apply(state,state.q[i]);
	State rstate=reduce(state,m,SZ(state.q)-1);
	rec(rstate);
}

State sstate;

void solve() {
	State state=sstate;
	rec(state);
	REPE(i,SZ(sstate.q)) ans[i]=sstate.n-ans[i];
}

void run() {
	int nq; scanf("%d%d",&sstate.n,&nq); sstate.ncol=MAXCOL;
	sstate.col=vector<int>(sstate.n); REP(i,sstate.n) { int col; scanf("%d",&col); --col; sstate.col[i]=col; }
	sstate.sum=sstate.match=sstate.mx=vector<int>(sstate.n,-1); sstate.cnt=vector<int>(MAXCOL,0); REP(i,sstate.n) ++sstate.cnt[sstate.col[i]];
	sstate.q.clear(); REP(i,nq) { int pos,col; scanf("%d%d",&pos,&col); --pos,--col; sstate.q.PB(Q(pos,col,i)); }
	solve();
	REPE(i,nq) printf("%d\n",ans[i]);
}

int main() {
	run();
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

struct simp_t
{
	int dat[524288];

	void upd(int id, int v)
	{
		id += 262144;
		dat[id] = v;
		while(id > 1) {
			id >>= 1;
			dat[id] = max(dat[id << 1], dat[id << 1 | 1]);
		}
	}

	int rmq(int l, int r)
	{
		l += 262144;
		r += 262144;
		int ret = 0;
		while(l < r) {
			if(l & 1) ret = max(ret, dat[l]);
			if(!(r & 1)) ret = max(ret, dat[r]);
			l = l + 1 >> 1;
			r = r - 1 >> 1;
		}
		if(l == r) ret = max(ret, dat[l]);
		return ret;
	}
}cmin;

int rmq[524288], cnt[524288], lpos[524288], rpos[524288];
int tag[524288];

int armq[524288], alpos[524288], arpos[524288], acnt[524288];

struct segt
{
	void init()
	{
		rep(i, 262144) {
			cnt[262144 + i] = 0;
			lpos[262144 + i] = rpos[262144 + i] = i;
		}
		for(int i = 262143; i >= 1; i --) pushup(i);
	}

	void pushdown(int cur)
	{
		rmq[cur << 1] += tag[cur];
		tag[cur << 1] += tag[cur];
		rmq[cur << 1 | 1] += tag[cur];
		tag[cur << 1 | 1] += tag[cur];
		tag[cur] = 0;
	}

	void pushup(int cur, int* rmq = rmq, int* cnt = cnt, int* lpos = lpos, int* rpos = rpos)
	{
		rmq[cur] = min(rmq[cur << 1], rmq[cur << 1 | 1]);
		if(rmq[cur << 1 | 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1];
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1];
		} else if(rmq[cur << 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1 | 1];
			lpos[cur] = lpos[cur << 1 | 1];
			rpos[cur] = rpos[cur << 1 | 1];
		} else {
			cnt[cur] = cnt[cur << 1] + cnt[cur << 1 | 1] + cmin.rmq(rpos[cur << 1], lpos[cur << 1 | 1] - 1);
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1 | 1];
		}
	}

	void add(int l, int r, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			tag[cur] += v;
			rmq[cur] += v;
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(l <= mid) add(l, min(mid, r), v, cur << 1, cl, mid);
		if(r > mid) add(max(mid + 1, l), r, v, cur << 1 | 1, mid + 1, cr);
		pushup(cur);
	}

	void uwei(int id, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(id == cl && id == cr) {
			cmin.upd(id, v);
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(id <= mid) uwei(id, v, cur << 1, cl, mid);
		else uwei(id, v, cur << 1 | 1, mid + 1, cr);
		pushup(cur);
	}

	void query(int l, int r, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			armq[cur] = rmq[cur];
			acnt[cur] = cnt[cur];
			alpos[cur] = lpos[cur];
			arpos[cur] = rpos[cur];
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		armq[cur << 1] = armq[cur << 1 | 1] = INF;
		if(r <= mid) query(l, min(mid, r), cur << 1, cl, mid);
		else if(l > mid) query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		else {
			int minvr, cntvr;
			query(l, min(mid, r), cur << 1, cl, mid);
			query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		}
		pushup(cur, armq, acnt, alpos, arpos);
	}
}tre;

int n, q;
int a[200005];

set<int> S[200005];

void update(const set<int>& cs, int coef)
{
	if(!cs.empty()) {
		if(coef == -1) tre.uwei(*(cs.begin()), 0);
		else tre.uwei(*(cs.begin()), cs.size());
	}
	if(cs.size() >= 2) tre.add(*(cs.begin()) + 1, *(cs.rbegin()), coef);
}

int query()
{
	tre.query(1, n);
	return n - acnt[1] - cmin.rmq(1, alpos[1] - 1) - cmin.rmq(arpos[1], n);
}

int main()
{
	scanf("%d%d", &n, &q);
	rep1(i, n) {
		scanf("%d", &a[i]);
		S[a[i]].insert(i);
	}

	tre.init();
	rep1(i, 200000) update(S[i], 1);

	printf("%d\n", query());

	rep1(i, q) {
		int id, v;
		scanf("%d%d", &id, &v);
		update(S[a[id]], -1);
		update(S[v], -1);
		S[a[id]].erase(id);
		S[v].insert(id);
		update(S[a[id]], 1);
		update(S[v], 1);
		a[id] = v;
		printf("%d\n", query());
	}
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

struct simp_t
{
	int dat[524288];

	void upd(int id, int v)
	{
		id += 262144;
		dat[id] = v;
		while(id > 1) {
			id >>= 1;
			dat[id] = max(dat[id << 1], dat[id << 1 | 1]);
		}
	}

	int rmq(int l, int r)
	{
		l += 262144;
		r += 262144;
		int ret = 0;
		while(l < r) {
			if(l & 1) ret = max(ret, dat[l]);
			if(!(r & 1)) ret = max(ret, dat[r]);
			l = l + 1 >> 1;
			r = r - 1 >> 1;
		}
		if(l == r) ret = max(ret, dat[l]);
		return ret;
	}
}cmin;

int rmq[524288], cnt[524288], lpos[524288], rpos[524288];
int tag[524288];

int armq[524288], alpos[524288], arpos[524288], acnt[524288];

struct segt
{
	void init()
	{
		rep(i, 262144) {
			cnt[262144 + i] = 0;
			lpos[262144 + i] = rpos[262144 + i] = i;
		}
		for(int i = 262143; i >= 1; i --) pushup(i);
	}

	void pushdown(int cur)
	{
		rmq[cur << 1] += tag[cur];
		tag[cur << 1] += tag[cur];
		rmq[cur << 1 | 1] += tag[cur];
		tag[cur << 1 | 1] += tag[cur];
		tag[cur] = 0;
	}

	void pushup(int cur, int* rmq = rmq, int* cnt = cnt, int* lpos = lpos, int* rpos = rpos)
	{
		rmq[cur] = min(rmq[cur << 1], rmq[cur << 1 | 1]);
		if(rmq[cur << 1 | 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1];
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1];
		} else if(rmq[cur << 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1 | 1];
			lpos[cur] = lpos[cur << 1 | 1];
			rpos[cur] = rpos[cur << 1 | 1];
		} else {
			cnt[cur] = cnt[cur << 1] + cnt[cur << 1 | 1] + cmin.rmq(rpos[cur << 1], lpos[cur << 1 | 1] - 1);
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1 | 1];
		}
	}

	void add(int l, int r, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			tag[cur] += v;
			rmq[cur] += v;
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(l <= mid) add(l, min(mid, r), v, cur << 1, cl, mid);
		if(r > mid) add(max(mid + 1, l), r, v, cur << 1 | 1, mid + 1, cr);
		pushup(cur);
	}

	void uwei(int id, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(id == cl) {
			cmin.upd(id, v);
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(id <= mid) uwei(id, v, cur << 1, cl, mid);
		else uwei(id, v, cur << 1, mid + 1, cr);
	}

	void query(int l, int r, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			armq[cur] = rmq[cur];
			acnt[cur] = cnt[cur];
			alpos[cur] = lpos[cur];
			arpos[cur] = rpos[cur];
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		armq[cur << 1] = armq[cur << 1 | 1] = INF;
		if(r <= mid) query(l, min(mid, r), cur << 1, cl, mid);
		else if(l > mid) query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		else {
			int minvr, cntvr;
			query(l, min(mid, r), cur << 1, cl, mid);
			query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		}
		pushup(cur, armq, acnt, alpos, arpos);
	}
}tre;

int n, q;
int a[200005];

set<int> S[200005];

int update(const set<int>& cs, int coef)
{
	if(!cs.empty()) {
		if(coef == 0) tre.uwei(*(cs.begin()), 0);
		else tre.uwei(*(cs.begin()), cs.size());
	}
	if(cs.size() >= 2) tre.add(*(cs.begin()) + 1, *(cs.rbegin()), coef);
}

int query()
{
	tre.query(1, n);
	return n - acnt[1] - cmin.rmq(1, alpos[1] - 1) - cmin.rmq(arpos[1], n);
}

int main()
{
	scanf("%d%d", &n, &q);
	rep1(i, n) {
		scanf("%d", &a[i]);
		S[a[i]].insert(i);
	}

	tre.init();
	rep1(i, 200000) update(S[i], 1);

	printf("%d\n", query());
	rep1(i, q) {
		int id, v;
		scanf("%d%d", &id, &v);
		update(S[a[id]], -1);
		update(S[v], -1);
		S[a[id]].erase(id);
		S[v].insert(id);
		update(S[a[id]], 1);
		update(S[v], 1);
		a[id] = v;
		printf("%d\n", query());
	}
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;

struct simp_t
{
	int dat[524288];

	void upd(int id, int v)
	{
		id += 262144;
		dat[id] = v;
		while(id > 1) {
			id >>= 1;
			dat[id] = max(dat[id << 1], dat[id << 1 | 1]);
		}
	}

	int rmq(int l, int r)
	{
		l += 262144;
		r += 262144;
		int ret = 0;
		while(l < r) {
			if(l & 1) ret = max(ret, dat[l]);
			if(!(r & 1)) ret = max(ret, dat[r]);
			l = l + 1 >> 1;
			r = r - 1 >> 1;
		}
		if(l == r) ret = max(ret, dat[l]);
		return ret;
	}
}cmin;

int rmq[524288], cnt[524288], lpos[524288], rpos[524288];
int tag[524288];

int armq[524288], alpos[524288], arpos[524288], acnt[524288];

struct segt
{
	void init()
	{
		rep(i, 262144) {
			cnt[262144 + i] = 0;
			lpos[262144 + i] = rpos[262144 + i] = i;
		}
		for(int i = 262143; i >= 1; i --) pushup(i);
	}

	void pushdown(int cur)
	{
		rmq[cur << 1] += tag[cur];
		tag[cur << 1] += tag[cur];
		rmq[cur << 1 | 1] += tag[cur];
		tag[cur << 1 | 1] += tag[cur];
		tag[cur] = 0;
	}

	void pushup(int cur, int* rmq = rmq, int* cnt = cnt, int* lpos = lpos, int* rpos = rpos)
	{
		rmq[cur] = min(rmq[cur << 1], rmq[cur << 1 | 1]);
		if(rmq[cur << 1 | 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1];
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1];
		} else if(rmq[cur << 1] != rmq[cur]) {
			cnt[cur] = cnt[cur << 1 | 1];
			lpos[cur] = lpos[cur << 1 | 1];
			rpos[cur] = rpos[cur << 1 | 1];
		} else {
			cnt[cur] = cnt[cur << 1] + cnt[cur << 1 | 1] + cmin.rmq(rpos[cur << 1], lpos[cur << 1 | 1] - 1);
			lpos[cur] = lpos[cur << 1];
			rpos[cur] = rpos[cur << 1 | 1];
		}
	}

	void add(int l, int r, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			tag[cur] += v;
			rmq[cur] += v;
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(l <= mid) add(l, min(mid, r), v, cur << 1, cl, mid);
		if(r > mid) add(max(mid + 1, l), r, v, cur << 1 | 1, mid + 1, cr);
		pushup(cur);
	}

	void uwei(int id, int v, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(id == cl && id == cr) {
			cmin.upd(id, v);
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		if(id <= mid) uwei(id, v, cur << 1, cl, mid);
		else uwei(id, v, cur << 1 | 1, mid + 1, cr);
		pushup(cur);
	}

	void query(int l, int r, int cur = 1, int cl = 0, int cr = 262143)
	{
		if(l == cl && r == cr) {
			armq[cur] = rmq[cur];
			acnt[cur] = cnt[cur];
			alpos[cur] = lpos[cur];
			arpos[cur] = rpos[cur];
			return;
		}
		pushdown(cur);
		int mid = cl + cr >> 1;
		armq[cur << 1] = armq[cur << 1 | 1] = INF;
		if(r <= mid) query(l, min(mid, r), cur << 1, cl, mid);
		else if(l > mid) query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		else {
			int minvr, cntvr;
			query(l, min(mid, r), cur << 1, cl, mid);
			query(max(mid + 1, l), r, cur << 1 | 1, mid + 1, cr);
		}
		pushup(cur, armq, acnt, alpos, arpos);
	}
}tre;

int n, q;
int a[200005];

set<int> S[200005];

void update(const set<int>& cs, int coef)
{
	if(!cs.empty()) {
		if(coef == -1) tre.uwei(*(cs.begin()), 0);
		else tre.uwei(*(cs.begin()), cs.size());
	}
	if(cs.size() >= 2) tre.add(*(cs.begin()) + 1, *(cs.rbegin()), coef);
}

int query()
{
	tre.query(1, n);
	cout << acnt[1] << ' ' << alpos[1] << ' ' << arpos[1] << endl;
	return n - acnt[1] - cmin.rmq(1, alpos[1] - 1) - cmin.rmq(arpos[1], n);
}

int main()
{
	scanf("%d%d", &n, &q);
	rep1(i, n) {
		scanf("%d", &a[i]);
		S[a[i]].insert(i);
	}

	tre.init();
	rep1(i, 200000) update(S[i], 1);

	printf("%d\n", query());

	rep1(i, q) {
		int id, v;
		scanf("%d%d", &id, &v);
		update(S[a[id]], -1);
		update(S[v], -1);
		S[a[id]].erase(id);
		S[v].insert(id);
		update(S[a[id]], 1);
		update(S[v], 1);
		a[id] = v;
		printf("%d\n", query());
	}
	return 0;
}


#pragma GCC optimize("O3")
#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;
// gp_hash_table<int, int> mapka;

using namespace std;
#define PB push_back
#define MP make_pair
#define LL long long
#define int LL
#define FOR(i,a,b) for(int i = (a); i <= (b); i++)
#define RE(i,n) FOR(i,1,n)
#define REP(i,n) FOR(i,0,(int)(n)-1)
#define R(i,n) REP(i,n)
#define VI vector<int>
#define PII pair<int,int>
#define LD long double
#define FI first
#define SE second
#define st FI
#define nd SE
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())

template<class C> void mini(C &a4, C b4) { a4 = min(a4, b4); }
template<class C> void maxi(C &a4, C b4) { a4 = max(a4, b4); }

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<'='<<h<<','; _dbg(sdbg+1, a...);
}

template<class T> ostream &operator<<(ostream& os, vector<T> V) {
  os << "["; for (auto vv : V) os << vv << ","; return os << "]";
}
template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
  return os << "(" << P.st << "," << P.nd << ")";
}

#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

const int MAX=200100;
set<int> gd[MAX];
struct node{
  int cal;
  int naj;
  int najpref;
  int najsuf;
  int pref;
  int suf;
  bool ok;
}dp[1<<19];
int t[MAX];
int n,nn,q;

void ak(int v){
  int sze = 1;
  while(v != 1){
    v /= 2;
    dp[v].naj = max(dp[v * 2].naj, dp[v*2+1].naj);
    dp[v].cal = 0;
    dp[v].ok = 0;
    dp[v].najpref = 0;
    dp[v].najsuf = 0;
    dp[v].pref = dp[v*2].pref;
    dp[v].suf = dp[v*2+1].suf;
    if(dp[v * 2].suf > sze){
      maxi(dp[v].suf,dp[v*2].suf - sze);
      maxi(dp[v].najsuf,max(dp[v*2+1].naj,dp[v*2].najsuf));
    }else{
      if(dp[v * 2 + 1].pref <= sze){
        if(dp[v*2].ok && dp[v*2+1].ok){
          dp[v].cal += max(dp[v*2+1].najpref,dp[v*2].najsuf);
        }
        if(!dp[v*2].ok){
          maxi(dp[v].najpref, max(dp[v*2+1].najpref,dp[v*2].najsuf));
        }
        if(!dp[v*2+1].ok){
          maxi(dp[v].najsuf, max(dp[v*2+1].najpref,dp[v*2].najsuf));
        }
      }
      dp[v].ok |= dp[v*2+1].ok;
      dp[v].cal += dp[v*2+1].cal;
      maxi(dp[v].najsuf, dp[v*2+1].najsuf);
    }
    if(dp[v * 2 + 1].pref > sze){
      maxi(dp[v].pref,dp[v*2+1].pref - sze);
      maxi(dp[v].najpref,max(dp[v*2].naj,dp[v*2+1].najpref));
    }else{
      dp[v].ok |= dp[v*2].ok;
      dp[v].cal += dp[v*2].cal;
      maxi(dp[v].najpref, dp[v*2].najpref);
    }
    debug(v, dp[v].cal, dp[v].naj, dp[v].najpref, dp[v].najsuf, dp[v].pref, dp[v].suf, dp[v].ok);
    sze *= 2;
  }
}

void dodaj(int i){
  int kr = SZ(gd[i]);
  if(!kr)return;
  int a = *gd[i].begin();
  if(kr == 1){
    dp[a + nn] = {1,1,0,0,0,0,true};
    ak(a + nn);
  }else{
    int b = *gd[i].rbegin();
    dp[a + nn] = {0,kr,0,kr,0,b-a,true};
    dp[b + nn] = {0,kr,kr,0,b - a,0,true};
    ak(a + nn);
    ak(b + nn);
  }
}

void us(int i){
  node empty = {0,0,0,0,0,0,false};
  int kr = SZ(gd[i]);
  if(!kr)return;
  int a = *gd[i].begin();
  if(kr == 1){
    dp[a + nn] = empty;
    ak(a + nn);
  }else{
    int b = *gd[i].rbegin();
    dp[a + nn] = empty;
    dp[b + nn] = empty;
    ak(a + nn);
    ak(b + nn);
  }
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(11);
  cerr << fixed << setprecision(6);
  cin >> n >> q;
  nn = 1;while(nn <= n) nn *= 2;
  R(i,n){
    cin >> t[i];
    gd[t[i]].insert(i);
  }
  R(i,MAX)dodaj(i);
  cout << n - dp[1].cal << "\n";
  R(i,q){
    int a,v;
    cin >> a >> v;a--;
    us(t[a]);
    gd[t[a]].erase(a);
    dodaj(t[a]);
    us(v);
    t[a] = v;
    gd[v].insert(a);
    dodaj(v);
    cout << n - dp[1].cal << "\n";
  }
}


#include<bits/stdc++.h>
using namespace std;

int read(){
	int a = 0; char c = getchar(); bool f = 0;
	while(!isdigit(c)){f = c == '-'; c = getchar();}
	while(isdigit(c)){
		a = a * 10 + c - 48; c = getchar();
	}
	return f ? -a : a;
}

const int _ = 2e5 + 11;
struct DATA{
	int mn , mx , lftmx , rhtmx , sum , mrk;
	DATA(){mn = 0; lftmx = rhtmx = sum = mrk = 0;}
	friend DATA merge(DATA &p , DATA &q){
		DATA t; t.mx = max(p.mx , q.mx);
		if(p.mn == q.mn){
			t.lftmx = p.lftmx; t.rhtmx = q.rhtmx;
			t.mn = p.mn; t.sum = p.sum + q.sum + max(p.rhtmx , q.lftmx);
		}
		else if(p.mn < q.mn){t.mn = p.mn; t.sum = p.sum; t.lftmx = p.lftmx; t.rhtmx = max(p.rhtmx , q.mx);}
		else{t.mn = q.mn; t.sum = q.sum; t.lftmx = max(p.mx , q.lftmx); t.rhtmx = q.rhtmx;}
		return t;
	}

	void mark(int x){mrk += x; mn += x;}
};
namespace segt{
	DATA now[_ << 3];

#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)

	void down(int x){now[lch].mark(now[x].mrk); now[rch].mark(now[x].mrk); now[x].mrk = 0;}

	void M1(int x , int l , int r , int L , int R , int val){
		if(l >= L && r <= R) return now[x].mark(val);
		down(x); if(mid >= L) M1(lch , l , mid , L , R , val);
		if(mid < R) M1(rch , mid + 1 , r , L , R , val);
		now[x] = merge(now[lch] , now[rch]);
	}

	void M2(int x , int l , int r , int tar , int val){
		if(l == r){now[x].mx = val; return;}
		down(x); mid >= tar ? M2(lch , l , mid , tar , val) : M2(rch , mid + 1 , r , tar , val);
		now[x] = merge(now[lch] , now[rch]);
	}
}
int N , Q , arr[_]; set < int > pos[_];

int main(){
	N = read(); Q = read(); for(int i = 1 ; i <= N ; ++i) pos[arr[i] = read()].insert(i);
	for(int i = 1 ; i <= 200000 ; ++i)
		if(pos[i].size()){
			segt::M2(1 , 1 , 2 * N + 1 , 2 * (*pos[i].begin()) , pos[i].size());
			segt::M1(1 , 1 , 2 * N + 1 , 2 * (*pos[i].begin()) , 2 * (*--pos[i].end()) , 1);
		}
	printf("%d\n" , N - segt::now[1].sum);
	while(Q--){
		int p = read() , x = read() , t = arr[p];

		if(pos[t].size() != 1)
			if(p == *pos[t].begin()){
				segt::M2(1 , 1 , 2 * N + 1 , 2 * p , 0);
				segt::M2(1 , 1 , 2 * N + 1 , 2 * (*++pos[t].begin()) , pos[t].size() - 1);
				segt::M1(1 , 1 , 2 * N + 1 , 2 * p , 2 * (*++pos[t].begin()) - 1 , -1);
			}
			else{
				if(p == *--pos[t].end())
					segt::M1(1 , 1 , 2 * N + 1 , 2 * (*----pos[t].end()) + 1 , 2 * (*--pos[t].end()) , -1);
				segt::M2(1 , 1 , 2 * N + 1 , 2 * (*pos[t].begin()) , pos[t].size() - 1);
			}
		else{
			segt::M2(1 , 1 , 2 * N + 1 , 2 * p , 0);
			segt::M1(1 , 1 , 2 * N + 1 , 2 * p , 2 * p , -1);
		}

		pos[t].erase(p); pos[arr[p] = x].insert(p);

		if(pos[x].size() != 1)
			if(p == *pos[x].begin()){
				segt::M2(1 , 1 , 2 * N + 1 , 2 * p , pos[x].size());
				segt::M2(1 , 1 , 2 * N + 1 , 2 * (*++pos[x].begin()) , 0);
				segt::M1(1 , 1 , 2 * N + 1 , 2 * p , 2 * (*++pos[x].begin()) - 1 , 1);
			}
			else{
				if(p == *--pos[x].end())
					segt::M1(1 , 1 , 2 * N + 1 , 2 * (*----pos[x].end()) + 1 , 2 * (*--pos[x].end()) , 1);
				segt::M2(1 , 1 , 2 * N + 1 , 2 * (*pos[x].begin()) , pos[x].size());
			}
		else{
			segt::M2(1 , 1 , 2 * N + 1 , 2 * p , 1);
			segt::M1(1 , 1 , 2 * N + 1 , 2 * p , 2 * p , 1);
		}
		printf("%d\n" , N - segt::now[1].sum);
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define N 300000
#define ls (x<<1)
#define rs (x<<1|1)

int n,m,a[N];
set<int> se[N];

struct node{
	int p1,p2,sum,val;
	node(int a=0,int b=0,int c=0,int d=0):p1(a),p2(b),sum(c),val(d){}
}seg[N<<2];

void MAX(int &x,int y){x=max(x,y);}

void merge(node &p,int x,int l,int r){
	if (!seg[x].p1) return;
	if (l==r){
		if (p.p2>=l){
			MAX(p.p2,seg[x].p2);
			p.val=max(p.val,seg[x].val);
		}
		else{
			p.p1=seg[x].p1;
			p.p2=seg[x].p2;
			p.sum+=p.val;
			p.val=seg[x].val;
		}
		return;
	}
	int mid=(l+r)>>1;
	if (p.p2>=seg[ls].p1){
		MAX(p.p2,seg[ls].p2);
		MAX(p.val,seg[ls].val);
		merge(p,rs,mid+1,r);
	}
	else{
		merge(p,ls,l,mid);
		p.sum+=seg[x].sum-seg[ls].sum;
		p.p1=seg[x].p1;
		p.p2=seg[x].p2;
		p.val=seg[x].val;
	}
}

void mdf(int x,int l,int r,int t,int k,int o){
	if (l==r){seg[x]=node(t*(k>0),k,0,o); return;}
	int mid=(l+r)>>1;
	if (t<=mid) mdf(ls,l,mid,t,k,o);
	else mdf(rs,mid+1,r,t,k,o);
	seg[x]=seg[ls];
	merge(seg[x],rs,mid+1,r);
}

void ers(int i){
	int c=a[i];
	mdf(1,1,n,*se[c].begin(),0,0);
	se[c].erase(i);
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

void ins(int i){
	int c=a[i];
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),0,0);
	se[c].insert(i);
	mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;++i){
		scanf("%d",a+i);
		se[a[i]].insert(i);
	}
	for (int i=1;i<=200000;++i){
		if (se[i].empty()) continue;
		int x=*se[i].begin(),y=*se[i].rbegin(),z=se[i].size();
		mdf(1,1,n,x,y,z);
	}
	printf("%d\n",n-seg[1].sum-seg[1].val);
	for (int i=1;i<=m;++i){
		int x,y; scanf("%d%d",&x,&y);
		ers(x); a[x]=y; ins(x);
		printf("%d\n",n-seg[1].sum-seg[1].val);
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define N 300000
#define ls (x<<1)
#define rs (x<<1|1)

int n,m,a[N];
set<int> se[N];

struct node{
	int p1,p2,sum,val,all;
	node(int a=0,int b=0,int c=0,int d=0):p1(a),p2(b),sum(c),val(d),all(d){}
}seg[N<<2];

void MAX(int &x,int y){x=max(x,y);}

void merge(node &p,int x,int l,int r){
	if (!seg[x].p1) return;
	if (l==r){
		if (p.p2>=seg[x].p1){
			MAX(p.p2,seg[x].p2);
			MAX(p.val,seg[x].all);
		}
		else{
			p.p1=seg[x].p1;
			p.p2=seg[x].p2;
			p.sum+=p.val;
			p.val=seg[x].val;
		}
		return;
	}
	int mid=(l+r)>>1;
	if (p.p2>=seg[ls].p1){
		MAX(p.p2,seg[ls].p2);
		MAX(p.val,seg[ls].all);
		merge(p,rs,mid+1,r);
	}
	else{
		merge(p,ls,l,mid);
		p.p1=seg[x].p1;
		p.p2=seg[x].p2;
		p.sum+=seg[x].sum-seg[ls].sum;
		p.val=seg[x].val;
	}
}

void mdf(int x,int l,int r,int t,int k,int o){
	if (l==r){seg[x]=node(t*(k>0),k,0,o); return;}
	int mid=(l+r)>>1;
	if (t<=mid) mdf(ls,l,mid,t,k,o);
	else mdf(rs,mid+1,r,t,k,o);
	seg[x]=seg[ls];
	merge(seg[x],rs,mid+1,r);
	seg[x].all=max(seg[ls].all,seg[rs].all);
}

void ers(int i){
	int c=a[i];
	mdf(1,1,n,*se[c].begin(),0,0);
	se[c].erase(i);
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

void ins(int i){
	int c=a[i];
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),0,0);
	se[c].insert(i);
	mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;++i){
		scanf("%d",a+i);
		se[a[i]].insert(i);
	}
	for (int i=1;i<=200000;++i){
		if (se[i].empty()) continue;
		int x=*se[i].begin(),y=*se[i].rbegin(),z=se[i].size();
		mdf(1,1,n,x,y,z);
	}
	printf("%d\n",n-seg[1].sum-seg[1].val);
	for (int i=1;i<=m;++i){
		int x,y; scanf("%d%d",&x,&y);
		ers(x); a[x]=y; ins(x);
		printf("%d\n",n-seg[1].sum-seg[1].val);
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define N 300000
#define ls (x<<1)
#define rs (x<<1|1)

int n,m,a[N];
set<int> se[N];

struct node{
	int p1,p2,sum,val;
	node(int a=0,int b=0,int c=0,int d=0):p1(a),p2(b),sum(c),val(d){}
}seg[N<<2];

void MAX(int &x,int y){x=max(x,y);}

void merge(node &p,int x,int l,int r){
	if (!seg[x].p1) return;
	if (l==r){
		if (p.p2>=seg[x].p1){
			MAX(p.p2,seg[x].p2);
			MAX(p.val,seg[x].val);
		}
		else{
			p.p1=seg[x].p1;
			p.p2=seg[x].p2;
			p.sum+=p.val;
			p.val=seg[x].val;
		}
		return;
	}
	int mid=(l+r)>>1;
	if (p.p2>=seg[ls].p1){
		MAX(p.p2,seg[ls].p2);
		MAX(p.val,seg[ls].val);
		merge(p,rs,mid+1,r);
	}
	else{
		merge(p,ls,l,mid);
		p.p1=seg[x].p1;
		p.p2=seg[x].p2;
		p.sum+=seg[x].sum-seg[ls].sum;
		p.val=seg[x].val;
	}
}

void mdf(int x,int l,int r,int t,int k,int o){
	if (l==r){seg[x]=node(t*(k>0),k,0,o); return;}
	int mid=(l+r)>>1;
	if (t<=mid) mdf(ls,l,mid,t,k,o);
	else mdf(rs,mid+1,r,t,k,o);
	seg[x]=seg[ls];
	merge(seg[x],rs,mid+1,r);
}

void ers(int i){
	int c=a[i];
	mdf(1,1,n,*se[c].begin(),0,0);
	se[c].erase(i);
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

void ins(int i){
	int c=a[i];
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),0,0);
	se[c].insert(i);
	mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;++i){
		scanf("%d",a+i);
		se[a[i]].insert(i);
	}
	for (int i=1;i<=200000;++i){
		if (se[i].empty()) continue;
		int x=*se[i].begin(),y=*se[i].rbegin(),z=se[i].size();
		mdf(1,1,n,x,y,z);
	}
	printf("%d\n",n-seg[1].sum-seg[1].val);
	for (int i=1;i<=m;++i){
		int x,y; scanf("%d%d",&x,&y);
		ers(x); a[x]=y; ins(x);
		printf("%d\n",n-seg[1].sum-seg[1].val);
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define N 300000
#define ls (x<<1)
#define rs (x<<1|1)

int n,m,a[N];
set<int> se[N];

struct node{
	int p1,p2,sum,val;
	node(int a=0,int b=0,int c=0,int d=0):p1(a),p2(b),sum(c),val(d){}
}seg[N<<2];

void MAX(int &x,int y){x=max(x,y);}

void merge(node &p,int x,int l,int r){
	if (!seg[x].p1) return;
	if (l==r){
		if (p.p2>=l){
			MAX(p.p2,seg[x].p2);
			p.val=max(p.val,seg[x].val);
		}
		else{
			p.p1=seg[x].p1;
			p.p2=seg[x].p2;
			p.sum+=p.val;
			p.val=seg[x].val;
		}
		return;
	}
	int mid=(l+r)>>1;
	if (p.p2>=seg[ls].p1){
		MAX(p.p2,seg[ls].p2);
		MAX(p.val,seg[ls].val);
		merge(p,rs,mid+1,r);
	}
	else{
		merge(p,ls,l,mid);
		p.sum+=seg[x].sum-seg[ls].sum;
		p.p1=seg[x].p1;
		p.p2=seg[x].p2;
		p.val=seg[x].val;
	}
}

void mdf(int x,int l,int r,int t,int k,int o){
	if (l==r){seg[x]=node(t,k,0,o); return;}
	int mid=(l+r)>>1;
	if (t<=mid) mdf(ls,l,mid,t,k,o);
	if (t>mid) mdf(rs,mid+1,r,t,k,o);
	seg[x]=seg[ls];
	merge(seg[x],rs,mid+1,r);
}

void ers(int i){
	int c=a[i];
	mdf(1,1,n,*se[c].begin(),0,0);
	se[c].erase(i);
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

void ins(int i){
	int c=a[i];
	if (se[c].size())
		mdf(1,1,n,*se[c].begin(),0,0);
	se[c].insert(i);
	mdf(1,1,n,*se[c].begin(),*se[c].rbegin(),se[c].size());
}

int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;++i){
		scanf("%d",a+i);
		se[a[i]].insert(i);
	}
	for (int i=1;i<=200000;++i){
		if (se[i].empty()) continue;
		int x=*se[i].begin(),y=*se[i].rbegin(),z=se[i].size();
		mdf(1,1,n,x,y,z);
	}
	printf("%d\n",n-seg[1].sum-seg[1].val);
	for (int i=1;i<=m;++i){
		int x,y; scanf("%d%d",&x,&y);
		ers(x); a[x]=y; ins(x);
		printf("%d\n",n-seg[1].sum-seg[1].val);
	}

	return 0;
}