#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 20010
#define maxlim 150
using namespace std;
inline void read(int &x) {
char ch;
bool flag = false;
for (ch = getchar(); !isdigit(ch); ch = getchar())if (ch == '-') flag = true;
for (x = 0; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
x = flag ? -x : x;
}
inline void write(int x) {
static const int maxlen = 100;
static char s[maxlen];
if (x < 0) { putchar('-'); x = -x;}
if (!x) { putchar('0'); return; }
int len = 0; for (; x; x /= 10) s[len++] = x % 10 + '0';
for (int i = len - 1; i >= 0; --i) putchar(s[i]);
}
int lim;
int block[2*maxlim][2*maxlim];
int siz[maxlim] , cnt;
int pree[2*maxlim],nextt[2*maxlim];
int n,m;
int tree[2*maxlim][maxn];
int ans=0;
int get_pos(int &x){
int now=1;
while ( ( siz[now]<x) && ( nextt[now] ) )
{
x-=siz[now];
now=nextt[now];
}
return now;
}
int lowbit(int x){
return x & (-x);
}
void add(int pos,int x,int op){
while (x<=n)
{
tree[pos][x]+=op;
x+=lowbit(x);
}
}
int query(int pos,int x){
int tmp=0;
while (x)
{
tmp+=tree[pos][x];
x-=lowbit(x);
}
return tmp;
}
void build(int a,int b){
pree[b]=a; nextt[a]=b;
}
void rebuild(int x){
memset(tree[x],0,sizeof (tree[x]));
for (int i=1;i<=siz[x];i++)
add( x , block[x][i] ,1);
}
void calc(int at_block,int v,int at_in,int op){
int tmp=at_block;
while ( pree[tmp] )
{
tmp=pree[tmp];
ans+=( siz[tmp]-query(tmp,v) )*op;
}
tmp=at_block;
while ( nextt[tmp] )
{
tmp=nextt[tmp];
ans+=query( tmp ,v-1 )*op;
}
for (int i=1;i<=at_in;i++)
if (block[ at_block ][i]>v)
ans+=op;
for (int i=at_in+1;i<=siz[ at_block ];i++)
if (block[ at_block ][i]<v)
ans+=op;
}
void watch(){
for (int i=1;i;i=nextt[i])
{
printf("val= ");
for (int j=1;j<=siz[ i ];j++)
printf(" %d ",block[i][j] );
puts("");
}
}
void ins(int pos,int v){
int at_block=get_pos(pos);
calc(at_block,v,pos,1);
add(at_block , v ,1);
memmove(block[at_block]+pos+2,block[at_block]+pos+1, sizeof(int)*(siz[ at_block ]-pos) );
block[ at_block ][ pos+1 ]=v;
siz[ at_block ]++;
if (siz[at_block]>=2*lim)
{
++cnt;
build(cnt,nextt[at_block ] );
build(at_block ,cnt);
siz[cnt]=lim;
siz[at_block]=lim;
memcpy(block[cnt]+1,block[at_block]+lim+1,sizeof(int)*lim);
rebuild(at_block );
rebuild(cnt);
}
}
void Delete(int pos){
int at_block=get_pos(pos);
calc(at_block, block[ at_block ][ pos ] ,pos,-1);
add(at_block, block[ at_block ][ pos ] ,-1);
memmove(block[at_block]+pos,block[at_block ]+pos+1, sizeof(int)*(siz[at_block]-pos) );
siz[ at_block ]--;
if (siz[at_block]==0)
{
if (at_block!=1)
build(pree[at_block],nextt[at_block]);
}
}
int main(){
while (scanf("%d%d",&n,&m)!=EOF)
{
cnt=1;
pree[1]=0; nextt[1]=0;
siz[1]=0;
lim=sqrt(n);
ans=0;
for (int i=1;i<=n;i++)
{
int x;
read(x);
ins( i-1 , x);
}
for (int i=1;i<=m;i++)
{
int op;
read(op);
if (op==0)
{
int x,pos;
read(pos); read(x);
ins(pos,x);
printf("%d\n",ans);
}
else
{
int x;
read(x);
Delete(x);
printf("%d\n",ans);
}
}
}
return 0;
}