#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
using namespace std;
//const int maxn = 100 + 10;
const int maxn = 200000 + 10;
const int maxt = maxn << 2;
const int INF = 0x3f3f3f3f;

int n, q, a[maxn], Mx, sz[maxn], val[maxn];
set<int> pos[maxn];
multiset<int> vmx[maxn];

//sgt
struct tnode{
	int ls, rs, mn, mxl, mxr, pl, pr, mx, lazy, sum;
	tnode() {}
	tnode(int val) {
		ls = rs = 0;
		mn = 0;
		mxl = mxr = 0;
		pl = pr = mx = 0;
		lazy = sum = 0;
	}
}t[maxt];
int rt, tcnt;

inline void pushup(int u, int l, int r) {
	int ls = t[u].ls, rs = t[u].rs;
	int mid = (l + r) >> 1;
	if(!ls && !rs) return;
	if(!rs) {
		t[u] = t[ls];
		return;
	}
	t[u].mx = max(val[mid + 1],max(t[ls].mx,t[rs].mx));
	t[u].mn = min(t[ls].mn,t[rs].mn);
	if(t[ls].mn == t[u].mn && t[rs].mn == t[u].mn) {
		t[u].pl = t[ls].pl;
		t[u].pr = t[rs].pr;
		t[u].mxl = t[ls].mxl;
		t[u].mxr = t[rs].mxr;
		int now = max(val[mid + 1],max(t[ls].mxr,t[rs].mxl));
		t[u].sum = t[ls].sum + t[rs].sum + now;
	}
	else {
		if(t[ls].mn == t[u].mn) {
			t[u].pl = t[ls].pl;
			t[u].pr = t[ls].pr;
      t[u].mxl = t[ls].mxl;
			t[u].mxr = max(t[ls].mxr,max(t[rs].mx,val[mid + 1]));
			t[u].sum = t[ls].sum;
		}
		else {
			t[u].pl = t[rs].pl;
			t[u].pr = t[rs].pr;
			t[u].mxl = max(t[rs].mxl,max(t[ls].mx,val[mid + 1]));
			t[u].mxr = t[rs].mxr;
			t[u].sum = t[rs].sum;
		}
	}
}

inline void tag(int u, int k) {
	t[u].mn += k;
	t[u].lazy += k;
}

inline void pushdown(int u) {
  int ls = t[u].ls, rs = t[u].rs;
	if(t[u].lazy != 0) {
		tag(ls,t[u].lazy);
		tag(rs,t[u].lazy);
		t[u].lazy = 0;
	}
}

void build(int &u, int l, int r) {
	u = ++ tcnt; t[u] = tnode(0);
	if(l == r) {
		t[u].mx = 0;
		t[u].pl = t[u].pr = l;
		t[u].mn = 0;
		t[u].mxl = val[l]; t[u].mxr = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(t[u].ls,l,mid);
	build(t[u].rs,mid + 1,r);
	pushup(u,l,r);
}

void updata1(int u, int l, int r, int p, int q, int k) {
	if(p > q) return;
	if(p <= l && r <= q) {
		tag(u,k);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(u);
	if(p <= mid) updata1(t[u].ls,l,mid,p,q,k);
	if(mid + 1 <= q) updata1(t[u].rs,mid + 1,r,p,q,k);
	pushup(u,l,r);
}

void updata2(int u, int l, int r, int p) {
	if(p < l || p > r) return;
	if(l == r) {
    t[u].mx = 0;
		t[u].mxl = val[l];
    t[u].mxr = 0;
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(u);
	if(p <= mid) updata2(t[u].ls,l,mid,p);
	else updata2(t[u].rs,mid + 1,r,p);
	pushup(u,l,r);
}

inline void prepare() {
	Mx = a[1];
	for(int i = 1;i <= n;i ++) {
		pos[a[i]].insert(i);
		Mx = max(Mx,a[i]);
		sz[a[i]] ++;
	}
	for(int i = 1;i <= n;i ++) {
		vmx[i].clear();
		vmx[i].insert(- INF);
	}
	for(int i = 1;i <= Mx;i ++) {
    int id = *(pos[i].begin());
    vmx[id].insert(sz[i]);
	}
	for(int i = 1;i <= n;i ++) {
		multiset<int>::iterator tmp = vmx[i].end();
		tmp --;
		val[i]= *tmp;
	}
	rt = tcnt = 0;
	build(rt,0,n);
	for(int i = 1;i <= Mx;i ++) {
		if(pos[i].size() <= 0) continue;
		set<int>::iterator tmp = pos[i].begin();
		int l = *tmp;
		tmp = pos[i].end(); tmp --;
		int r = *tmp;
		updata1(rt,0,n,l,r - 1,1);
	}
}

inline void work(int x, int y) {
	set<int>::iterator tmp = pos[a[x]].begin();
	multiset<int>::iterator now;
	int l = *tmp;
	tmp = pos[a[x]].end(); tmp --;
	int r = *tmp;
	now = vmx[l].find(sz[a[x]]);
	vmx[l].erase(now);
	sz[a[x]] --;
//	vmx[l].insert(sz[a[x]]);
	now = vmx[l].end(); now --;
	if(val[l] != *now) {
		val[l] = *now;
		updata2(rt,0,n,l);
		updata2(rt,0,n,l + 1);
	}

	pos[a[x]].erase(x);
	if(x == l || x == r) {
		updata1(rt,0,n,l,r - 1,-1);
		tmp = pos[a[x]].begin();
		l = *tmp;
		tmp = pos[a[x]].end();
		if(pos[a[x]].size() > 0) {
			tmp --;
			r = *tmp;
			updata1(rt,0,n,l,r - 1,1);
		}
		else r = -1;
	}
	if(r != -1) {
		vmx[l].insert(sz[a[x]]);
		now = vmx[l].end(); now --;
		if(val[l] != *now) {
			val[l] = *now;
			updata2(rt,0,n,l);
			updata2(rt,0,n,l + 1);
		}
	}

	if(sz[y] > 0) {
		tmp = pos[y].begin();
		l = *tmp;
		tmp = pos[y].end(); tmp --;
		r = *tmp;
		now = vmx[l].find(sz[y]);
		vmx[l].erase(now);
	}
	else l = -1;
	sz[y] ++;
//	vmx[l].insert(sz[y]);
	if(l != -1) {
		now = vmx[l].end(); now --;
		if(val[l] != *now) {
			val[l] = *now;
			updata2(rt,0,n,l);
			updata2(rt,0,n,l + 1);
		}
	}

	pos[y].insert(x);
	if(x < l || x > r || l == -1) {
		if(l != -1) updata1(rt,0,n,l,r - 1,-1);
		tmp = pos[y].begin();
		l = *tmp;
		tmp = pos[y].end(); tmp --;
		r = *tmp;
		updata1(rt,0,n,l,r - 1,1);
	}
	vmx[l].insert(sz[y]);
	now = vmx[l].end(); now --;
	if(val[l] != *now) {
		val[l] = *now;
		updata2(rt,0,n,l);
		updata2(rt,0,n,l + 1);
	}

	a[x] = y;
}

inline void solve() {
	int Ans = n - t[1].sum;
	printf("%d\n", Ans);
	for(int i = 1;i <= q;i ++) {
		int x, y;
		scanf("%d%d", &x, &y);
		work(x,y);
		Ans = n - t[1].sum;
		printf("%d\n", Ans);
	}
}

int main() {
//	freopen("data.in","r",stdin);
  scanf("%d%d", &n, &q);
	for(int i = 1;i <= n;i ++) scanf("%d", &a[i]);
  prepare();
	solve();
	return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
using namespace std;
//const int maxn = 100 + 10;
const int maxn = 200000 + 10;
const int maxt = maxn << 2;
const int INF = 0x3f3f3f3f;

int n, q, a[maxn], Mx, sz[maxn], val[maxn];
set<int> pos[maxn];
multiset<int> vmx[maxn];

//sgt
struct tnode{
	int ls, rs, mn, mxl, mxr, pl, pr, mx, lazy, sum;
	tnode() {}
	tnode(int val) {
		ls = rs = 0;
		mn = 0;
		mxl = mxr = 0;
		pl = pr = mx = 0;
		lazy = sum = 0;
	}
}t[maxt];
int rt, tcnt;

inline void pushup(int u, int l, int r) {
	int ls = t[u].ls, rs = t[u].rs;
	int mid = (l + r) >> 1;
	if(!ls && !rs) return;
	if(!rs) {
		t[u] = t[ls];
		return;
	}
	t[u].mx = max(val[mid + 1],max(t[ls].mx,t[rs].mx));
	t[u].mn = min(t[ls].mn,t[rs].mn);
	if(t[ls].mn == t[u].mn && t[rs].mn == t[u].mn) {
		t[u].pl = t[ls].pl;
		t[u].pr = t[rs].pr;
		t[u].mxl = t[ls].mxl;
		t[u].mxr = t[rs].mxr;
		int now = max(val[mid + 1],max(t[ls].mxr,t[rs].mxl));
		t[u].sum = t[ls].sum + t[rs].sum + now;
	}
	else {
		if(t[ls].mn == t[u].mn) {
			t[u].pl = t[ls].pl;
			t[u].pr = t[ls].pr;
      t[u].mxl = t[ls].mxl;
			t[u].mxr = max(t[ls].mxr,max(t[rs].mx,val[mid + 1]));
			t[u].sum = t[ls].sum;
		}
		else {
			t[u].pl = t[rs].pl;
			t[u].pr = t[rs].pr;
			t[u].mxl = max(t[rs].mxl,max(t[ls].mx,val[mid + 1]));
			t[u].mxr = t[rs].mxr;
			t[u].sum = t[rs].sum;
		}
	}
}

inline void tag(int u, int k) {
	t[u].mn += k;
	t[u].lazy += k;
}

inline void pushdown(int u) {
  int ls = t[u].ls, rs = t[u].rs;
	if(t[u].lazy != 0) {
		tag(ls,t[u].lazy);
		tag(rs,t[u].lazy);
		t[u].lazy = 0;
	}
}

void build(int &u, int l, int r) {
	u = ++ tcnt; t[u] = tnode(0);
	if(l == r) {
		t[u].mx = 0;
		t[u].pl = t[u].pr = l;
		t[u].mn = 0;
		t[u].mxl = val[l]; t[u].mxr = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(t[u].ls,l,mid);
	build(t[u].rs,mid + 1,r);
	pushup(u,l,r);
}

void updata1(int u, int l, int r, int p, int q, int k) {
	if(p > q) return;
	if(p <= l && r <= q) {
		tag(u,k);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(u);
	if(p <= mid) updata1(t[u].ls,l,mid,p,q,k);
	if(mid + 1 <= q) updata1(t[u].rs,mid + 1,r,p,q,k);
	pushup(u,l,r);
}

void updata2(int u, int l, int r, int p) {
	if(p < l || p > r) return;
	if(l == r) {
    t[u].mx = 0;
		t[u].mxl = val[l];
    t[u].mxr = 0;
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(u);
	if(p <= mid) updata2(t[u].ls,l,mid,p);
	else updata2(t[u].rs,mid + 1,r,p);
	pushup(u,l,r);
}

inline void prepare() {
	Mx = a[1];
	for(int i = 1;i <= n;i ++) {
		pos[a[i]].insert(i);
		Mx = max(Mx,a[i]);
		sz[a[i]] ++;
	}
	for(int i = 1;i <= n;i ++) {
		vmx[i].clear();
		vmx[i].insert(- INF);
	}
	for(int i = 1;i <= Mx;i ++) {
    int id = *(pos[i].begin());
    vmx[id].insert(sz[i]);
	}
	for(int i = 1;i <= n;i ++) {
		multiset<int>::iterator tmp = vmx[i].end();
		tmp --;
		val[i]= *tmp;
	}
	rt = tcnt = 0;
	build(rt,0,n);
	for(int i = 1;i <= Mx;i ++) {
		if(pos[i].size() <= 0) continue;
		set<int>::iterator tmp = pos[i].begin();
		int l = *tmp;
		tmp = pos[i].end(); tmp --;
		int r = *tmp;
		updata1(rt,0,n,l,r - 1,1);
	}
}

inline void work(int x, int y) {
	set<int>::iterator tmp = pos[a[x]].begin();
	multiset<int>::iterator now;
	int l = *tmp;
	tmp = pos[a[x]].end(); tmp --;
	int r = *tmp;
	now = vmx[l].find(sz[a[x]]);
	vmx[l].erase(now);
	sz[a[x]] --;
//	vmx[l].insert(sz[a[x]]);
	now = vmx[l].end(); now --;
	if(val[l] != *now) {
		val[l] = *now;
		updata2(rt,0,n,l);
		updata2(rt,0,n,l + 1);
	}

	pos[a[x]].erase(x);
	if(x == l || x == r) {
		updata1(rt,0,n,l,r - 1,-1);
		tmp = pos[a[x]].begin();
		l = *tmp;
		tmp = pos[a[x]].end();
		if(pos[a[x]].size() > 0) {
			tmp --;
			r = *tmp;
			updata1(rt,0,n,l,r - 1,1);
		}
		else r = -1;
	}
	if(r != -1) {
		vmx[l].insert(sz[a[x]]);
		now = vmx[l].end(); now --;
		if(val[l] != *now) {
			val[l] = *now;
			updata2(rt,0,n,l);
			updata2(rt,0,n,l + 1);
		}
	}

	if(sz[y] > 0) {
		tmp = pos[y].begin();
		l = *tmp;
		tmp = pos[y].end(); tmp --;
		r = *tmp;
		now = vmx[l].find(sz[y]);
		vmx[l].erase(now);
	}
	else l = -1;
	sz[y] ++;
//	vmx[l].insert(sz[y]);
	if(l != -1) {
		now = vmx[l].end(); now --;
		if(val[l] != *now) {
			val[l] = *now;
			updata2(rt,0,n,l);
			updata2(rt,0,n,l + 1);
		}
	}

	pos[y].insert(x);
	if(x < l || x > r || l == -1) {
		if(l != -1) updata1(rt,0,n,l,r - 1,-1);
		tmp = pos[y].begin();
		l = *tmp;
		tmp = pos[y].end(); tmp --;
		r = *tmp;
		updata1(rt,0,n,l,r - 1,1);
	}
	vmx[l].insert(sz[y]);
	now = vmx[l].end(); now --;
	if(val[l] != *now) {
		val[l] = *now;
		updata2(rt,0,n,l);
		updata2(rt,0,n,l + 1);
	}

	a[x] = y;
}

inline void solve() {
	int Ans = n - t[1].sum;
	printf("%d\n", Ans);
	for(int i = 1;i <= q;i ++) {
		int x, y;
		scanf("%d%d", &x, &y);
		work(x,y);
		Ans = n - t[1].sum;
		printf("%d\n", Ans);
	}
}

int main() {
	freopen("data.in","r",stdin);
  scanf("%d%d", &n, &q);
	for(int i = 1;i <= n;i ++) scanf("%d", &a[i]);
  prepare();
	solve();
	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> T gcd(T a, T b){return !b?a:gcd(b,a%b);}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
const int N = 233333;
int n,q,a[N];set<int>Set[N];
struct node{
	int mn,lzy,mx,lmx,rmx,ans;
}tree[N<<2];
void upd(int k){
	tree[k].mn=min(tree[k<<1].mn,tree[k<<1|1].mn);
	tree[k].mx=max(tree[k<<1].mx,tree[k<<1|1].mx);
	if(tree[k<<1].mn<tree[k<<1|1].mn){
		tree[k].ans=tree[k<<1].ans;tree[k].lmx=tree[k<<1].lmx;
		tree[k].rmx=max(tree[k<<1].rmx,tree[k<<1|1].mx);
	}
	else if(tree[k<<1].mn>tree[k<<1|1].mn){
		tree[k].ans=tree[k<<1|1].ans;tree[k].rmx=tree[k<<1|1].rmx;
		tree[k].lmx=max(tree[k<<1].mx,tree[k<<1|1].lmx);
	}
	else{
		tree[k].ans=tree[k<<1].ans+tree[k<<1|1].ans+max(tree[k<<1].rmx,tree[k<<1|1].lmx);
		tree[k].lmx=tree[k<<1].lmx;tree[k].rmx=tree[k<<1|1].rmx;
	}
}
void pushdown(int k){
	if(tree[k].lzy){
		tree[k<<1].lzy+=tree[k].lzy;tree[k<<1].mn+=tree[k].lzy;
		tree[k<<1|1].lzy+=tree[k].lzy;tree[k<<1|1].mn+=tree[k].lzy;
		tree[k].lzy=0;
	}
}
void mdy(int k, int l, int r, int x, int L, int R){
	if(l==L&&r==R){tree[k].mn+=x;tree[k].lzy+=x;return;}
	int mid=(L+R)>>1;pushdown(k);
	if(r<=mid)mdy(k<<1,l,r,x,L,mid);
	else if(l>mid)mdy(k<<1|1,l,r,x,mid+1,R);
	else mdy(k<<1,l,mid,x,L,mid),mdy(k<<1|1,mid+1,r,x,mid+1,R);
	upd(k);
}
void modify(int k, int p, int x, int l, int r){
	if(l==r){tree[k].mx=tree[k].lmx=x;return;}
	int mid=(l+r)>>1;pushdown(k);
	if(p<=mid)modify(k<<1,p,x,l,mid);else modify(k<<1|1,p,x,mid+1,r);
	upd(k);
}
void ins(int x, int t){
	if(Set[x].empty())return;
	if(Set[x].size()>=2)mdy(1,*Set[x].begin(),(*Set[x].rbegin())-1,t,0,n);
	modify(1,*Set[x].begin(),t>0?SZ(Set[x]):0,0,n);
}
int main() {
	read(n);read(q);rep(i,1,n)read(a[i]),Set[a[i]].insert(i);
	rep(i,0,n)modify(1,i,0,0,n);
	rep(i,1,2e5)ins(i,1);
	printf("%d\n",n-tree[1].ans);
	while(q--){
		int x,y;read(x);read(y);
		ins(a[x],-1);Set[a[x]].erase(x);ins(a[x],1);
		a[x]=y;
		ins(a[x],-1);Set[a[x]].insert(x);ins(a[x],1);
		printf("%d\n",n-tree[1].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

const int maxn=2e5+5;

struct TR{
	int sum,l0,r0,nmin;
};

int n,q,a[maxn],maxa;
set<int> pos[maxn];

int nmax[4*maxn];
void nmax_xg(int k,int l,int r,int x,int z)
{
	if (l==r)
	{
		nmax[k]+=z;
		return;
	}
	int t=k<<1, mid=(l+r)>>1;
	if (x<=mid) nmax_xg(t,l,mid,x,z); else nmax_xg(t+1,mid+1,r,x,z);
	nmax[k]=max(nmax[t],nmax[t+1]);
}
int nmax_cx(int k,int l,int r,int x,int y)
{
	if (x>y) return 0;
	if (x<=l && r<=y) return nmax[k];
	int t=k<<1, mid=(l+r)>>1, re=0;
	if (x<=mid) re=max(re,nmax_cx(t,l,mid,x,y));
	if (mid<y) re=max(re,nmax_cx(t+1,mid+1,r,x,y));
	return re;
}

TR tr[4*maxn];
int bz[4*maxn];
void update(int k,int t)
{
	tr[t].nmin+=bz[k], tr[t+1].nmin+=bz[k];
	bz[t]+=bz[k], bz[t+1]+=bz[k];
	bz[k]=0;
}
TR merge(const TR &a,const TR &b)
{
	if (a.nmin<b.nmin) return a;
		else if (a.nmin>b.nmin) return b;
			else return (TR){a.sum+b.sum+nmax_cx(1,1,n,a.r0+1,b.l0),a.l0,b.r0,a.nmin};
}
void tr_js(int k,int l,int r)
{
	if (l==r)
	{
		tr[k].l0=tr[k].r0=l;
		return;
	}
	int t=k<<1, mid=(l+r)>>1;
	tr_js(t,l,mid), tr_js(t+1,mid+1,r);
	tr[k]=merge(tr[t],tr[t+1]);
}
void tr_xg_sing(int k,int l,int r,int x,int z)
{
	if (l==r)
	{
		nmax_xg(1,1,n,x,z);
		return;
	}
	int t=k<<1, mid=(l+r)>>1;
	update(k,t);
	if (x<=mid) tr_xg_sing(t,l,mid,x,z); else tr_xg_sing(t+1,mid+1,r,x,z);
	tr[k]=merge(tr[t],tr[t+1]);
}
void tr_xg_q(int k,int l,int r,int x,int y,int z)
{
	if (x>y) return;
	if (x<=l && r<=y)
	{
		tr[k].nmin+=z;
		bz[k]+=z;
		return;
	}
	int t=k<<1, mid=(l+r)>>1;
	update(k,t);
	if (x<=mid) tr_xg_q(t,l,mid,x,y,z);
	if (mid<y) tr_xg_q(t+1,mid+1,r,x,y,z);
	tr[k]=merge(tr[t],tr[t+1]);
}

void modify(int x,int sig)
{
	if (pos[x].empty()) return;
	tr_xg_sing(1,0,n,*pos[x].begin(),sig*pos[x].size());
	set<int>::iterator it=pos[x].end();
	it--;
	tr_xg_q(1,0,n,*pos[x].begin(),*it-1,sig);
}

void calc_ans()
{
	int ans=n-tr[1].sum-nmax_cx(1,1,n,1,tr[1].l0)-nmax_cx(1,1,n,tr[1].r0+1,n);
	printf("%d\n",ans);
}

int main()
{
	scanf("%d %d",&n,&q);
	fo(i,1,n)
	{
		scanf("%d",&a[i]);
		maxa=max(maxa,a[i]);
		pos[a[i]].insert(i);
	}

	tr_js(1,0,n);
	fo(i,1,maxa) modify(i,1);

	calc_ans();
	while (q--)
	{
		int x,y;
		scanf("%d %d",&x,&y);

		modify(a[x],-1);
		pos[a[x]].erase(x);
		modify(a[x],1);

		modify(y,-1);
		pos[y].insert(x);
		modify(y,1);
		a[x]=y;

		calc_ans();
	}
}


/*
 * Since g++10 is released, some characters is not valid inside #if 0 :(
 * So, why not using clang++? :D

 * Date:
  2020.06.16

 * Solution:
 * 问题转换（量化地描述问题），线段树动态维护分治结构

    对于一个权值 w ，设其出现的位置集合为 S[w] ，l = min(S[w]), r = max(S[w]) ，那么
最终序列里 [l, r] 必须是同一个权值，不妨缩为一段。最后序列被分为若干段，那么花费显然
就是 n 减去每一段出现次数最多的值的出现次数。

    乍一看不好维护，首先为了很好的描述这个分段，设一个辅助数组 {a} ，a[i] = 1 当且仅
当原序列 i 和 i + 1 在同一段，那么对于每个权值 w ，其对 {a} 的影响就是一个区间覆盖。
如果要求的是段数，用个线段树维护 {a} 即可，但是区间覆盖难以逆操作，不妨扩展 {a} 的定
义，把是否覆盖改为覆盖次数，那么维护 {a} 的最小值和最小值数量就可以动态维护段数。

    然而要求的并不是段数，是原序列在每段的出现次数最大值的和。为了描述这个出现次数，
不妨再设一个辅助数组 {b} ，对于一个权值 w 和 x in S[w] ，令 b[x] = |S[w]| ，那么要求
的就是每段在 {b} 上的最大值的和，事实上，这样每个 w 涉及到的 b 的下标很多，可以仅令
b[min(S[w])] = |S[w]| ，这样在维护中可能更方便。

    使用线段树，维护 {a} 的最小值和最小值数的同时维护 {b} ，具体的，对于线段树的任意
一个节点，按 {a} 的最小值分段（不一定是 0 ），维护 {b} 在最左边一段的最大值，最右边
一段的最大值，整个区间的最大值，然后维护在每个段的最大值的和即可。稍加讨论可以发现这
些信息是可以 O(1) 合并的。

 * Digression:
  看上去很复杂，讨论清楚其实并不难，直接一遍过。

 * CopyRight:
          ▁▃▄▄▄▃▃▃▃▄▶
        ▗▇▀▔    ▔▔▔▔
       ▄▛   ▃▅━━■▄▂
      ▟▊   ▐▘     ▀▙
     ▟▜▌   ▐▖   ▋  ▐▍
    ▟▘ ▜   ▝▀▇▆●▘  ▐▌
  ▗▟▘   ▜▃       ▁▅▛
  ▔▀▼▅▄▃▃██▅▄▄▄▅■▀▔
        ▔▔▔▔▔▔
 */

#include <cstdio>
#include <algorithm>
#include <set>
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long ll;

struct {
	inline operator int () { int x; return scanf("%d", &x), x; }
} read;

const int maxn = 200005;
std::set<int> pos[maxn];
int min[maxn << 2], tot[maxn << 2], tag[maxn << 2];
int ans[maxn << 2], lv[maxn << 2], rv[maxn << 2], nv[maxn << 2];
#define ls (now << 1)
#define rs (now << 1 | 1)

void modi (int now, int x) {
	min[now] += x;
	tag[now] += x;
}

void push (int now) {
	if (tag[now]) {
		modi(ls, tag[now]);
		modi(rs, tag[now]);
		tag[now] = 0;
	}
}

void update (int now) {
	min[now] = std::min(min[ls], min[rs]);
	nv[now] = std::max(nv[ls], nv[rs]);
	if (min[ls] == min[rs]) {
		tot[now] = tot[ls] + tot[rs];
		ans[now] = ans[ls] + ans[rs] - rv[ls] - lv[rs] + std::max(rv[ls], lv[rs]);
		lv[now] = lv[ls];
		rv[now] = rv[rs];
	}
	if (min[ls] < min[rs]) {
		tot[now] = tot[ls];
		ans[now] = ans[ls] - rv[ls] + std::max(rv[ls], nv[rs]);
		lv[now] = lv[ls];
		rv[now] = std::max(rv[ls], nv[rs]);
	}
	if (min[ls] > min[rs]) {
		tot[now] = tot[rs];
		ans[now] = ans[rs] - lv[rs] + std::max(lv[rs], nv[ls]);
		lv[now] = std::max(lv[rs], nv[ls]);
		rv[now] = rv[rs];
	}
}

void modify (int now, int L, int R, int l, int r, int x) {
	if (r < L or l > R) return;
	if (l <= L and R <= r) return modi(now, x);
	int M = (L + R) >> 1;
	push(now);
	modify(ls, L, M, l, r, x);
	modify(rs, M + 1, R, l, r, x);
	update(now);
}

void modify2 (int now, int L, int R, int p, int x) {
	if (L == R) {
		ans[now] = lv[now] = nv[now] = x;
		return;
	}
	int M = (L + R) >> 1;
	push(now);
	if (p <= M) modify2(ls, L, M, p, x);
	else modify2(rs, M + 1, R, p, x);
	update(now);
}

void print (int now, int L, int R) {
	debug("%d - %d : l=%d r=%d n=%d a=%d\n",
			L, R, lv[now], rv[now], nv[now], ans[now]);
	if (L == R) return;
	int M = (L + R) >> 1;
	print(ls, L, M);
	print(rs, M + 1, R);
}

void build (int now, int L, int R) {
	tot[now] = R - L + 1;
	if (L == R) return;
	int M = (L + R) >> 1;
	build(ls, L, M);
	build(rs, M + 1, R);
}

int a[maxn];
void update (int w, int n, int x) {
	if (pos[w].empty()) return;
	int l = *pos[w].begin(), r = *pos[w].rbegin();
	if (l < r)
		modify(1, 1, n, l, r - 1, x);
	if (x == -1)
		modify2(1, 1, n, l, 0);
	if (x == 1)
		modify2(1, 1, n, l, int(pos[w].size()));
}

int main () {
	int n = read, q = read;
	for (int i = 1; i <= n; i ++)
		pos[a[i] = read].insert(i);
	build(1, 1, n);
	for (int w = 1; w <= 200000; w ++)
		update(w, n, 1);
	printf("%d\n", n - ans[1]);
	while (q --) {
		int p = read, w = read;
		update(a[p], n, -1);
		update(w, n, -1);
		pos[a[p]].erase(p);
		pos[w].insert(p);
		update(a[p], n, 1);
		update(w, n, 1);
		a[p] = w;
		printf("%d\n", n - ans[1]);
	}
	/* print(1, 1, n); */
}


#include<bits/stdc++.h>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
using namespace std;
const int N=2e5+50,m=2e5+5;
int n,Q;
int a[N];
set<int> st[N];
struct Segment_tree
{
	int vmi[N<<2],lmx[N<<2],rmx[N<<2],mx[N<<2],sum[N<<2],tag[N<<2];
	void cover(int rt,int w)
	{
		vmi[rt]+=w;tag[rt]+=w;
	}
	void mdown(int rt)
	{
		cover(ls,tag[rt]);cover(rs,tag[rt]);
		tag[rt]=0;
	}
	void mup(int rt)
	{
		if(vmi[ls]==vmi[rs])
		{
			lmx[rt]=lmx[ls];rmx[rt]=rmx[rs];
			sum[rt]=sum[ls]+sum[rs]+max(rmx[ls],lmx[rs]);
		}
		else if(vmi[ls]<vmi[rs])
		{
			lmx[rt]=lmx[ls];rmx[rt]=max(mx[rs],rmx[ls]);
			sum[rt]=sum[ls];
		}
		else
		{
			rmx[rt]=rmx[rs];lmx[rt]=max(mx[ls],lmx[rs]);
			sum[rt]=sum[rs];
		}
		mx[rt]=max(mx[ls],mx[rs]);vmi[rt]=min(vmi[ls],vmi[rs]);
	}
	void chg(int rt,int l,int r,int x,int w)
	{
		if(l==r)
		{
			lmx[rt]=mx[rt]=w;return ;
		}
		int mid=(l+r)>>1;
		mdown(rt);
		if(mid>=x) chg(ls,l,mid,x,w);
		else chg(rs,mid+1,r,x,w);
		mup(rt);
	}
	void update(int rt,int l,int r,int x,int y,int w)
	{
		if(l>=x&&r<=y)
		{
			cover(rt,w);
			return ;
		}
		int mid=(l+r)>>1;
		mdown(rt);
		if(mid>=x) update(ls,l,mid,x,y,w);
		if(mid<y) update(rs,mid+1,r,x,y,w);
		mup(rt);
	}
}sgt;
void update(int col,int typ)
{
	if(st[col].empty()) return ;
	int siz=st[col].size();
	if(siz>1) sgt.update(1,1,n,*st[col].begin(),*st[col].rbegin()-1,typ);
	if(typ==-1) sgt.chg(1,1,n,*st[col].begin(),0);
	else sgt.chg(1,1,n,*st[col].begin(),siz);
}
int main()
{
	int i,pos,c;
	scanf("%d%d",&n,&Q);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		st[a[i]].insert(i);
	}
	for(i=1;i<=m;i++) update(i,1);
	printf("%d\n",n-sgt.sum[1]-sgt.lmx[1]-sgt.rmx[1]);
	while(Q--)
	{
		scanf("%d%d",&pos,&c);
		update(a[pos],-1);
		st[a[pos]].erase(pos);
		update(a[pos],1);
		a[pos]=c;
		update(a[pos],-1);
		st[a[pos]].insert(pos);
		update(a[pos],1);
		printf("%d\n",n-sgt.sum[1]-sgt.lmx[1]-sgt.rmx[1]);
	}
	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,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 <set>

#include <cstdio>

const int N = 200005 ;

#define _be begin
#define _en rbegin

#define era erase
#define ins insert

using namespace std ;

set <int> col[N] ;

int seg[N * 3] ;
int mnv[N * 3] ;
int mxt[N * 3] ;
int tag[N * 3] ;
int lcon[N * 3] ;
int rcon[N * 3] ;

#define lc (rt << 1)
#define rc (rt << 1 | 1)

inline void _down(int rt){
    if (tag[rt]){
        mnv[lc] += tag[rt] ;
        mnv[rc] += tag[rt] ;
        tag[lc] += tag[rt] ;
        tag[rc] += tag[rt] ;
        tag[rt] = 0 ;
    }
}
inline void _up(int rt){
    int ls = rt << 1 ;
    int rs = rt << 1 | 1 ;
    mxt[rt] = max(mxt[ls], mxt[rs]) ;
    mnv[rt] = min(mnv[ls], mnv[rs]) ;
    if (mnv[ls] < mnv[rs]){
        seg[rt] = seg[ls] ;
        lcon[rt] = lcon[ls] ;
        rcon[rt] = max(mxt[rs], rcon[ls]) ;
        //此处由于最后要覆盖，所以 max_Time(rc) 本质上就是包含右端点的值。
    }
    else if (mnv[ls] > mnv[rs]){
        seg[rt] = seg[rs] ;
        rcon[rt] = rcon[rs] ;
        lcon[rt] = max(mxt[ls], lcon[rs]) ;
    }
    else {
        lcon[rt] = lcon[ls] ; rcon[rt] = rcon[rs] ;
        seg[rt] = seg[ls] + seg[rs] + max(lcon[rs], rcon[ls]) ;
    }
}
void upd(int rt, int l, int r, int ul, int ur, int v){
    if (ul > ur) return ;
    if (ul <= l && r <= ur)
        return mnv[rt] += v, void(tag[rt] += v) ;
    int mid = (l + r) >> 1 ; _down(rt) ;
    if (ul <= mid) upd(lc, l, mid, ul, ur, v) ;
    if (ur > mid) upd(rc, mid + 1, r, ul, ur, v) ;
    _up(rt) ;
}
void cov(int rt, int l, int r, int p, int v){
    if (l == r)
        return void(mxt[rt] = lcon[rt] = v) ;
    int mid = (l + r) >> 1 ; _down(rt) ;
    if (p <= mid) cov(lc, l, mid, p, v) ;
    else cov(rc, mid + 1, r, p, v) ; _up(rt) ;
}
int n, q ;
int base[N] ;
void mdf(int c, int mk){
    int w ;
    if (!(w = col[c].size())) return ;
//	printf("%d %d %d %d %d\n", c, mk, *col[c]._be(), *-- col[c]._en(), (int)col[c].size()) ;
    cov(1, 1, n, *col[c]._be(), mk > 0 ? w : 0) ;
    upd(1, 1, n, *col[c]._be(), *col[c]._en() - 1, mk) ;
}
int val_it(){ return n - seg[1] - lcon[1] - rcon[1] ; }

int main(){
    int x, y, z ;
    scanf("%d%d", &n, &q) ;
    for (int i = 1 ; i <= n ; ++ i)
        scanf("%d", &base[i]), col[base[i]].ins(i) ;
    for (int i = 1 ; i < N ; ++ i)
        mdf(i, 1) ; printf("%d\n", val_it()) ;
    while (q --){
        scanf("%d%d", &x, &y) ; z = base[x] ;
        mdf(z, -1) ; col[z].era(x) ; mdf(z, 1) ;
        mdf(y, -1) ; col[y].ins(x) ; mdf(y, 1) ;
        printf("%d\n", val_it()) ; base[x] = y ;
    }
    return 0 ;
}


#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
const int N = 2e5+100;
int a[N],w[N],b[N],vis[N],n,q,p,x;
set<int> st[N];
struct node{
    int tag,mn,mx,l,r,all,cnt;
}tr[1<<19];
void pushup(int k,int l,int r){
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    tr[k].mn=min(tr[lk].mn,tr[rk].mn);
    tr[k].mx=max(tr[lk].mx,tr[rk].mx);
    tr[k].l=(tr[k].mn==tr[lk].mn)?tr[lk].l:max(tr[lk].mx,tr[rk].l);
    tr[k].r=(tr[k].mn==tr[rk].mn)?tr[rk].r:max(tr[lk].r,tr[rk].mx);
    if(tr[k].mn!=tr[lk].mn){
        tr[k].cnt=tr[rk].cnt;
        tr[k].all=tr[rk].cnt+mid-l+1;
    }
    else if(tr[k].mn!=tr[rk].mn){
        tr[k].cnt=tr[lk].cnt;
        tr[k].all=tr[lk].all+r-mid;
    }
    else{
        tr[k].cnt=tr[lk].cnt+tr[rk].cnt;
        tr[k].all=tr[lk].all+tr[rk].all;
        if(tr[lk].r!=-1||tr[rk].l!=-1){
            tr[k].cnt+=max(tr[lk].r,tr[rk].l);
            tr[k].all++;
        }
    }
}
void pushdown(int k){
    if(tr[k].tag){
        int lk=k*2+1,rk=k*2+2;
        tr[lk].tag+=tr[k].tag;
        tr[rk].tag+=tr[k].tag;
        tr[lk].mn+=tr[k].tag;
        tr[rk].mn+=tr[k].tag;
        tr[k].tag=0;
    }
}
void build(int k,int l,int r){
    if(l==r){
        tr[k].all=tr[k].cnt=tr[k].tag=0;
        tr[k].l=tr[k].r=-1; tr[k].mn=b[l];
        tr[k].mx=max(w[l],w[l+1]);
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    build(lk,l,mid); build(rk,mid+1,r);
    pushup(k,l,r);
}
void update(int p,int k,int l,int r){
    if(p<l||p>r) return;
    if(l==r){
        tr[k].mx=max(w[l],w[l+1]);
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    pushdown(k);
    update(p,lk,l,mid); update(p,rk,mid+1,r);
    pushup(k,l,r);
}
void modify(int a,int b,int c,int k,int l,int r){
    if(a>r||b<l) return;
    if(a<=l&&r<=b){
        tr[k].tag+=c; tr[k].mn+=c;
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    pushdown(k);
    modify(a,b,c,lk,l,mid); modify(a,b,c,rk,mid+1,r);
    pushup(k,l,r);
}

void add(int p,int x){
    if(!st[x].empty()){
        int l=*st[x].begin(),r=*st[x].rbegin();
        if(l<=r-1) modify(l,r-1,-1,0,0,n);
        w[l]=0; update(l-1,0,0,n); update(l,0,0,n);
    }

    st[x].insert(p);
    int l=*st[x].begin(),r=*st[x].rbegin();
    if(l<=r-1) modify(l,r-1,1,0,0,n);
    w[l]=st[x].size(); update(l-1,0,0,n); update(l,0,0,n);
}
void del(int p,int x){
    int l=*st[x].begin(),r=*st[x].rbegin();
    if(l<=r-1) modify(l,r-1,-1,0,0,n);
    w[l]=0; update(l-1,0,0,n); update(l,0,0,n);

    st[x].erase(p);
    if(!st[x].empty()){
        int l=*st[x].begin(),r=*st[x].rbegin();
        if(l<=r-1) modify(l,r-1,1,0,0,n);
        w[l]=st[x].size(); update(l-1,0,0,n); update(l,0,0,n);
    }
}

int main(){
    scanf("%d %d",&n,&q);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        st[a[i]].insert(i);
    }
    for(int i=1;i<=n;++i){
        if(vis[a[i]]) continue;
        vis[a[i]]=1;
        int l=*st[a[i]].begin(), r=*st[a[i]].rbegin();
        w[l]=st[a[i]].size();
        if(l<=r-1) b[l]++,b[r]--;
    }
    for(int i=1;i<=n;++i) b[i]+=b[i-1];
    build(0,0,n);
    printf("%d\n",tr[0].all-tr[0].cnt);
    while(q--){
        scanf("%d %d",&p,&x);
        del(p,a[p]); a[p]=x; add(p,a[p]);
        printf("%d\n",tr[0].all-tr[0].cnt);
    }
}


#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
const int N = 2e5+100;
int a[N],w[N],b[N],n,q,p,x;
bool vis[N];
set<int> st[N];
struct node{
    int tag,mn,mx,l,r,all,cnt;
}tr[1<<19];
void pushup(int k,int l,int r){
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    tr[k].mn=min(tr[lk].mn,tr[rk].mn);
    tr[k].mx=max(tr[lk].mx,tr[rk].mx);
    tr[k].l=(tr[k].mn==tr[lk].mn)?tr[lk].l:max(tr[lk].mx,tr[rk].l);
    tr[k].r=(tr[k].mn==tr[rk].mn)?tr[rk].r:max(tr[lk].r,tr[rk].mx);
    if(tr[k].mn!=tr[lk].mn){
        tr[k].cnt=tr[rk].cnt;
        tr[k].all=tr[rk].all+mid-l+1;
    }
    else if(tr[k].mn!=tr[rk].mn){
        tr[k].cnt=tr[lk].cnt;
        tr[k].all=tr[lk].all+r-mid;
    }
    else{
        tr[k].cnt=tr[lk].cnt+tr[rk].cnt;
        tr[k].all=tr[lk].all+tr[rk].all;
        if(tr[lk].r!=-1||tr[rk].l!=-1){
            tr[k].cnt+=max(tr[lk].r,tr[rk].l);
            tr[k].all++;
        }
    }
}
void pushdown(int k){
    if(tr[k].tag){
        int lk=k*2+1,rk=k*2+2;
        tr[lk].tag+=tr[k].tag;
        tr[rk].tag+=tr[k].tag;
        tr[lk].mn+=tr[k].tag;
        tr[rk].mn+=tr[k].tag;
        tr[k].tag=0;
    }
}
void build(int k,int l,int r){
    tr[k].tag=0;
    if(l==r){
        tr[k].all=tr[k].cnt=0;
        tr[k].l=tr[k].r=-1; tr[k].mn=b[l];
        tr[k].mx=max(w[l],w[l+1]);
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    build(lk,l,mid); build(rk,mid+1,r);
    pushup(k,l,r);
}
void update(int p,int k,int l,int r){
    if(p<l||p>r) return;
    if(l==r){
        tr[k].mx=max(w[l],w[l+1]);
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    pushdown(k);
    update(p,lk,l,mid); update(p,rk,mid+1,r);
    pushup(k,l,r);
}
void modify(int a,int b,int c,int k,int l,int r){
    if(a>r||b<l) return;
    if(a<=l&&r<=b){
        tr[k].tag+=c; tr[k].mn+=c;
        return ;
    }
    int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
    pushdown(k);
    modify(a,b,c,lk,l,mid); modify(a,b,c,rk,mid+1,r);
    pushup(k,l,r);
}

void add(int p,int x){
    if(!st[x].empty()){
        int l=*st[x].begin(),r=*st[x].rbegin();
        if(l<r) modify(l,r-1,-1,0,0,n);
        w[l]=0; update(l-1,0,0,n); update(l,0,0,n);
    }

    st[x].insert(p);
    int l=*st[x].begin(),r=*st[x].rbegin();
    if(l<r) modify(l,r-1,1,0,0,n);
    w[l]=st[x].size(); update(l-1,0,0,n); update(l,0,0,n);
}
void del(int p,int x){
    int l=*st[x].begin(),r=*st[x].rbegin();
    if(l<r) modify(l,r-1,-1,0,0,n);
    w[l]=0; update(l-1,0,0,n); update(l,0,0,n);

    st[x].erase(p);
    if(!st[x].empty()){
        int l=*st[x].begin(),r=*st[x].rbegin();
        if(l<r) modify(l,r-1,1,0,0,n);
        w[l]=st[x].size(); update(l-1,0,0,n); update(l,0,0,n);
    }
}
void debug(int k,int l,int r){
    if(l!=r){
        int lk=k*2+1,rk=k*2+2,mid=(l+r)>>1;
        pushdown(k);
        debug(lk,l,mid); debug(rk,mid+1,r);
        pushup(k,l,r);
    }
    printf("%d %d %d %d %d %d\n",l,r,tr[k].l,tr[k].r,tr[k].cnt,tr[k].all);
}
int main(){
    scanf("%d %d",&n,&q);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        st[a[i]].insert(i); vis[a[i]]=false;
    }
    for(int i=1;i<=n;++i){
        if(vis[a[i]]) continue;
        vis[a[i]]=true;
        int l=*st[a[i]].begin(), r=*st[a[i]].rbegin();
        w[l]=st[a[i]].size();
        if(l<=r-1) b[l]++,b[r]--;
    }
    for(int i=1;i<=n;++i) b[i]+=b[i-1];
    build(0,0,n);
    printf("%d\n",tr[0].all-tr[0].cnt);
    while(q--){
        //debug(0,0,n);
        scanf("%d %d",&p,&x);
        del(p,a[p]); a[p]=x; add(p,a[p]);
        printf("%d\n",tr[0].all-tr[0].cnt);
    }
}


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

const int N=410000,mx=200000;
int n,Q,arr[N]; set<int> pos[N];
struct data {
	int sum,mx,mn,tag,rmx,lmx;
} t[N<<2];
#define ls (k<<1)
#define rs (k<<1|1)
void pushdown(int k) {
	if(!t[k].tag) return ;
	t[ls].tag += t[k].tag, t[ls].mn += t[k].tag;
	t[rs].tag += t[k].tag, t[rs].mn += t[k].tag;
	t[k].tag=0;
}

void pushup(int k) {
	t[k].mn=min(t[ls].mn,t[rs].mn);
	t[k].mx=max(t[ls].mx,t[rs].mx);
	if(t[ls].mn == t[rs].mn) {
		t[k].sum=t[ls].sum+t[rs].sum+max(t[ls].rmx,t[rs].lmx);
		t[k].lmx=t[ls].lmx, t[k].rmx=t[rs].rmx;
	}
	else if(t[ls].mn<t[rs].mn)
			t[k].sum=t[ls].sum, t[k].lmx=t[ls].lmx, t[k].rmx=max(t[rs].mx,t[ls].rmx);
		else
			t[k].sum=t[rs].sum, t[k].rmx=t[rs].rmx, t[k].lmx=max(t[ls].mx,t[rs].lmx);
}

void mdf(int k,int tar,int val,int l=1,int r=2*n+1) {
	if(l == r) { t[k].mx=val; return; }
	int mid=(l+r)>>1; pushdown(k);
	tar <= mid?mdf(ls,tar,val,l,mid):mdf(rs,tar,val,mid+1,r);
	pushup(k);
}

void cover(int k,int ql,int qr,int val,int l=1,int r=2*n+1) {
	if(ql <= l && r <= qr) {
		t[k].tag += val, t[k].mn += val;
		return ;
	}
	int mid=(l+r)>>1; pushdown(k);
	if(ql <= mid) cover(ls,ql,qr,val,l,mid);
	if(qr > mid) cover(rs,ql,qr,val,mid+1,r);
	pushup(k);
}

int main() {
	scanf("%d%d",&n,&Q);
	for(int i=1;i<=n;++i) scanf("%d",&arr[i]), pos[arr[i]].insert(i);
	for(int i=1;i<=mx;++i)
		if(pos[i].size()) {
			mdf(1,2*(*pos[i].begin()),pos[i].size());
			cover(1,2*(*pos[i].begin()),2*(*pos[i].rbegin()),1);
		}
	printf("%d\n",n-t[1].sum);
	while(Q--) {
		int p,val; scanf("%d%d",&p,&val);

		if(pos[arr[p]].size()) {
			mdf(1,2*(*pos[arr[p]].begin()),0);
			cover(1,2*(*pos[arr[p]].begin()),2*(*pos[arr[p]].rbegin()),-1);
		}
		pos[arr[p]].erase(p);
		if(pos[arr[p]].size()) {
			mdf(1,2*(*pos[arr[p]].begin()),pos[arr[p]].size());
			cover(1,2*(*pos[arr[p]].begin()),2*(*pos[arr[p]].rbegin()),1);
		}

		if(pos[val].size()) {
			mdf(1,2*(*pos[val].begin()),0);
			cover(1,2*(*pos[val].begin()),2*(*pos[val].rbegin()),-1);
		}
		arr[p]=val, pos[val].insert(p);
		if(pos[val].size()) {
			mdf(1,2*(*pos[val].begin()),pos[val].size());
			cover(1,2*(*pos[val].begin()),2*(*pos[val].rbegin()),1);
		}
		printf("%d\n",n-t[1].sum);
	}
	return 0;
}


#include <bits/stdc++.h>
#define mset(a, b) memset(a, b, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
#define lc (rt << 1)
#define rc (rt << 1) | 1
using namespace std;
typedef long long LL;
const int MAXN = 200005;

template <typename T> inline void read(T &AKNOI) {
	T x = 0, flag = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flag = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	AKNOI = flag * x;
}

int n, q, a[MAXN];
set<int> pos[MAXN];

int tag[MAXN << 2];
struct Node {
	int mn, mx, lmx, rmx, sum;
} seg[MAXN << 2];

Node operator + (Node a, Node b) {
	Node c;
	c.mn = min(a.mn, b.mn);
	c.mx = max(a.mx, b.mx);
	if (a.mn < b.mn) {
		c.sum = a.sum;
		c.lmx = a.lmx;
		c.rmx = max(a.rmx, b.mx);
	} else if (a.mn > b.mn) {
		c.sum = b.sum;
		c.rmx = b.rmx;
		c.lmx = max(b.lmx, a.mx);
	} else {
		c.sum = a.sum + b.sum + max(a.rmx, b.lmx);
		c.lmx = a.lmx;
		c.rmx = b.rmx;
	}
	return c;
}

inline void puttag(int rt, int tg) {
	seg[rt].mn += tg;
	tag[rt] += tg;
}

inline void pushdown(int rt) {
	if (tag[rt]) {
		puttag(lc, tag[rt]);
		puttag(rc, tag[rt]);
		tag[rt] = 0;
	}
}

void Cover(int rt, int b, int e, int l, int r, int v) {
	if (l <= b && e <= r) {
		puttag(rt, v);
		return;
	}
	int mid = (b + e) >> 1;
	pushdown(rt);
	if (l <= mid) Cover(lc, b, mid, l, r, v);
	if (r > mid) Cover(rc, mid + 1, e, l, r, v);
	seg[rt] = seg[lc] + seg[rc];
}

void Update(int rt, int b, int e, int p, int v) {
	if (b == e) {
		seg[rt].mx = seg[rt].lmx = v;
		return;
	}
	int mid = (b + e) >> 1;
	pushdown(rt);
	if (p <= mid) Update(lc, b, mid, p, v);
	else Update(rc, mid + 1, e, p, v);
	seg[rt] = seg[lc] + seg[rc];
}

inline void Modify(int c, int t) {
	if (!pos[c].size()) return;
	Cover(1, 1, n, *pos[c].begin(), *pos[c].rbegin() - 1, t);
	Update(1, 1, n, *pos[c].begin(), (t == 1? pos[c].size() : 0));
}

inline int GetAns() {
	return n - seg[1].sum - seg[1].lmx - seg[1].rmx;
}

void init() {
	read(n); read(q);
	for (int i = 1; i <= n; ++i) {
		read(a[i]);
		pos[a[i]].insert(i);
	}
	for (int i = 1; i < MAXN; ++i) {
		Modify(i, 1);
	}
}

void solve() {
	printf("%d\n", GetAns());
	int i, x;
	while (q--) {
		read(i); read(x);
		Modify(a[i], -1);
		pos[a[i]].erase(i);
		Modify(a[i], 1);
		a[i] = x;
		Modify(a[i], -1);
		pos[a[i]].insert(i);
		Modify(a[i], 1);
		printf("%d\n", GetAns());
	}
}

int main() {
	init();
	solve();
	return 0;
}


#include <bits/stdc++.h>
#define mset(a, b) memset(a, b, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
#define lc (rt << 1)
#define rc (rt << 1) | 1
using namespace std;
typedef long long LL;
const int MAXN = 200005;

template <typename T> inline void read(T &AKNOI) {
	T x = 0, flag = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flag = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	AKNOI = flag * x;
}

int n, q, a[MAXN];
set<int> pos[MAXN];

int tag[MAXN << 2];
struct Node {
	int mn, mx, lmx, rmx, sum;
} seg[MAXN << 2];

Node operator + (Node a, Node b) {
	Node c;
	c.mn = min(a.mn, b.mn);
	c.mx = max(a.mx, b.mx);
	if (a.mn < b.mn) {
		c.sum = a.sum;
		c.lmx = a.lmx;
		c.rmx = max(a.rmx, b.mx);
	} else if (a.mn > b.mn) {
		c.sum = b.sum;
		c.rmx = b.rmx;
		c.lmx = max(b.lmx, a.mx);
	} else {
		c.sum = a.sum + b.sum + max(a.rmx, b.lmx);
		c.lmx = a.lmx;
		c.rmx = b.rmx;
	}
	return c;
}

inline void puttag(int rt, int tg) {
	seg[rt].mn += tg;
	tag[rt] += tg;
}

inline void pushdown(int rt) {
	if (tag[rt]) {
		puttag(lc, tag[rt]);
		puttag(rc, tag[rt]);
		tag[rt] = 0;
	}
}

void Cover(int rt, int b, int e, int l, int r, int v) {
	if (l <= b && e <= r) {
		puttag(rt, v);
		return;
	}
	int mid = (b + e) >> 1;
	pushdown(rt);
	if (l <= mid) Cover(lc, b, mid, l, r, v);
	if (r > mid) Cover(rc, mid + 1, e, l, r, v);
	seg[rt] = seg[lc] + seg[rc];
}

void Update(int rt, int b, int e, int p, int v) {
	if (b == e) {
		seg[rt].mx = seg[rt].lmx = v;
		return;
	}
	int mid = (b + e) >> 1;
	pushdown(rt);
	if (p <= mid) Update(lc, b, mid, p, v);
	else Update(rc, mid + 1, e, p, v);
	seg[rt] = seg[lc] + seg[rc];
}

inline void Modify(int c, int t) {
	if (!pos[c].size()) return;
	if (pos[c].size() > 1) Cover(1, 1, n, *pos[c].begin(), *pos[c].rbegin() - 1, t);
	Update(1, 1, n, *pos[c].begin(), (t == 1? pos[c].size() : 0));
}

inline int GetAns() {
	return n - seg[1].sum - seg[1].lmx - seg[1].rmx;
}

void init() {
	read(n); read(q);
	for (int i = 1; i <= n; ++i) {
		read(a[i]);
		pos[a[i]].insert(i);
	}
	for (int i = 1; i < MAXN; ++i) {
		Modify(i, 1);
	}
}

void solve() {
	printf("%d\n", GetAns());
	int i, x;
	while (q--) {
		read(i); read(x);
		Modify(a[i], -1);
		pos[a[i]].erase(i);
		Modify(a[i], 1);
		a[i] = x;
		Modify(a[i], -1);
		pos[a[i]].insert(i);
		Modify(a[i], 1);
		printf("%d\n", GetAns());
	}
}

int main() {
	init();
	solve();
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned int ui;
typedef pair<int, int> pi;

#define fi first
#define se second

int read() {
  int res = 0, w = 1; char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-') c = getchar(), w = -1;
  while (isdigit(c)) res = (res << 1) + (res << 3) + c - '0', c = getchar();
  return res * w;
}

const int N = 2e5 + 10;

#define LD (t << 1)
#define RD (t << 1 | 1)

struct Point {
  int mx, mn, ml, mr, ans, tag;
} p[N << 2];

void pushup(Point & t, Point ls, Point rs) {
  t.mn = min(ls.mn, rs.mn);
  t.mx = max(ls.mx, rs.mx);
  if (ls.mn == rs.mn) {
    t.ml = ls.ml, t.mr = rs.mr;
    t.ans = ls.ans + rs.ans + max(ls.mr, rs.ml);
  } else {
    if (ls.mn > rs.mn) {
      t.ml = max(ls.mx, rs.ml), t.mr = rs.mr, t.ans = rs.ans;
    } else {
      t.ml = ls.ml, t.mr = max(ls.mr, rs.mx), t.ans = ls.ans;
    }
  }
}

void pushnow(int t, int vl) {
  p[t].tag += vl;
  p[t].mn += vl;
}

void pushdown(int t) {
  if (p[t].tag) {
    pushnow(LD, p[t].tag);
    pushnow(RD, p[t].tag);
    p[t].tag = 0;
  }
}

void update(int t, int l, int r, int pos, int vl) {
  if (l == r) { p[t].ans = p[t].mx = vl; return; }
  pushdown(t);
  int mid = (l + r) >> 1;
  if (pos <= mid) update(LD, l, mid, pos, vl);
  else update(RD, mid + 1, r, pos, vl);
  pushup(p[t], p[LD], p[RD]);
}

void modify(int t, int l, int r, int ql, int qr, int vl) {
  if (ql <= l && r <= qr) { pushnow(t, vl); return; }
  pushdown(t);
  int mid = (l + r) >> 1;
  if (ql <= mid) modify(LD, l, mid, ql, qr, vl);
  if (qr > mid) modify(RD, mid + 1, r, ql, qr, vl);
  pushup(p[t], p[LD], p[RD]);
}

set<int> s[N];
int n, q, a[N];

void add(int id) {
  if (!s[id].size()) return;
  int lp = *s[id].begin(), rp = *s[id].rbegin();
  if (lp < rp) modify(1, 1, n, lp, rp - 1, 1);
  update(1, 1, n, lp, s[id].size());
}

void sub(int id) {
  if (!s[id].size()) return;
  int lp = *s[id].begin(), rp = *s[id].rbegin();
  if (lp < rp) modify(1, 1, n, lp, rp - 1, -1);
  update(1, 1, n, lp, 0);
}

int main() {
#ifdef dream_maker
  freopen("tst.in", "r", stdin);
#else
  //freopen(".in", "r", stdin);
  //freopen(".out", "w", stdout);
#endif
  n = read(), q = read();
  for (int i = 1; i <= n; i++) {
    a[i] = read();
    s[a[i]].insert(i);
  }
  for (int i = 1; i <= 200000; i++) add(i);
  printf("%d\n", n - (p[1].ans + p[1].ml + p[1].mr));
  while (q--) {
    int pos = read(), x = read();
    sub(a[pos]), s[a[pos]].erase(pos), add(a[pos]);
    a[pos] = x;
    sub(a[pos]), s[a[pos]].insert(pos), add(a[pos]);
    printf("%d\n", n - (p[1].ans + p[1].ml + p[1].mr));
  }
  return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cassert>
using namespace std;
int n,q,a[200020],last[200020],cnt[200020],lp[200020],rp[200020];
vector<pair<int,int> >d[800080];
void upd(int k,int l,int r,int ll,int rr,pair<int,int>w)
{
	if(l>rr||r<ll)return ;
	if(l>=ll&&r<=rr)return d[k].push_back(w),void();
	upd(k<<1,l,l+r>>1,ll,rr,w);
	upd(k<<1|1,(l+r>>1)+1,r,ll,rr,w);
}
struct data
{
	int lmx,rmx,mi,cnt,sum,mx;
	void print(){printf("%d %d %d %d %d %d\n",lmx,rmx,mi,cnt,sum,mx);}
	friend data operator + (data &a,data &b)
	{
		static data c;
		c.mi=min(a.mi,b.mi);c.mx=max(a.mx,b.mx);
		c.cnt=(a.mi==c.mi?a.cnt:0)+(b.mi==c.mi?b.cnt:0);
		if(b.mi>c.mi)
		{
			c.sum=a.sum;c.rmx=max(b.mx,a.rmx),c.lmx=a.lmx;
			if(b.mx>a.rmx)c.sum+=b.mx-a.rmx;
		}
		else if(a.mi>c.mi)
		{
			c.sum=b.sum;c.lmx=max(a.mx,b.lmx),c.rmx=b.rmx;
			if(a.mx>b.lmx)c.sum+=a.mx-b.lmx;
		}
		else
		{
			c.lmx=a.lmx,c.rmx=b.rmx;
			c.sum=a.sum+b.sum-min(a.rmx,b.lmx);
		}
		return c;
	}
}s[800080];
int ad[800080];
inline void pushdown(int k)
{
	ad[k<<1]+=ad[k],ad[k<<1|1]+=ad[k];
	s[k<<1].mi+=ad[k],s[k<<1|1].mi+=ad[k];
	ad[k]=0;
}
void build(int k,int l,int r)
{
	s[k].cnt=r-l+1;
	if(l==r)return ;
	build(k<<1,l,l+r>>1);
	build(k<<1|1,(l+r>>1)+1,r);
}
void add(int k,int l,int r,int ll,int rr,int w)
{
	if(l>rr||r<ll)return ;
	if(l>=ll&&r<=rr)
	{
		ad[k]+=w;
		s[k].mi+=w;
		return ;
	}
	if(ad[k])pushdown(k);
	add(k<<1,l,l+r>>1,ll,rr,w);
	add(k<<1|1,(l+r>>1)+1,r,ll,rr,w);
	s[k]=s[k<<1]+s[k<<1|1];
}
void change(int k,int l,int r,int p,int w)
{
	if(l==r)
	{
		s[k].mx=s[k].lmx=s[k].sum=w;
		return ;
	}
	if(ad[k])pushdown(k);
	if(p<=l+r>>1)change(k<<1,l,l+r>>1,p,w);
	else change(k<<1|1,(l+r>>1)+1,r,p,w);
	s[k]=s[k<<1]+s[k<<1|1];
}
void print(int k,int l,int r)
{
	if(l==r)return printf("%d ",s[k].mi),void();
	if(ad[k])pushdown(k);
	print(k<<1,l,l+r>>1);
	print(k<<1|1,(l+r>>1)+1,r);
}
pair<int,int>st[400040];
int tp;
void solve(int k,int l,int r)
{
	int x,w;
	for(auto p:d[k])
	{
		x=p.first,w=p.second;
		++cnt[w];
		st[++tp]=make_pair(lp[w],rp[w]);
		if(lp[w]!=rp[w]&&rp[w])add(1,1,n,lp[w],rp[w]-1,-1);
		if(x<lp[w])lp[w]=x;
		if(x>rp[w])rp[w]=x;
		change(1,1,n,lp[w],cnt[w]);
		if(lp[w]!=rp[w])add(1,1,n,lp[w],rp[w]-1,1);
	}
//	printf("%d %d\n",l,r);
//	for(int i=1;i<=9;++i)ad[i]?pushdown(i),0:0,s[i].print();printf("\n");
	if(l==r)
	{
	//	printf("%d:\n",l);
	//	print(1,1,n);
	//	for(int i=1;i<=14;++i)ad[i]?pushdown(i),0:0,s[i].print();
		printf("%d\n",n-s[1].sum);
	}
	else solve(k<<1,l,l+r>>1),solve(k<<1|1,(l+r>>1)+1,r);
	reverse(d[k].begin(),d[k].end());
	for(auto p:d[k])
	{
		x=p.first,w=p.second;
		--cnt[w];
		if(lp[w]!=rp[w])add(1,1,n,lp[w],rp[w]-1,-1);
		lp[w]=st[tp].first,rp[w]=st[tp].second;
		if(lp[w]!=rp[w]&&rp[w])add(1,1,n,lp[w],rp[w]-1,1);
		if(x<lp[w])change(1,1,n,x,0);
		else change(1,1,n,lp[w],cnt[w]);
		--tp;
	}
}
int main()
{
	scanf("%d %d",&n,&q);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]);
	int x,w;
	for(int i=1;i<=q;++i)
	{
		scanf("%d %d",&x,&w);
		if(a[x]==w)continue;
		upd(1,0,q,last[x],i-1,make_pair(x,a[x]));
		a[x]=w,last[x]=i;
	}
	for(int i=1;i<=n;++i)upd(1,0,q,last[i],q,make_pair(i,a[i]));
	build(1,1,n);
	for(int i=1;i<=200000;++i)lp[i]=n+1,rp[i]=0;
	solve(1,0,q);
//	for(int i=1;i<=14;++i)ad[i]?pushdown(i),0:0,s[i].print();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n,q,a[200020],last[200020],cnt[200020],lp[200020],rp[200020];
vector<pair<int,int> >d[800080];
void upd(int k,int l,int r,int ll,int rr,pair<int,int>w)
{
	if(l>rr||r<ll)return ;
	if(l>=ll&&r<=rr)return d[k].push_back(w),void();
	upd(k<<1,l,l+r>>1,ll,rr,w);
	upd(k<<1|1,(l+r>>1)+1,r,ll,rr,w);
}
struct data
{
	int lmx,rmx,mi,cnt,sum,mx;
	void print(){printf("%d %d %d %d %d %d\n",lmx,rmx,mi,cnt,sum,mx);}
	friend data operator + (data &a,data &b)
	{
		static data c;
		c.mi=min(a.mi,b.mi);c.mx=max(a.mx,b.mx);
		c.cnt=(a.mi==c.mi?a.cnt:0)+(b.mi==c.mi?b.cnt:0);
		if(b.mi>c.mi)
		{
			c.sum=a.sum;c.rmx=max(b.mx,a.rmx),c.lmx=a.lmx;
			if(b.mx>a.rmx)c.sum+=b.mx-a.rmx;
		}
		else if(a.mi>c.mi)
		{
			c.sum=b.sum;c.lmx=max(a.mx,b.lmx),c.rmx=b.rmx;
			if(a.mx>b.lmx)c.sum+=a.mx-b.lmx;
		}
		else
		{
			c.lmx=a.lmx,c.rmx=b.rmx;
			c.sum=a.sum+b.sum-min(a.rmx,b.lmx);
		}
		return c;
	}
}s[800080];
int ad[800080];
inline void pushdown(int k)
{
	ad[k<<1]+=ad[k],ad[k<<1|1]+=ad[k];
	s[k<<1].mi+=ad[k],s[k<<1|1].mi+=ad[k];
	ad[k]=0;
}
void build(int k,int l,int r)
{
	s[k].cnt=r-l+1;
	if(l==r)return ;
	build(k<<1,l,l+r>>1);
	build(k<<1|1,(l+r>>1)+1,r);
}
void add(int k,int l,int r,int ll,int rr,int w)
{
	if(l>rr||r<ll)return ;
	if(l>=ll&&r<=rr)
	{
		ad[k]+=w;
		s[k].mi+=w;
		return ;
	}
	if(ad[k])pushdown(k);
	add(k<<1,l,l+r>>1,ll,rr,w);
	add(k<<1|1,(l+r>>1)+1,r,ll,rr,w);
	s[k]=s[k<<1]+s[k<<1|1];
}
void change(int k,int l,int r,int p,int w)
{
	if(l==r)
	{
		s[k].mx=s[k].lmx=s[k].sum=w;
		return ;
	}
	if(ad[k])pushdown(k);
	if(p<=l+r>>1)change(k<<1,l,l+r>>1,p,w);
	else change(k<<1|1,(l+r>>1)+1,r,p,w);
	s[k]=s[k<<1]+s[k<<1|1];
}
pair<int,int>st[400040];
int tp;
void solve(int k,int l,int r)
{
	int now=tp,x,w;
	for(auto p:d[k])
	{
		x=p.first,w=p.second;
	//	printf("%d %d %d\n",k,x,w);
		++cnt[w];
		st[++tp]=make_pair(lp[w],rp[w]);
		if(lp[w]!=rp[w]&&rp[w])add(1,1,n,lp[w],rp[w]-1,-1);
		if(x<lp[w])lp[w]=x;
		if(x>rp[w])rp[w]=x;
		change(1,1,n,lp[w],cnt[w]);
		if(lp[w]!=rp[w])add(1,1,n,lp[w],rp[w]-1,1);
	}
//	printf("%d %d\n",l,r);
//	for(int i=1;i<=9;++i)ad[i]?pushdown(i),0:0,s[i].print();printf("\n");
	if(l==r)printf("%d\n",n-s[1].sum);
	else solve(k<<1,l,l+r>>1),solve(k<<1|1,(l+r>>1)+1,r);
	int pos=now;
	for(auto p:d[k])
	{
		++pos;
		x=p.first,w=p.second;
		if(lp[w]!=rp[w])add(1,1,n,lp[w],rp[w]-1,-1);
		lp[w]=st[pos].first,rp[w]=st[pos].second;
		if(lp[w]!=rp[w]&&rp[w])add(1,1,n,lp[w],rp[w]-1,1);
		if(x<lp[w])change(1,1,n,x,0);
		else change(1,1,n,lp[w],cnt[w]-1);
		--cnt[w];
	}
	tp=now;
}
int main()
{
	scanf("%d %d",&n,&q);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]);
	int x,w;
	for(int i=1;i<=q;++i)
	{
		scanf("%d %d",&x,&w);
		if(a[x]==w)continue;
		upd(1,0,q,last[x],i-1,make_pair(x,a[x]));
		a[x]=w,last[x]=i;
	}
	for(int i=1;i<=n;++i)upd(1,0,q,last[i],q,make_pair(i,a[i]));
	build(1,1,n);
	for(int i=1;i<=200000;++i)lp[i]=n+1,rp[i]=0;
	solve(1,0,q);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<ctime>
#include<iostream>
using namespace std;
int n,q,a[200020];
set<int>S[200020];
struct data
{
	int lmx,rmx,mi,cnt,sum,mx;
	void print(){printf("%d %d %d %d %d %d\n",lmx,rmx,mi,cnt,sum,mx);}

}s[800080];
inline void get(data &a,data &b,data &c)
{
	c.mi=min(a.mi,b.mi);c.mx=max(a.mx,b.mx);
	c.cnt=(a.mi==c.mi?a.cnt:0)+(b.mi==c.mi?b.cnt:0);
	if(b.mi>c.mi)
	{
		c.sum=a.sum;c.rmx=max(b.mx,a.rmx),c.lmx=a.lmx;
		if(b.mx>a.rmx)c.sum+=b.mx-a.rmx;
	}
	else if(a.mi>c.mi)
	{
		c.sum=b.sum;c.lmx=max(a.mx,b.lmx),c.rmx=b.rmx;
		if(a.mx>b.lmx)c.sum+=a.mx-b.lmx;
	}
	else
	{
		c.lmx=a.lmx,c.rmx=b.rmx;
		c.sum=a.sum+b.sum-min(a.rmx,b.lmx);
	}
}
int ad[800080];
inline void pushdown(int k)
{
	ad[k<<1]+=ad[k],ad[k<<1|1]+=ad[k];
	s[k<<1].mi+=ad[k],s[k<<1|1].mi+=ad[k];
	ad[k]=0;
}
void build(int k,int l,int r)
{
	s[k].cnt=r-l+1;
	if(l==r)return ;
	build(k<<1,l,l+r>>1);
	build(k<<1|1,(l+r>>1)+1,r);
}
void add(int k,int l,int r,int ll,int rr,int w)
{
	if(l>rr||r<ll)return ;
	if(l>=ll&&r<=rr)
	{
		ad[k]+=w;
		s[k].mi+=w;
		return ;
	}
	if(ad[k])pushdown(k);
	add(k<<1,l,l+r>>1,ll,rr,w);
	add(k<<1|1,(l+r>>1)+1,r,ll,rr,w);
	get(s[k<<1],s[k<<1|1],s[k]);
}
void change(int k,int l,int r,int p,int w)
{
	if(l==r)
	{
		s[k].mx=s[k].lmx=s[k].sum=w;
		return ;
	}
	if(ad[k])pushdown(k);
	if(p<=l+r>>1)change(k<<1,l,l+r>>1,p,w);
	else change(k<<1|1,(l+r>>1)+1,r,p,w);
	get(s[k<<1],s[k<<1|1],s[k]);
}
int main()
{
	scanf("%d %d",&n,&q);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
		S[a[i]].insert(i);
	}
	build(1,1,n);
	for(int i=1;i<=200000;++i)
		if(S[i].size())
		{
			if(S[i].size()>1)add(1,1,n,*S[i].begin(),*S[i].rbegin()-1,1);
			change(1,1,n,*S[i].begin(),S[i].size());
		}
	printf("%d\n",n-s[1].sum);
	int x,w,y;
	for(int i=1;i<=q;++i)
	{
		scanf("%d %d",&x,&w);
		if(a[x]!=w)
		{
			y=a[x];
			change(1,1,n,*S[y].begin(),0);
			if(S[y].size()>1)add(1,1,n,*S[y].begin(),*S[y].rbegin()-1,-1);
			S[y].erase(x);
			if(S[y].size())
			{
				if(S[y].size()>1)add(1,1,n,*S[y].begin(),*S[y].rbegin()-1,1);
				change(1,1,n,*S[y].begin(),S[y].size());
			}
			if(S[w].size())
			{
				if(S[w].size()>1)add(1,1,n,*S[w].begin(),*S[w].rbegin()-1,-1);
				change(1,1,n,*S[w].begin(),0);
			}
			S[w].insert(x);
			change(1,1,n,*S[w].begin(),S[w].size());
			if(S[w].size()>1)add(1,1,n,*S[w].begin(),*S[w].rbegin()-1,1);
			a[x]=w;
		}
		printf("%d\n",n-s[1].sum);
	}
	cerr<<clock()<<endl;
	return 0;
}


/*mjytxdy!*/
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fir first
#define sec second
#define all(x) x.begin(),x.end()
#define size(x) ((int)x.size())
#define pii pair<int,int>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define inl inline
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,r,l) for(int i=(r);i>=(l);i--)
#define trv(i,u) for(int i=head[u];i;i=e[i].next)
#define lb(x) ((x)&(-(x)))
#define debug(x) cout<<#x":"<<x<<'\n'
#define myput puts("QaQ")
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
typedef long long ll;
template<class T>inl bool ylmin(T &a,T b){return a<b?0:(a=b,1);}
template<class T>inl bool ylmax(T &a,T b){return a>b?0:(a=b,1);}
template<class T>inl T abs(T x){return x<0?-x:x;}
inl char read(){
	static const int IO_LEN=1024*1024;
	static char buf[IO_LEN],*ioh,*iot;
	if(ioh==iot){
		iot=(ioh=buf)+fread(buf,1,IO_LEN,stdin);
		if(ioh==iot) return -1;
	}
	return *ioh++;
}
template<class T>inl void read(T &x){
	static int iosig;static char ioc;
	for(iosig=0,ioc=read();!isdigit(ioc);ioc=read()) if(ioc=='-') iosig=1;
	for(x=0;isdigit(ioc);ioc=read())x=(x<<1)+(x<<3)+(ioc^'0');
	if(iosig) x=-x;
}
const int MAXN = 2e5 + 10;
int n,q,a[MAXN],b[MAXN],c[MAXN];
set<int> Set[MAXN];
struct Segment{
	#define ls rt<<1
	#define rs rt<<1|1
	int Max[MAXN<<2],lmax[MAXN<<2],rmax[MAXN<<2],Min[MAXN<<2],sum[MAXN<<2],tag[MAXN<<2];
	inl void pushup(int rt){
		Max[rt]=max(Max[ls],Max[rs]);
		Min[rt]=min(Min[ls],Min[rs]);
		if(Min[ls]<Min[rs]){
			sum[rt]=sum[ls];
			lmax[rt]=lmax[ls];
			rmax[rt]=max(rmax[ls],Max[rs]);
		}
		else if(Min[ls]>Min[rs]){
			sum[rt]=sum[rs];
			lmax[rt]=max(lmax[rs],Max[ls]);
			rmax[rt]=rmax[rs];
		}
		else {
			sum[rt]=sum[ls]+sum[rs]+max(rmax[ls],lmax[rs]);
			lmax[rt]=lmax[ls];
			rmax[rt]=rmax[rs];
		}
	}
	inl void pushdown(int rt){
		Min[ls]+=tag[rt],Min[rs]+=tag[rt];
		tag[ls]+=tag[rt],tag[rs]+=tag[rt];
		tag[rt]=0;
	}
	inl void build(int rt,int l,int r){
		if(l==r) {
			Max[rt]=lmax[rt]=c[l];
			Min[rt]=b[l];
			return ;
		}
		int mid=l+r>>1;
		build(ls,l,mid),build(rs,mid+1,r);
		pushup(rt);
	}
	inl void update1(int rt,int l,int r,int L,int R,int k){
		if(l>=L && r<=R){
			Min[rt]+=k,tag[rt]+=k;
			return ;
		}
		if(tag[rt]) pushdown(rt);
		int mid=l+r>>1;
		if(R<=mid) update1(ls,l,mid,L,R,k);
		else if(L>mid) update1(rs,mid+1,r,L,R,k);
		else update1(ls,l,mid,L,R,k),update1(rs,mid+1,r,L,R,k);
		pushup(rt);
	}
	inl void update2(int rt,int l,int r,int pos,int k){
		if(l==r){
			Max[rt]=lmax[rt]=k;
			return ;
		}
		if(tag[rt]) pushdown(rt);
		int mid=l+r>>1;
		if(pos<=mid) update2(ls,l,mid,pos,k);
		else update2(rs,mid+1,r,pos,k);
		pushup(rt);
	}
	inl int query(){
		if(Min[1]==0) return n-lmax[1]-rmax[1]-sum[1];
		else return n-Max[1];
	}
}mjy;
inl void del(int x){
	if(!size(Set[x])) return ;
	mjy.update2(1,1,n,*Set[x].begin(),0);
	if(size(Set[x])>1) mjy.update1(1,1,n,*Set[x].begin(),*Set[x].rbegin()-1,-1);
}
inl void add(int x){
	if(!size(Set[x])) return ;
	mjy.update2(1,1,n,*Set[x].begin(),size(Set[x]));
	if(size(Set[x])>1) mjy.update1(1,1,n,*Set[x].begin(),*Set[x].rbegin()-1,1);
}
int main(){
//	freopen("in.txt","r",stdin);
	read(n),read(q);
	rep(i,1,n) read(a[i]),Set[a[i]].insert(i);
	rep(i,1,2e5) {
		if(!size(Set[i])) continue;
		c[*Set[i].begin()]=size(Set[i]);
		b[*Set[i].begin()]++;
		b[*Set[i].rbegin()]--;
	}
	rep(i,1,n) b[i]+=b[i-1];
	mjy.build(1,1,n);
	printf("%d\n",mjy.query());
	rep(i,1,q){
		int p,x;
		read(p),read(x);
		del(a[p]);Set[a[p]].erase(p);add(a[p]);
		del(x);Set[x].insert(p);add(x);a[p]=x;
		printf("%d\n",mjy.query());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,opv,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
}ret[N];
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	while(u!=fa[u]) u=fa[u];
	return u;
}
inline void rebuild(int l,int r,int t){
	int len=opv;
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		while(q.l!=(*p.begin()).l){
			note g=(*(--p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
				s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				ret[++opv]=s;
				continue;
			}
			break;
		}
		while(q.l!=(*p.rbegin()).l){
			note g=(*(++p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
				s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				ret[++opv]=s;
				continue;
			}
			break;
		}

	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	for(int i=c[t].size()-1;i>=0;i--){
		while(opv>len&&ret[opv].num==i){
			del c=ret[opv];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			sum[c.a]=c.c,sum[c.b]=c.d;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			opv--;
		}
		ans=ans+c[t][i].w,sum[c[t][i].t]=0;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}
}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read(); if(w[u]==c) continue;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
set<int>g[N]; bool fl[N];
int n,m,sum,w[N],pot[N],siz[N],ch[N][2],lt[N],rt[N],val[N],tag[N],pos[N],opt[N],ans[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r; if(l==r) {ch[t][0]=ch[t][1]=l,pot[l]=t; return;}
	int d=(l+r)>>1; build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void pushdown(int u){
	tag[u<<1]+=tag[u],tag[u<<1|1]+=tag[u];
	opt[u<<1]+=tag[u],opt[u<<1|1]+=tag[u],tag[u]=0;
}
inline void update(int u){
	u=u>>1;
	while(u>0) val[u]=max(val[u<<1],val[u<<1|1]),u=u>>1;
}
inline void getmax(int l,int r,int t){
	if(l>r) return;
	if(lt[t]==l&&rt[t]==r){
		sum=max(sum,val[t]); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) getmax(l,min(d,r),t<<1);
	if(d+1<=r) getmax(max(d+1,l),r,t<<1|1);
}
inline void updatex(int t){

	if(opt[t<<1]<opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0];
		ch[t][1]=ch[t<<1][1],ans[t]=ans[t<<1];
	}
	if(opt[t<<1]>opt[t<<1|1]){
		opt[t]=opt[t<<1|1],ch[t][0]=ch[t<<1|1][0];
		ch[t][1]=ch[t<<1|1][1],ans[t]=ans[t<<1|1];
	}
	if(opt[t<<1]==opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0],ch[t][1]=ch[t<<1|1][1];
		sum=0,getmax(ch[t<<1][1]+1,ch[t<<1|1][0],1);
		ans[t]=ans[t<<1]+ans[t<<1|1]+sum;
	}
}
inline void adds(int l,int r,int t,int c){//delta=c
	if(l>r) return; pushdown(t);
	if(l==lt[t]&&r==rt[t]){
		opt[t]+=c,tag[t]+=c; return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) adds(l,min(d,r),t<<1,c);
	if(d+1<=r) adds(max(d+1,l),r,t<<1|1,c);
	updatex(t);
}
inline void updatec(int u,int t){
	pushdown(t); int d=(lt[t]+rt[t])>>1;
	if(lt[t]==rt[t]) return;
	if(u<=d) updatec(u,t<<1); else updatec(u,t<<1|1);
	updatex(t);
}
inline void print_ans(){
	int a=ch[1][0],b=ch[1][1],opt=ans[1];
	sum=0,getmax(1,a,1),opt+=sum;
	sum=0,getmax(b+1,n,1),opt+=sum;
	printf("%d\n",n-opt);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),siz[w[i]]++;
	build(1,n,1);
	for(int i=1;i<=n;i++){
		if(fl[w[i]]) continue; fl[w[i]]=1;
		val[pot[*g[w[i]].begin()]]=siz[w[i]];
		update(pot[*g[w[i]].begin()]);
		adds(*g[w[i]].begin(),(*g[w[i]].rbegin())-1,1,1);
	}
	for(int i=1;i<=n;i++) updatec(i,1);
	print_ans(); int u,t;
	for(int i=1;i<=m;i++){
		u=read(),t=read();

		val[pot[*g[w[u]].begin()]]=0;
		update(pot[*g[w[u]].begin()]);
		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
		updatec(*g[w[u]].begin(),1);

		g[w[u]].erase(u),siz[w[u]]--;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=siz[w[u]];
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
			updatec(*g[w[u]].begin(),1);
		}

		w[u]=t;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=0;
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
			updatec(*g[w[u]].begin(),1);
		}

		g[w[u]].insert(u),siz[w[u]]++;

		val[pot[*g[w[u]].begin()]]=siz[w[u]];
		update(pot[*g[w[u]].begin()]);

		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
		updatec(*g[w[u]].begin(),1);

		print_ans();
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,opv,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
}ret[N];
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	if(fa[u]==u) return u; return find(fa[u]);
}
inline void rebuild(int l,int r,int t){
	int len=opv;
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		while(1){
			if(q.l!=(*p.begin()).l){
				note g=(*(--p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
					s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					ret[++opv]=s;
					continue;
				}
			}
			if(q.l!=(*p.rbegin()).l){
				note g=(*(++p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
					s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					ret[++opv]=s;
					continue;
				}
			}
			break;
		}

	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	for(int i=c[t].size()-1;i>=0;i--){
		while(opv>len&&ret[opv].num==i){
			del c=ret[opv];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			sum[c.a]=c.c,sum[c.b]=c.d;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			opv--;
		}
		ans=ans+c[t][i].w,sum[c[t][i].t]=0;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}
}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read(); if(w[u]==c) continue;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
};
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
vector<del>rf[N<<2];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	if(fa[u]==u) return u; return find(fa[u]);
}
inline void rebuild(int l,int r,int t){
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		while(1){
			if(q.l!=(*p.begin()).l){
				note g=(*(--p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
					s.e=g,s.f=q;
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					rf[t].push_back(s);
					continue;
				}
			}
			if(q.l!=(*p.rbegin()).l){
				note g=(*(++p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
					s.e=g,s.f=q;
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					rf[t].push_back(s);
					continue;
				}
			}
			break;
		}

	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	int len=rf[t].size()-1;
	for(int i=c[t].size()-1;i>=0;i--){
		while(len>=0&&rf[t][len].num==i){
			del c=rf[t][len];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			sum[c.a]=c.c,sum[c.b]=c.d;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			len--;
		}
		ans=ans+c[t][i].w,sum[c[t][i].t]=0;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}
}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read(); if(w[u]==c) continue;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
};
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
vector<del>rf[N<<2];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	if(fa[u]==u) return u; return find(fa[u]);
}
inline void rebuild(int l,int r,int t){
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		if(q.l!=(*p.begin()).l){
			note g=(*(--p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(siz[x],siz[y]);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
		if(q.l!=(*p.rbegin()).l){
			note g=(*(++p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(siz[x],siz[y]);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	int len=rf[t].size()-1;
	for(int i=c[t].size()-1;i>=0;i--){
		while(len>=0&&rf[t][len].num==i){

			del c=rf[t][len];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			len--;
		}
		ans=ans+c[t][i].w;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}

}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read();
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
};
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
vector<del>rf[N<<2];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	if(fa[u]==u) return u; return find(fa[u]);
}
inline void rebuild(int l,int r,int t){
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];

		if(q.l!=(*p.begin()).l){
			note g=(*(--p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
		if(q.l!=(*p.rbegin()).l){
			note g=(*(++p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	int len=rf[t].size()-1;
	for(int i=c[t].size()-1;i>=0;i--){
		while(len>=0&&rf[t][len].num==i){
			del c=rf[t][len];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			len--;
		}
		ans=ans+c[t][i].w;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}

}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read();
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e6+7;
set<int>g[N]; bool fl[N];
int n,m,sum,w[N],pot[N],siz[N],ch[N][2],lt[N],rt[N],val[N],tag[N],pos[N],opt[N],ans[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r; if(l==r) {ch[t][0]=ch[t][1]=l,pot[l]=t; return;}
	int d=(l+r)>>1; build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void pushdown(int u){
	tag[u<<1]+=tag[u],tag[u<<1|1]+=tag[u];
	opt[u<<1]+=tag[u],opt[u<<1|1]+=tag[u],tag[u]=0;
}
inline void update(int u){
	u=u>>1;
	while(u>0) val[u]=max(val[u<<1],val[u<<1|1]),u=u>>1;
}
inline void getmax(int l,int r,int t){
	if(l>r) return;
	if(lt[t]==l&&rt[t]==r){
		sum=max(sum,val[t]); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) getmax(l,min(d,r),t<<1);
	if(d+1<=r) getmax(max(d+1,l),r,t<<1|1);
}
inline void updatex(int t){

	if(opt[t<<1]<opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0];
		ch[t][1]=ch[t<<1][1],ans[t]=ans[t<<1];
	}
	if(opt[t<<1]>opt[t<<1|1]){
		opt[t]=opt[t<<1|1],ch[t][0]=ch[t<<1|1][0];
		ch[t][1]=ch[t<<1|1][1],ans[t]=ans[t<<1|1];
	}
	if(opt[t<<1]==opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0],ch[t][1]=ch[t<<1|1][1];
		sum=0,getmax(ch[t<<1][1]+1,ch[t<<1|1][0],1);
		ans[t]=ans[t<<1]+ans[t<<1|1]+sum;
	}
}
inline void adds(int l,int r,int t,int c){//delta=c
	if(l>r) return; pushdown(t);
	if(l==lt[t]&&r==rt[t]){
		opt[t]+=c,tag[t]+=c; return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) adds(l,min(d,r),t<<1,c);
	if(d+1<=r) adds(max(d+1,l),r,t<<1|1,c);
	updatex(t);
}
inline void updatec(int u,int t){
	pushdown(t); int d=(lt[t]+rt[t])>>1;
	if(lt[t]==rt[t]) return;
	if(u<=d) updatec(u,t<<1); else updatec(u,t<<1|1);
	updatex(t);
}
inline void print_ans(){
	int a=ch[1][0],b=ch[1][1],opt=ans[1];
	sum=0,getmax(1,a,1),opt+=sum;
	sum=0,getmax(b+1,n,1),opt+=sum;
	printf("%d\n",n-opt);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),siz[w[i]]++;
	build(1,n,1);
	for(int i=1;i<=n;i++){
		if(fl[w[i]]) continue; fl[w[i]]=1;
		val[pot[*g[w[i]].begin()]]=siz[w[i]];
		update(pot[*g[w[i]].begin()]);
		adds(*g[w[i]].begin(),(*g[w[i]].rbegin())-1,1,1);
	}
	for(int i=1;i<=n;i++) updatec(i,1);
	print_ans(); int u,t;
	for(int i=1;i<=m;i++){
		u=read(),t=read();

		val[pot[*g[w[u]].begin()]]=0;
		update(pot[*g[w[u]].begin()]);
		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
		updatec(*g[w[u]].begin(),1);

		g[w[u]].erase(u),siz[w[u]]--;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=siz[w[u]];
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
			updatec(*g[w[u]].begin(),1);
		}

		w[u]=t;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=0;
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
			updatec(*g[w[u]].begin(),1);
		}

		g[w[u]].insert(u),siz[w[u]]++;

		val[pot[*g[w[u]].begin()]]=siz[w[u]];
		update(pot[*g[w[u]].begin()]);

		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
		updatec(*g[w[u]].begin(),1);

		print_ans();
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,opv,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
}ret[N];
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	int op=0;
	while(u!=fa[u]) u=fa[u],op++;
	if(op>=60) cout<<114514<<endl;
	return u;
}
inline void rebuild(int l,int r,int t){
	int len=opv;
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		while(1){
			if(q.l!=(*p.begin()).l){
				note g=(*(--p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
					s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					ret[++opv]=s;
					continue;
				}
			}
			if(q.l!=(*p.rbegin()).l){
				note g=(*(++p.find(q)));
				if(check(g,q)){
					del s;
					p.erase(g),p.erase(q);
					int x=find(g.t),y=find(q.t);
					if(siz[x]>siz[y]) swap(x,y);
					s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
					s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
					fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
					sum[y]=max(sum[x],sum[y]);
					siz[y]+=siz[x];
					q.l=min(q.l,g.l);
					q.r=max(q.r,g.r);
					s.g=q;
					p.insert(q),s.num=i;
					ret[++opv]=s;
					continue;
				}
			}
			break;
		}

	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	for(int i=c[t].size()-1;i>=0;i--){
		while(opv>len&&ret[opv].num==i){
			del c=ret[opv];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			sum[c.a]=c.c,sum[c.b]=c.d;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			opv--;
		}
		ans=ans+c[t][i].w,sum[c[t][i].t]=0;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}
}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read(); if(w[u]==c) continue;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
};
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
vector<del>rf[N<<2];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	if(fa[u]==u) return u; return find(fa[u]);
}
inline void rebuild(int l,int r,int t){
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];

		if(q.l!=(*p.begin()).l){
			note g=(*(--p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(siz[x],siz[y]);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
		if(q.l!=(*p.rbegin()).l){
			note g=(*(++p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(siz[x],siz[y]);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y],s.p=siz[x],s.q=siz[y];
				s.e=g,s.f=q;
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				rf[t].push_back(s);
			}
		}
	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	int len=rf[t].size()-1;
	for(int i=c[t].size()-1;i>=0;i--){
		while(len>=0&&rf[t][len].num==i){

			del c=rf[t][len];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			len--;
		}
		ans=ans+c[t][i].w;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}

}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read();
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
set<int>g[N]; bool fl[N];
int n,m,sum,w[N],pot[N],siz[N],ch[N<<2][2],lt[N<<2],rt[N<<2],val[N<<2],tag[N<<2],pos[N<<2],opt[N<<2],ans[N<<2];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r; if(l==r) {ch[t][0]=ch[t][1]=l,pot[l]=t; return;}
	int d=(l+r)>>1; build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void pushdown(int u){
	tag[u<<1]+=tag[u],tag[u<<1|1]+=tag[u];
	opt[u<<1]+=tag[u],opt[u<<1|1]+=tag[u],tag[u]=0;
}
inline void update(int u){
	u=u>>1;
	while(u>0) val[u]=max(val[u<<1],val[u<<1|1]),u=u>>1;
}
inline void getmax(int l,int r,int t){
	if(l>r) return;
	if(lt[t]==l&&rt[t]==r){
		sum=max(sum,val[t]); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) getmax(l,min(d,r),t<<1);
	if(d+1<=r) getmax(max(d+1,l),r,t<<1|1);
}
inline void updatex(int t){

	if(opt[t<<1]<opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0];
		ch[t][1]=ch[t<<1][1],ans[t]=ans[t<<1];
	}
	if(opt[t<<1]>opt[t<<1|1]){
		opt[t]=opt[t<<1|1],ch[t][0]=ch[t<<1|1][0];
		ch[t][1]=ch[t<<1|1][1],ans[t]=ans[t<<1|1];
	}
	if(opt[t<<1]==opt[t<<1|1]){
		opt[t]=opt[t<<1],ch[t][0]=ch[t<<1][0],ch[t][1]=ch[t<<1|1][1];
		sum=0,getmax(ch[t<<1][1]+1,ch[t<<1|1][0],1);
		ans[t]=ans[t<<1]+ans[t<<1|1]+sum;
	}
}
inline void adds(int l,int r,int t,int c){//delta=c
	if(l>r) return; pushdown(t);
	if(l==lt[t]&&r==rt[t]){
		opt[t]+=c,tag[t]+=c; return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) adds(l,min(d,r),t<<1,c);
	if(d+1<=r) adds(max(d+1,l),r,t<<1|1,c);
	updatex(t);
}
inline void updatec(int u,int t){
	pushdown(t); int d=(lt[t]+rt[t])>>1;
	if(lt[t]==rt[t]) return;
	if(u<=d) updatec(u,t<<1); else updatec(u,t<<1|1);
	updatex(t);
}
inline void print_ans(){
	int a=ch[1][0],b=ch[1][1],opt=ans[1];
	sum=0,getmax(1,a,1),opt+=sum;
	sum=0,getmax(b+1,n,1),opt+=sum;
	printf("%d\n",n-opt);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),siz[w[i]]++;
	build(1,n,1);
	for(int i=1;i<=n;i++){
		if(fl[w[i]]) continue; fl[w[i]]=1;
		val[pot[*g[w[i]].begin()]]=siz[w[i]];
		update(pot[*g[w[i]].begin()]);
		adds(*g[w[i]].begin(),(*g[w[i]].rbegin())-1,1,1);
	}
	for(int i=1;i<=n;i++) updatec(i,1);
	print_ans(); int u,t;
	for(int i=1;i<=m;i++){
		u=read(),t=read();

		val[pot[*g[w[u]].begin()]]=0;
		update(pot[*g[w[u]].begin()]);
		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
		updatec(*g[w[u]].begin(),1);

		g[w[u]].erase(u),siz[w[u]]--;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=siz[w[u]];
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
			updatec(*g[w[u]].begin(),1);
		}

		w[u]=t;

		if(siz[w[u]]){
			val[pot[*g[w[u]].begin()]]=0;
			update(pot[*g[w[u]].begin()]);
			adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,-1);
			updatec(*g[w[u]].begin(),1);
		}

		g[w[u]].insert(u),siz[w[u]]++;

		val[pot[*g[w[u]].begin()]]=siz[w[u]];
		update(pot[*g[w[u]].begin()]);

		adds(*g[w[u]].begin(),(*g[w[u]].rbegin())-1,1,1);
		updatec(*g[w[u]].begin(),1);

		print_ans();
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7; bool fl[N];
int n,m,ans,opv,fa[N],sum[N],siz[N],res[N],lt[N<<2],rt[N<<2],w[N],t[N]; set<int>g[N];
struct node{
	int l,r,w,t;
};
struct note{
	int l,r,t;
};
struct del{
	int a,b,c,d,p,q,num;
	note e,f,g;
}ret[N];
inline bool operator < (note a,note b){
	return a.l<b.l;
}
vector<node>c[N<<2]; set<note>p;
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline void write(int u){
	if(u>9) write(u/10); putchar(u%10+48);
}
inline void build(int l,int r,int t){
	lt[t]=l,rt[t]=r;
	if(l==r) return; int d=(l+r)>>1;
	build(l,d,t<<1),build(d+1,r,t<<1|1);
}
inline void addit(int l,int r,node q,int t){
	if(l==lt[t]&&r==rt[t]){
		c[t].push_back(q); return;
	}
	int d=(lt[t]+rt[t])>>1;
	if(l<=d) addit(l,min(d,r),q,t<<1);
	if(d+1<=r) addit(max(d+1,l),r,q,t<<1|1);
}
inline bool check(note a,note b){
	if(b.l<a.l&&a.l<b.r) return true;
	if(a.l<b.l&&b.l<a.r) return true;
	return false;
}
inline int find(int u){
	while(u!=fa[u]) u=fa[u];
	return u;
}
inline void rebuild(int l,int r,int t){
	int len=opv;
	for(int i=0;i<c[t].size();i++){
		note q; q.l=c[t][i].l,q.r=c[t][i].r,q.t=c[t][i].t;
		p.insert(q); sum[q.t]=c[t][i].w,ans-=sum[q.t];
		while(q.l!=(*p.begin()).l){
			note g=(*(--p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
				s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				ret[++opv]=s;
				continue;
			}
		}
		while(q.l!=(*p.rbegin()).l){
			note g=(*(++p.find(q)));
			if(check(g,q)){
				del s;
				p.erase(g),p.erase(q);
				int x=find(g.t),y=find(q.t);
				if(siz[x]>siz[y]) swap(x,y);
				s.a=x,s.b=y,s.c=sum[x],s.d=sum[y];
				s.e=g,s.f=q,s.p=siz[x],s.q=siz[y];
				fa[x]=y,ans=ans+sum[x]+sum[y]-max(sum[x],sum[y]);
				sum[y]=max(sum[x],sum[y]);
				siz[y]+=siz[x];
				q.l=min(q.l,g.l);
				q.r=max(q.r,g.r);
				s.g=q;
				p.insert(q),s.num=i;
				ret[++opv]=s;
				continue;
			}
		}

	}
	if(l==r){
		write(ans),putchar('\n');
	}
	else{
		int d=(l+r)>>1;
		rebuild(l,d,t<<1),rebuild(d+1,r,t<<1|1);
	}
	for(int i=c[t].size()-1;i>=0;i--){
		while(opv>len&&ret[opv].num==i){
			del c=ret[opv];
			fa[c.a]=c.a;
			ans=ans-min(c.c,c.d);
			siz[c.a]=c.p,siz[c.b]=c.q;
			sum[c.a]=c.c,sum[c.b]=c.d;
			p.erase(c.g),p.insert(c.e),p.insert(c.f);
			opv--;
		}
		ans=ans+c[t][i].w,sum[c[t][i].t]=0;
		note h; h.l=c[t][i].l,h.r=c[t][i].r,h.t=c[t][i].t; p.erase(h);
	}
}
int main(){
	n=read(),m=read(),ans=n; int u,c; node q; build(0,m,1);
	for(int i=1;i<=2e5;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) w[i]=read(),g[w[i]].insert(i),res[w[i]]++;
	for(int i=1;i<=m;i++){
		u=read(),c=read(); if(w[u]==c) continue;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		g[w[u]].erase(u),res[w[u]]--,t[w[u]]=i,w[u]=c;
		if(res[w[u]]) q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],i-1,q,1);
		res[w[u]]++,t[w[u]]=i,g[w[u]].insert(u);
	}
	for(int u=1;u<=n;u++){
		if(fl[w[u]]) continue; fl[w[u]]=1; node q;
		q.l=(*g[w[u]].begin()),q.r=(*g[w[u]].rbegin()),q.w=res[w[u]],q.t=w[u],addit(t[w[u]],m,q,1);
	}
	rebuild(0,m,1);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int sz=4e5+10;
struct el
{
    int l=0, r=0, su=0, mi, ma, add=0;
};
el dot[sz*4];

void push(int nu)
{
    dot[nu*2].add+=dot[nu].add;
    dot[nu*2+1].add+=dot[nu].add;
    dot[nu].add=0;
}
void recalc(int nu)
{
    int lmi=dot[nu*2].mi+dot[nu*2].add, rmi=dot[nu*2+1].mi+dot[nu*2+1].add;

    dot[nu].mi=min(lmi, rmi);
    dot[nu].ma=max(dot[nu*2].ma, dot[nu*2+1].ma);

    if(lmi<rmi)
    {
        dot[nu].l=dot[nu*2].l;
        dot[nu].r=max(dot[nu*2].r, dot[nu*2+1].ma);
        dot[nu].su=dot[nu*2].su;
    }
    if(lmi>rmi)
    {
        dot[nu].l=max(dot[nu*2].ma, dot[nu*2+1].l);
        dot[nu].r=dot[nu*2+1].r;
        dot[nu].su=dot[nu*2+1].su;
    }
    if(lmi==rmi)
    {
        dot[nu].l=dot[nu*2].l;
        dot[nu].r=dot[nu*2+1].r;
        dot[nu].su=dot[nu*2].su+max(dot[nu*2].r, dot[nu*2+1].l)+dot[nu*2+1].su;
    }
}
int n, qq, ar[sz], q[sz];
void build(int nu, int l, int r)
{
    if(l==r)
    {
        dot[nu].mi=ar[l], dot[nu].ma=q[l];
    }
    else
    {
        int mid=(l+r)>>1;
        build(nu*2, l, mid);
        build(nu*2+1, mid+1, r);
        recalc(nu);
    }
}
int lg, rg, va;
void cha(int nu, int l, int r)
{
    if(l>=lg and r<=rg) dot[nu].add+=va;
    else if(!(l>rg or r<lg))
    {
        int mid=(l+r)>>1;
        push(nu);
        cha(nu*2, l, mid);
        cha(nu*2+1, mid+1, r);
        recalc(nu);
    }
}
int p;
void cha2(int nu, int l, int r)
{
    if(l==r) dot[nu].ma=q[l];
    else
    {
        int mid=(l+r)>>1;
        push(nu);
        if(p<=mid) cha2(nu*2, l, mid);
        else cha2(nu*2+1, mid+1, r);
        recalc(nu);
    }
}
set <int> se[sz];
void f(int i, int ty)
{
    if(se[i].size())
    {
        int l=*se[i].begin();
        auto it=se[i].end();
        it--;
        int r=*it;

        lg=l*2+1, rg=r*2+1, va=ty, cha(1, 0, n*2);

        q[l*2+1]=(ty==1) ? se[i].size() : 0, p=l*2+1, cha2(1, 0, n*2);
    }
}
main()
{
    //freopen("input.txt", "r", stdin);
    cin>>n>>qq;
    int ch[n];
    for(int a=0; a<n; a++)
    {
        scanf("%d", &ch[a]);
        se[ch[a]].insert(a);
    }
    for(int a=0; a<sz; a++)
    {
        if(se[a].size())
        {
            int l=*se[a].begin();
            auto it=se[a].end();
            it--;
            int r=*it;
            ar[l*2+1]++, ar[r*2+2]--;
            q[l*2+1]=se[a].size();
        }
    }
    int cu=0;
    for(int a=0; a<=n*2; a++) cu+=ar[a], ar[a]=cu;
    build(1, 0, n*2);
    printf("%d\n", n-dot[1].su);
    for(int a=0; a<qq; a++)
    {
        int i, x;
        scanf("%d%d", &i, &x);
        i--;
        f(ch[i], -1);
        se[ch[i]].erase(i);
        f(ch[i], 1);
        ch[i]=x;
        f(ch[i], -1);
        se[ch[i]].insert(i);
        f(ch[i], 1);
        printf("%d\n", n-dot[1].su);
    }
}


#include <bits/stdc++.h>
#define il inline
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define mid ((l+r)>>1)
#define MAXN 200050 * 4
#define MV 5000000
#define mod
#define inf (1<<30)
#define eps (1e-6)
#define alpha 0.75
#define rep(i, x, y) for(register int i = x; i <= (y); ++i)
#define repd(i, x, y) for(register int i = x; i >= (y); --i)
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define int ll
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
typedef pair <ll, ll> pll;
template <typename T> il bool chkmin(T &x, T y) {return x > y ? x = y, 1 : 0;}
template <typename T> il bool chkmax(T &x, T y) {return x < y ? x = y, 1 : 0;}
template <typename T> il void read(T &x) {
	char ch = getchar(); int f = 1; x = 0;
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') x = x*10+ch-'0', ch = getchar();
	x *= f;
}
template <typename T, typename... Args> il void read(T &x, Args &...args) {
	read(x), read(args...);
}
int n, m, a[MAXN];
set<int> se[MAXN];
int minv[MAXN << 2], cnt[MAXN << 2], maxwl[MAXN << 2], maxwr[MAXN << 2], maxw[MAXN << 2], tag[MAXN << 2];
ll sum[MAXN << 2];
void put_tag(int u, int w) {
	minv[u] += w, tag[u] += w;
}
void push(int u) {
	if(tag[u]) put_tag(u << 1, tag[u]), put_tag(u << 1 | 1, tag[u]), tag[u] = 0;
}
void update(int u) {
	minv[u] = min(minv[u << 1], minv[u << 1 | 1]);
	maxw[u] = max(maxw[u << 1], maxw[u << 1 | 1]);
	if(minv[u << 1] == minv[u << 1 | 1]) {
		maxwl[u] = maxwl[u << 1], maxwr[u] = maxwr[u << 1 | 1];
		sum[u] = sum[u << 1] + sum[u << 1 | 1] + max(maxwr[u << 1], maxwl[u << 1 | 1]);
		cnt[u] = cnt[u << 1] + cnt[u << 1 | 1];
	}
	else if(minv[u << 1] < minv[u << 1 | 1])
		maxwl[u] = maxwl[u << 1], maxwr[u] = max(maxwr[u << 1], maxw[u << 1 | 1]), sum[u] = sum[u << 1], cnt[u] = cnt[u << 1];
	else maxwr[u] = maxwr[u << 1 | 1], maxwl[u] = max(maxwl[u << 1 | 1], maxw[u << 1]), sum[u] = sum[u << 1 | 1], cnt[u] = cnt[u << 1 | 1];
}
void modify(int u, int l, int r, int tl, int tr, int w) {
	if(tl > tr) return ;
	if(tl <= l && r <= tr) return put_tag(u, w);
	push(u);
	if(tl <= mid) modify(u << 1, l, mid, tl, tr, w);
	if(mid < tr) modify(u << 1 | 1, mid+1, r, tl, tr, w);
	update(u);
}
void change(int u, int l, int r, int x, int w) {
	if(l == r) return (void)(minv[u] = maxw[u] = maxwl[u] = maxwr[u] = w);
	push(u);
	if(x <= mid) change(u << 1, l, mid, x, w);
	else change(u << 1 | 1, mid+1, r, x, w);
	update(u);
}
void replace(int x, int y) {
	int pr = a[x], nx = y;
	int _beg = *se[pr].begin(), _end = *se[pr].rbegin();
	change(1, 0, 2 * n, _beg * 2 - 1, MV);
	modify(1, 0, 2 * n, _beg * 2, _end * 2 - 2, -1);
	if(se[nx].size()) {
		_beg = *se[nx].begin(), _end = *se[nx].rbegin();
		change(1, 0, 2 * n, _beg * 2 - 1, MV);
		modify(1, 0, 2 * n, _beg * 2, _end * 2 - 2, -1);
	}
	se[a[x]].erase(x), se[a[x] = y].insert(x);
	if(se[pr].size()) {
		_beg = *se[pr].begin(), _end = *se[pr].rbegin();
		change(1, 0, 2 * n, _beg * 2 - 1, MV + se[pr].size());
		modify(1, 0, 2 * n, _beg * 2, _end * 2 - 2, 1);
	}
	_beg = *se[nx].begin(), _end = *se[nx].rbegin();
	change(1, 0, 2 * n, _beg * 2 - 1, MV + se[nx].size());
	modify(1, 0, 2 * n, _beg * 2, _end * 2 - 2, 1);
}
void build(int u, int l, int r) {
	if(l == r) return (void)(cnt[u] = 1);
	build(u << 1, l, mid), build(u << 1 | 1, mid+1, r);
	update(u);
}
signed main() {
	int x, y;
	read(n, m);
	rep(i, 1, n) se[0].insert(i);
	rep(i, 1, n) change(1, 0, 2 * n, i * 2 - 1, MV);
	build(1, 0, 2 * n);
	change(1, 0, 2 * n, 1, n + MV);
	modify(1, 0, 2 * n, 2, 2 * n - 2, 1);
	rep(i, 1, n) read(x), replace(i, x);
	printf("%lld\n", n - (sum[1] - (cnt[1] - 1) * MV));
	while(m--)
		read(x, y), replace(x, y), printf("%lld\n", n - (sum[1] - (cnt[1] - 1) * MV));
	return 0;
}