#include <cstdio>
#include <algorithm>

using namespace std;
using LL=long long;

int k, n, a[200005];
LL sum[200005], ans;

int main() {
    scanf("%d%d", &n, &k);
    if (k == 1) {
        putchar('0');
        return 0;
    }
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    sort(a + 1, a + n + 1);
    int md = a[n + 1 >> 1], c[2] = {0, 0};
    for (int i = 1; i <= n; i++) {
        sum[i] = sum[i - 1] + a[i];
        if (a[i] <= md)
            ans += md - a[i], c[0]++;
        else
            ans += a[i] - md - 1, c[1]++;
    }
    ans += max(k - max(c[0], c[1]), 0);
    ans = min(ans, sum[n] - sum[n - k + 1] - (LL) (k - 1) * a[n - k + 1]);
    ans = min(ans, (LL) (k - 1) * a[k] - sum[k - 1]);
    printf("%lld", ans);
    return 0;
}


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1700;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1900;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);

			if (pf[i] > sf[i+1]) {
				P[x].pb(pf[i]);
				S[x].pb(sf[i+1]);
				cnt[x]++;
			}
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for (len = 0; len * Magic <= n; ++len) {
		upd(len);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1777;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1700;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			if(pref < a[L[i]])
				res -= S[i].end() - ub(every(S[i]), pref);
			if(suff[i] > a[R[i]])
				res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1700;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			if(pref < a[L[i]])
				res -= S[i].end() - ub(every(S[i]), pref);
			if(suff[i] > a[R[i]])
				res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		L[len] = max(1, len * Magic);
		R[len] = min(n, (len + 1) * Magic - 1);

		upd(len++);
	}

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);

		if (a[p] != x) {
			a[p] = x;
			upd (p/Magic);
		}

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1700;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			if(pref < a[L[i]])
				res -= S[i].end() - ub(every(S[i]), pref);
			if(suff[i] > a[R[i]])
				res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")

//# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 2101;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];

inline int calc() {
	int res = 1;
	pf[0] = inf;
	for (int i = 1; i <= n; ++i) {
		pf[i] = min(pf[i-1], a[i]);
	}
	for (int i = n; i >= 1; --i) {
		sf[i] = max(sf[i+1], a[i]);
	}
	for (int i = 1; i < n; ++i)
		if (pf[i] > sf[i+1])
			++res;
	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 2e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1700;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 3];
int len;
vector < int > P[Magic + 3], S[Magic + 3];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1900;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1650;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1900;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);

			if (i + 1 <= n && pf[i] > sf[i+1]) {
				P[x].pb(pf[i]);
				S[x].pb(sf[i+1]);
				cnt[x]++;
			}
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			for (int j = L[i]; j <= R[i] && j < n; ++j) {
			    if(max(suff[i], sf[j+1]) < min(pref, pf[j])) {

			    	//cout << j << ' ';
					res++;
				}
			}
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


#pragma GCC target("avx2")
#pragma GCC optimize("O3")

# include <x86intrin.h>
# include <bits/stdc++.h>

//# include <ext/pb_ds/assoc_container.hpp>
//# include <ext/pb_ds/tree_policy.hpp>

//using namespace __gnu_pbds;
using namespace std;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++)
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                Red

inline void Input_Output () {
	//freopen(".in", "r", stdin);
   //freopen(".out", "w", stdout);
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e8 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;
const int M = 22;
const int pri = 997;
const int Magic = 1550;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

int n, m, k;
int a[N];
int pf[N];
int sf[N];
int cnt[N];
int L[N], R[N];
int suff[Magic + 5];
int len;
vector < int > P[Magic + 5], S[Magic + 5];

inline void upd (int x) {
	L[x] = max(1, x * Magic);
	R[x] = min(n, (x + 1) * Magic - 1);

	cnt[x] = 0;
	P[x].clear();
	S[x].clear();
	for (int i = L[x]; i <= R[x]; ++i) {
		pf[i] = a[i];
		if (i > L[x]) pf[i] = min(pf[i], pf[i-1]);
	}

	for (int i = R[x]; i >= L[x]; --i) {
		sf[i] = a[i];
		if (i < R[x]) {
			sf[i] = max(sf[i], sf[i+1]);
		}
		if (i < n && pf[i] > sf[i+1]) {
			P[x].pb(pf[i]);
			S[x].pb(sf[i+1]);
			cnt[x]++;
		}
	}
}

inline int calc() {
	int res = 1;

	suff[len] = 0;
	for (int i = len; i > 0; --i) {
		suff[i-1] = max(suff[i], sf[L[i]]);
	}
	int pref = inf;
	//cout << "now: ";
	for (int i = 0; i < len; ++i) {
		if (pref > suff[i]) {
			res += cnt[i];
			res -= S[i].end() - ub(every(S[i]), pref);
			res -= lb(every(P[i]), suff[i]) - P[i].begin();
		}

		pref = min(pref, pf[R[i]]);
	}
	//cout << '\n';

	return res;
}

int main () {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}

	for(; len * Magic <= n; ) {
		upd(len++);
	}
	//exit(0);

	for (int i = 1, p, x; i <= m; ++i) {
		scanf("%d%d", &p, &x);
		a[p] = x;
		upd (p/Magic);
	//	exit(0);

		printf("%d\n", calc());
	}

	return Accepted;
}

// B...a


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

#define MAXN 1000007
#define MAXVAL 1000002

int n , q ;
int a[ MAXN ] ;

class Tree {
public :
    int tr[ 4 * MAXN ] ;
    pair < int , int > valid[ 4 * MAXN ] ;
    int lazy[ 4 * MAXN ] ;
    void init ( int where , int IL , int IR ) {
        tr[ where ] = 0 ;
        valid[ where ] = { 10 * MAXN , 0 } ;
        if ( IL == IR ) { return ; }
        int mid = ( IL + IR ) / 2 ;
        init ( 2 * where , IL , mid ) ;
        init ( 2 * where + 1 , mid + 1 , IR ) ;
    }
    void unite ( int where , int ls , int rs ) {
        tr[ where ] = min ( tr[ ls ] , tr[ rs ] ) ;
        valid[ where ].first = min ( valid[ ls ].first , valid[ rs ].first ) ;
        valid[ where ].second = ( valid[ where ].first == valid[ ls ].first ) * valid[ ls ].second
                            + ( valid[ where ].first == valid[ rs ].first ) * valid[ rs ].second ;
    }
    void push_lazy ( int where , int IL , int IR ) {
        if ( lazy[ where ] == 0 ) { return ; }
        tr[ where ] += lazy[ where ] ;
        valid[ where ].first += lazy[ where ] ;
        if ( IL != IR ) {
            lazy[ 2 * where ] += lazy[ where ] ;
            lazy[ 2 * where + 1 ] += lazy[ where ] ;
        }
        lazy[ where ] = 0 ;
    }

    void update ( int where , int IL , int IR , int CURL , int CURR , int val ) {
        push_lazy ( where , IL , IR ) ;
        if ( IL > IR || CURL > CURR ) { return ; }
        if ( IR < CURL || CURR < IL ) { return ; }
        if ( CURL <= IL && IR <= CURR ) {
            lazy[ where ] += val ;
            push_lazy ( where , IL , IR ) ;
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        update ( 2 * where , IL , mid , CURL , CURR , val ) ;
        update ( 2 * where + 1 , mid + 1 , IR , CURL , CURR , val ) ;
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
    void act ( int where , int IL , int IR , int pos , int nw ) {
        push_lazy ( where , IL , IR ) ;
        if ( IR < pos || pos < IL ) { return ; }
        if ( IL == IR ) {
            if ( nw == 1 ) {
                valid[ where ] = { tr[ where ] , 1 } ;
            }
            else {
                valid[ where ] = { 10 * MAXN , 0 } ;
            }
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        act ( 2 * where , IL , mid , pos , nw ) ;
        act ( 2 * where + 1 , mid + 1 , IR , pos , nw ) ;
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
};
Tree w ;

void handle ( int pos , int coef ) {
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos - 1 ] , a[ pos ] ) + 1 , max ( a[ pos - 1 ] , a[ pos ] ) , coef ) ;
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos ] , a[ pos + 1 ] ) + 1 , max ( a[ pos ] , a[ pos + 1 ] ) , coef ) ;
}

void input ( ) {
    scanf ( "%d%d" , &n , &q ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d" , &a[ i ] ) ;
    }
    a[ 0 ] = MAXVAL ;
    a[ n + 1 ] = 0 ;
    w.init ( 1 , 1 , MAXVAL ) ;
    for ( int i = 1 ; i <= n + 1 ; ++ i ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ i - 1 ] , a[ i ] ) + 1 , max ( a[ i - 1 ] , a[ i ] ) , 1 ) ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        w.act ( 1 , 1 , MAXVAL , a[ i ] , 1 ) ;
    }
}

void solve ( ) {
    while ( q -- ) {
        int pos , x ;
        scanf ( "%d%d" , &pos , &x ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 0 ) ;
        handle ( pos , -1 ) ;
        a[ pos ] = x ;
        handle ( pos , 1 ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 1 ) ;
        printf ( "%d\n" , w.valid[ 1 ].second ) ;
    }
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    input ( ) ;
    solve ( ) ;
    return 0 ;
}


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

#define MAXN 1000007
#define MAXVAL 1000002

int n , q ;
int a[ MAXN ] ;

class Tree {
public :
    int tr[ 4 * MAXN ] ;
    pair < int , int > valid[ 4 * MAXN ] ;
    int lazy[ 4 * MAXN ] ;
    void init ( int where , int IL , int IR ) {
        tr[ where ] = 0 ;
        valid[ where ] = { 10 * MAXN , 0 } ;
        if ( IL == IR ) { return ; }
        int mid = ( IL + IR ) / 2 ;
        init ( 2 * where , IL , mid ) ;
        init ( 2 * where + 1 , mid + 1 , IR ) ;
    }
    void unite ( int where , int ls , int rs ) {
        tr[ where ] = min ( tr[ ls ] , tr[ rs ] ) ;
        valid[ where ].first = min ( valid[ ls ].first , valid[ rs ].first ) ;
        valid[ where ].second = ( valid[ where ].first == valid[ ls ].first ) * valid[ ls ].second
                            + ( valid[ where ].first == valid[ rs ].first ) * valid[ rs ].second ;
    }
    void push_lazy ( int where , int IL , int IR ) {
        if ( lazy[ where ] == 0 ) { return ; }
        tr[ where ] += lazy[ where ] ;
        valid[ where ].first += lazy[ where ] ;
        if ( IL != IR ) {
            lazy[ 2 * where ] += lazy[ where ] ;
            lazy[ 2 * where + 1 ] += lazy[ where ] ;
        }
        lazy[ where ] = 0 ;
    }

    void update ( int where , int IL , int IR , int CURL , int CURR , int val ) {
        push_lazy ( where , IL , IR ) ;
        if ( IL > IR || CURL > CURR ) { return ; }
        if ( IR < CURL || CURR < IL ) { return ; }
        if ( CURL <= IL && IR <= CURR ) {
            lazy[ where ] += val ;
            push_lazy ( where , IL , IR ) ;
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        update ( 2 * where , IL , mid , CURL , CURR , val ) ;
        update ( 2 * where + 1 , mid + 1 , IR , CURL , CURR , val ) ;
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
    void act ( int where , int IL , int IR , int pos , int nw ) {
        push_lazy ( where , IL , IR ) ;
        if ( IR < pos || pos < IL ) { return ; }
        if ( IL == IR ) {
            if ( nw == 1 ) {
                valid[ where ] = { tr[ where ] , 1 } ;
            }
            else {
                valid[ where ] = { 10 * MAXN , 0 } ;
            }
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        if ( pos <= mid ) {
            act ( 2 * where , IL , mid , pos , nw ) ;
        }
        else {
            act ( 2 * where + 1 , mid + 1 , IR , pos , nw ) ;
        }
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
};
Tree w ;

void handle ( int pos , int coef ) {
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos - 1 ] , a[ pos ] ) + 1 , max ( a[ pos - 1 ] , a[ pos ] ) , coef ) ;
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos ] , a[ pos + 1 ] ) + 1 , max ( a[ pos ] , a[ pos + 1 ] ) , coef ) ;
}

void input ( ) {
    scanf ( "%d%d" , &n , &q ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d" , &a[ i ] ) ;
    }
    a[ 0 ] = MAXVAL ;
    a[ n + 1 ] = 0 ;
    w.init ( 1 , 1 , MAXVAL ) ;
    for ( int i = 1 ; i <= n + 1 ; ++ i ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ i - 1 ] , a[ i ] ) + 1 , max ( a[ i - 1 ] , a[ i ] ) , 1 ) ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        w.act ( 1 , 1 , MAXVAL , a[ i ] , 1 ) ;
    }
}

void solve ( ) {
    while ( q -- ) {
        int pos , x ;
        scanf ( "%d%d" , &pos , &x ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 0 ) ;
        handle ( pos , -1 ) ;
        a[ pos ] = x ;
        handle ( pos , 1 ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 1 ) ;
        printf ( "%d\n" , w.valid[ 1 ].second ) ;
    }
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    input ( ) ;
    solve ( ) ;
    return 0 ;
}


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

#define MAXN 1000007
#define MAXVAL 1000000

int n , q ;
int a[ MAXN ] ;

class Tree {
public :
    int tr[ 4 * MAXN ] ;
    pair < int , int > valid[ 4 * MAXN ] ;
    int lazy[ 4 * MAXN ] ;
    void init ( int where , int IL , int IR ) {
        tr[ where ] = 0 ;
        valid[ where ] = { 10 * MAXN , 0 } ;
        if ( IL == IR ) { return ; }
        int mid = ( IL + IR ) / 2 ;
        init ( 2 * where , IL , mid ) ;
        init ( 2 * where + 1 , mid + 1 , IR ) ;
    }
    void unite ( int where , int ls , int rs ) {
        tr[ where ] = min ( tr[ ls ] , tr[ rs ] ) ;
        valid[ where ].first = min ( valid[ ls ].first , valid[ rs ].first ) ;
        valid[ where ].second = ( valid[ where ].first == valid[ ls ].first ) * valid[ ls ].second
                            + ( valid[ where ].first == valid[ rs ].first ) * valid[ rs ].second ;
    }
    void push_lazy ( int where , int IL , int IR ) {
        if ( lazy[ where ] == 0 ) { return ; }
        tr[ where ] += lazy[ where ] ;
        valid[ where ].first += lazy[ where ] ;
        if ( IL != IR ) {
            lazy[ 2 * where ] += lazy[ where ] ;
            lazy[ 2 * where + 1 ] += lazy[ where ] ;
        }
        lazy[ where ] = 0 ;
    }

    void update ( int where , int IL , int IR , int CURL , int CURR , int val ) {
        push_lazy ( where , IL , IR ) ;
        if ( IL > IR || CURL > CURR ) { return ; }
        if ( IR < CURL || CURR < IL ) { return ; }
        if ( CURL <= IL && IR <= CURR ) {
            lazy[ where ] += val ;
            push_lazy ( where , IL , IR ) ;
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        update ( 2 * where , IL , mid , CURL , CURR , val ) ;
        update ( 2 * where + 1 , mid + 1 , IR , CURL , CURR , val ) ;
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
    void act ( int where , int IL , int IR , int pos , int nw ) {
        push_lazy ( where , IL , IR ) ;
        if ( IR < pos || pos < IL ) { return ; }
        if ( IL == IR ) {
            if ( nw == 1 ) {
                valid[ where ] = { tr[ where ] , 1 } ;
            }
            else {
                valid[ where ] = { 10 * MAXN , 0 } ;
            }
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        if ( pos <= mid ) {
            act ( 2 * where , IL , mid , pos , nw ) ;
        }
        else {
            act ( 2 * where + 1 , mid + 1 , IR , pos , nw ) ;
        }
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
};
Tree w ;

void handle ( int pos , int coef ) {
    if ( pos > 1 ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ pos - 1 ] , a[ pos ] ) + 1 , max ( a[ pos - 1 ] , a[ pos ] ) , coef ) ;
    }
    if ( pos < n ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ pos ] , a[ pos + 1 ] ) + 1 , max ( a[ pos ] , a[ pos + 1 ] ) , coef ) ;
    }
}

void input ( ) {
    scanf ( "%d%d" , &n , &q ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d" , &a[ i ] ) ;
    }
    a[ 0 ] = MAXVAL ;
    a[ n + 1 ] = 0 ;
    w.init ( 1 , 1 , MAXVAL ) ;
    for ( int i = 1 ; i <= n + 1 ; ++ i ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ i - 1 ] , a[ i ] ) + 1 , max ( a[ i - 1 ] , a[ i ] ) , 1 ) ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        w.act ( 1 , 1 , MAXVAL , a[ i ] , 1 ) ;
    }
}

void solve ( ) {
    while ( q -- ) {
        int pos , x ;
        scanf ( "%d%d" , &pos , &x ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 0 ) ;
        handle ( pos , -1 ) ;
        a[ pos ] = x ;
        handle ( pos , 1 ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 1 ) ;
        printf ( "%d\n" , w.valid[ 1 ].second ) ;
    }
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    input ( ) ;
    solve ( ) ;
    return 0 ;
}


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

#define MAXN 1000007
#define MAXVAL 1000000

int n , q ;
int a[ MAXN ] ;

class Tree {
public :
    int tr[ 4 * MAXN ] ;
    pair < int , int > valid[ 4 * MAXN ] ;
    int lazy[ 4 * MAXN ] ;
    void init ( int where , int IL , int IR ) {
        tr[ where ] = 0 ;
        valid[ where ] = { 10 * MAXN , 0 } ;
        if ( IL == IR ) { return ; }
        int mid = ( IL + IR ) / 2 ;
        init ( 2 * where , IL , mid ) ;
        init ( 2 * where + 1 , mid + 1 , IR ) ;
    }
    void unite ( int where , int ls , int rs ) {
        tr[ where ] = min ( tr[ ls ] , tr[ rs ] ) ;
        valid[ where ].first = min ( valid[ ls ].first , valid[ rs ].first ) ;
        valid[ where ].second = ( valid[ where ].first == valid[ ls ].first ) * valid[ ls ].second
                            + ( valid[ where ].first == valid[ rs ].first ) * valid[ rs ].second ;
    }
    void push_lazy ( int where , int IL , int IR ) {
        if ( lazy[ where ] == 0 ) { return ; }
        tr[ where ] += lazy[ where ] ;
        valid[ where ].first += lazy[ where ] ;
        if ( IL != IR ) {
            lazy[ 2 * where ] += lazy[ where ] ;
            lazy[ 2 * where + 1 ] += lazy[ where ] ;
        }
        lazy[ where ] = 0 ;
    }

    void update ( int where , int IL , int IR , int CURL , int CURR , int val ) {
        push_lazy ( where , IL , IR ) ;
        if ( IL > IR || CURL > CURR ) { return ; }
        if ( IR < CURL || CURR < IL ) { return ; }
        if ( CURL <= IL && IR <= CURR ) {
            lazy[ where ] += val ;
            push_lazy ( where , IL , IR ) ;
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        update ( 2 * where , IL , mid , CURL , CURR , val ) ;
        update ( 2 * where + 1 , mid + 1 , IR , CURL , CURR , val ) ;
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
    void act ( int where , int IL , int IR , int pos , int nw ) {
        push_lazy ( where , IL , IR ) ;
        if ( IR < pos || pos < IL ) { return ; }
        if ( IL == IR ) {
            if ( nw == 1 ) {
                valid[ where ] = { tr[ where ] , 1 } ;
            }
            else {
                valid[ where ] = { 10 * MAXN , 0 } ;
            }
            return ;
        }
        int mid = ( IL + IR ) / 2 ;
        if ( pos <= mid ) {
            act ( 2 * where , IL , mid , pos , nw ) ;
        }
        else {
            act ( 2 * where + 1 , mid + 1 , IR , pos , nw ) ;
        }
        unite ( where , 2 * where , 2 * where + 1 ) ;
    }
};
Tree w ;

void handle ( int pos , int coef ) {
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos - 1 ] , a[ pos ] ) + 1 , max ( a[ pos - 1 ] , a[ pos ] ) , coef ) ;
    w.update ( 1 , 1 , MAXVAL , min ( a[ pos ] , a[ pos + 1 ] ) + 1 , max ( a[ pos ] , a[ pos + 1 ] ) , coef ) ;
}

void input ( ) {
    scanf ( "%d%d" , &n , &q ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d" , &a[ i ] ) ;
    }
    a[ 0 ] = MAXVAL ;
    a[ n + 1 ] = 0 ;
    w.init ( 1 , 1 , MAXVAL ) ;
    for ( int i = 1 ; i <= n + 1 ; ++ i ) {
        w.update ( 1 , 1 , MAXVAL , min ( a[ i - 1 ] , a[ i ] ) + 1 , max ( a[ i - 1 ] , a[ i ] ) , 1 ) ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        w.act ( 1 , 1 , MAXVAL , a[ i ] , 1 ) ;
    }
}

void solve ( ) {
    while ( q -- ) {
        int pos , x ;
        scanf ( "%d%d" , &pos , &x ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 0 ) ;
        handle ( pos , -1 ) ;
        a[ pos ] = x ;
        handle ( pos , 1 ) ;
        w.act ( 1 , 1 , MAXVAL , a[ pos ] , 1 ) ;
        printf ( "%d\n" , w.valid[ 1 ].second ) ;
    }
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    input ( ) ;
    solve ( ) ;
    return 0 ;
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN = 500010;
const int MAXV = 1000010;

class SegmentTree
{
	public:

		int getLeft(int node) { return 2*node; }
		int getRight(int node) { return 2*node + 1; }

		void merge(int node, int idLeft, int idRight)
		{
			qtdMn[node] = 0;

			if( mn[idLeft] <= mn[idRight] )
			{
				mn[node] = mn[idLeft];
				qtdMn[node] += qtdMn[idLeft];
			}

			if( mn[idLeft] >= mn[idRight] )
			{
				mn[node] = mn[idRight];
				qtdMn[node] += qtdMn[idRight];
			}
		}

		void build(int node, int l, int r)
		{
			mn[node] = 1;

			if( l == r ) return void( qtdMn[node] = 1 );

			int m = ( l + r )/2;

			build( getLeft(node) , l , m );
			build( getRight(node) , m + 1 , r );

			merge( node , getLeft(node) , getRight(node) );
		}

		void refresh(int node, int l, int r)
		{
			if( lazy[node] == 0 ) return;

			int lz = lazy[node];
			lazy[node] = 0;

			mn[node] += lz;

			if( l == r ) return;

			lazy[ getLeft(node) ] += lz;
			lazy[ getRight(node) ] += lz;
		}

		void update(int node, int l, int r, int i, int j, int v)
		{
			refresh( node , l , r );

			if( j < l || r < i ) return;
			if( i <= l && r <= j )
			{
				lazy[node] += v;
				refresh( node , l , r );

				return;
			}

			int m = ( l + r )/2;

			update( getLeft(node) , l , m , i , j , v );
			update( getRight(node) , m + 1 , r , i , j , v );

			merge( node , getLeft(node) , getRight(node) );
		}

		int qtdZeros()
		{
			refresh( 1 , 1 , MAXV );

			if( mn[1] != 0 ) return 0;
			return qtdMn[1];
		}

		SegmentTree() { build( 1 , 1 , MAXV ); }

	private:

		int mn[4*MAXV];
		int lazy[4*MAXV];
		int qtdMn[4*MAXV];
};

int n, q;

int v[MAXN];

SegmentTree SEG;

void update(int i, int val)
{
	if( i <= 0 ) return;
	if( v[i] > v[i + 1] ) return;

	SEG.update( 1 , 1 , MAXV , v[i] + 1 , v[i + 1] , val );
}

int main()
{
	scanf("%d %d",&n,&q);

	for(int i = 1 ; i <= n ; i++)
	{
		scanf("%d",&v[i]);
		SEG.update( 1 , 1 , MAXV , v[i] , v[i] , -1 );
	}

	for(int i = 1 ; i < n ; i++)
		update( i , 1 );

	for(int i = 1 ; i <= q ; i++)
	{
		int ind, x;
		scanf("%d %d",&ind,&x);

		SEG.update( 1 , 1 , MAXV , v[ind] , v[ind] , 1 );

		update( ind , -1 );
		update( ind - 1 , -1 );

		v[ind] = x;

		update( ind , 1 );
		update( ind - 1 , 1 );

		SEG.update( 1 , 1 , MAXV , v[ind] , v[ind] , -1 );

		printf("%d\n",SEG.qtdZeros());
	}
}


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

using ll = long long;
using ii = pair<int, int>;
using vi = vector<int>;
#define all(v) begin(v), end(v)

const int N = 1e6 + 5;

struct node {
  int sum = 0, sz = 0, cnt = 0, mn = 0;
} t[N << 2];

node merge(node &a, node &b) {
  if(!a.sz) return b;
  if(!b.sz) return a;
  node ret = {a.sum + b.sum, a.sz + b.sz, 69, 69};
  if(a.mn + b.sum < b.mn) {
    ret.mn = a.mn + b.sum;
    ret.cnt = a.cnt;
  } else if(a.mn + b.sum > b.mn) {
    ret.mn = b.mn;
    ret.cnt = b.cnt;
  } else {
    ret.mn = b.mn;
    ret.cnt = a.cnt + b.cnt;
  }
  return ret;
}

void update(int p, node x, int u = 1, int b = 1, int e = 1000000) {
  if(b == e) return void(t[u] = x);
  int m = (b + e) >> 1;
  if(p <= m) {
    update(p, x, u << 1, b, m);
  } else {
    update(p, x, u << 1 | 1, m+1, e);
  }
  t[u] = merge(t[u << 1], t[u << 1 | 1]);
}

void erase(int key) {
  update(key, {0,0,0,0});
}

void insert(int key, int value) {
  update(key, {value, 1, 1, value});
}

int count() {
  return t[1].cnt;
}

int n, q, a[N];

int delta(int i) {
  int ret = 0;
  if(i > 1) ret += a[i-1] > a[i] ? -1 : 1;
  ret += a[i+1] > a[i] ? -1 : 1;
  return ret;
}

int main(int argc, char const *argv[])
{
#ifdef LOCAL
  freopen("in", "r", stdin);
#endif
  scanf("%d %d", &n, &q);
  for(int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
  }
  for(int i = 1; i <= n; ++i) {
    insert(a[i], delta(i));
  }
  while(q--) {
    int p, x;
    scanf("%d %d", &p, &x);
    for(int i : {p-1, p, p+1}) if(1 <= i and i <= n) {
      erase(a[i]);
    }
    a[p] = x;
    for(int i : {p-1, p, p+1}) if(1 <= i and i <= n) {
      insert(a[i], delta(i));
    }
    printf("%d\n", count());
  }
  return 0;
}


#include <cstdio>
#include <iostream>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lson u<<1,l,mid
#define rson u<<1|1,mid+1,r
using namespace std;
inline char nc()
{
    // return getchar();
    static char buf[100000],*l=buf,*r=buf;
    return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<class T> void read(T &x)
{
    x=0; int f=1,ch=nc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
    while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
    x*=f;
}
const int maxn=5e5+50;
const int m=1e6;
int n,q;
int a[maxn];
namespace seg
{
    const int maxnode=(m<<2)+5;
    int mn[maxnode];
    int cnt[m+5];
    int sum[maxnode];
    int tag[maxnode];
    inline void change(int u,int d)
    {
        mn[u]+=d;
        tag[u]+=d;
    }
    inline void pushdown(int u)
    {
        if(tag[u])
        {
            change(u<<1,tag[u]);
            change(u<<1|1,tag[u]);
            tag[u]=0;
        }
    }
    inline void pushup(int u)
    {
        mn[u]=min(mn[u<<1],mn[u<<1|1]);
        sum[u]=0;
        if(mn[u]==mn[u<<1]) sum[u]+=sum[u<<1];
        if(mn[u]==mn[u<<1|1]) sum[u]+=sum[u<<1|1];
    }
    void update(int u,int l,int r,int qp,int qv)
    {
        if(l==r)
        {
            cnt[l]+=qv;
            sum[u]=bool(cnt[l]);
            return;
        }
        int mid=(l+r)>>1;
        pushdown(u);
        if(qp<=mid) update(lson,qp,qv);
        else update(rson,qp,qv);
        pushup(u);
    }
    void update(int u,int l,int r,int ql,int qr,int qv)
    {
        if(l==ql&&r==qr)
        {
            change(u,qv);
            return;
        }
        int mid=(l+r)>>1;
        pushdown(u);
        if(qr<=mid) update(lson,ql,qr,qv);
        else if(ql>mid) update(rson,ql,qr,qv);
        else
        {
            update(lson,ql,mid,qv);
            update(rson,mid+1,qr,qv);
        }
        pushup(u);
    }
    void travel(int u,int l,int r)
    {
        if(l==r)
        {
            if(mn[u]==1&&sum[u]==1) debug("%d\n",l);
            return;
        }
        int mid=(l+r)>>1;
        pushdown(u);
        travel(lson);
        travel(rson);
    }
}
inline void ins(int x,int f)
{
    seg::update(1,0,m,a[x],f);
    if(x==1) seg::update(1,0,m,a[x],m,f);
    else
    {
        if(a[x-1]>a[x]) seg::update(1,0,m,a[x],a[x-1]-1,f);
    }
    if(x==n) seg::update(1,0,m,0,a[x]-1,f);
    else
    {
        if(a[x]>a[x+1]) seg::update(1,0,m,a[x+1],a[x]-1,f);
    }
}
int main()
{
    read(n),read(q);
    for(int i=1;i<=n;++i)
    {
        read(a[i]);
        seg::update(1,0,m,a[i],1);
    }
    seg::update(1,0,m,a[1],m,1);
    for(int i=2;i<=n;++i)
    {
        if(a[i-1]>a[i])
        {
            seg::update(1,0,m,a[i],a[i-1]-1,1);
        }
    }
    seg::update(1,0,m,0,a[n]-1,1);
    for(int i=1;i<=q;++i)
    {
        int pos,x; read(pos),read(x);
        ins(pos,-1);
        a[pos]=x;
        ins(pos,1);
        // seg::travel(1,0,m);
        printf("%d\n",seg::mn[1]==1?seg::sum[1]:0);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int C = 1'000'001;
struct Node {
    int min, cnt;
    Node() {}
    Node(int min, int cnt) : min(min), cnt(cnt) {}
};
Node operator+(const Node &lhs, const Node &rhs) {
    if (lhs.min < rhs.min) {
        return lhs;
    } else if (lhs.min > rhs.min) {
        return rhs;
    } else {
        return Node(lhs.min, lhs.cnt + rhs.cnt);
    }
}
Node t[4 * C];
int lazy[4 * C], d[C + 1], act[C];
void add(int p, int v) {
    t[p].min += v;
    lazy[p] += v;
}
void push(int p) {
    add(2 * p, lazy[p]);
    add(2 * p + 1, lazy[p]);
    lazy[p] = 0;
}
void build(int p, int l, int r) {
    if (r - l == 1) {
        t[p] = Node(d[l], act[l]);
        return;
    }
    int m = (l + r) / 2;
    build(2 * p, l, m);
    build(2 * p + 1, m, r);
    t[p] = t[2 * p] + t[2 * p + 1];
}
void rangeAdd(int p, int l, int r, int x, int y, int v) {
    if (l >= y || r <= x)
        return;
    if (l >= x && r <= y) {
        add(p, v);
        return;
    }
    int m = (l + r) / 2;
    push(p);
    rangeAdd(2 * p, l, m, x, y, v);
    rangeAdd(2 * p + 1, m, r, x, y, v);
    t[p] = t[2 * p] + t[2 * p + 1];
}
void rangeAdd(int l, int r, int v) {
    if (l > r)
        swap(l, r);
    rangeAdd(1, 0, C, l, r, v);
}
void setActivity(int p, int l, int r, int x, int v) {
    if (r - l == 1) {
        t[p].cnt = v;
        return;
    }
    int m = (l + r) / 2;
    push(p);
    if (x < m) {
        setActivity(2 * p, l, m, x, v);
    } else {
        setActivity(2 * p + 1, m, r, x, v);
    }
    t[p] = t[2 * p] + t[2 * p + 1];
}
void setActivity(int x, int v) {
    setActivity(1, 0, C, x, v);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    vector<int> a(n + 2);
    a[0] = C;
    a[n + 1] = 0;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    for (int i = 0; i <= n; ++i) {
        int l = a[i], r = a[i + 1];
        if (l > r)
            swap(l, r);
        ++d[l];
        --d[r];
    }
    for (int i = 1; i <= C; ++i)
        d[i] += d[i - 1];
    for (int i = 1; i < n + 2; ++i)
        act[a[i]] = 1;
    build(1, 0, C);
    for (int i = 0; i < q; ++i) {
        int x, v;
        cin >> x >> v;
        setActivity(a[x], false);
        setActivity(v, true);
        rangeAdd(a[x - 1], a[x], -1);
        rangeAdd(a[x], a[x + 1], -1);
        rangeAdd(a[x - 1], v, 1);
        rangeAdd(v, a[x + 1], 1);
        a[x] = v;
        cout << t[1].cnt - 1 << "\n";
    }
    return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef double db;
typedef long long ll;
typedef long double ld;
typedef string str;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define eb emplace_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define rsz resize
#define ins insert

const int MOD = 1e9+7; // 998244353 = (119<<23)+1
const ll INF = 1e18;
const int MX = 2e5+5;
const ld PI = 4*atan((ld)1);

template<class T> bool ckmin(T& a, const T& b) { return a > b ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace __gnu_pbds;
using namespace __gnu_cxx;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define ook order_of_key
#define fbo find_by_order

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class T, class... Ts> void re(T& t, Ts&... ts) {
        re(t); re(ts...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    void pr(int x) { cout << x; }
    void pr(long x) { cout << x; }
    void pr(ll x) { cout << x; }
    void pr(unsigned x) { cout << x; }
    void pr(unsigned long x) { cout << x; }
    void pr(unsigned long long x) { cout << x; }
    void pr(float x) { cout << x; }
    void pr(double x) { cout << x; }
    void pr(ld x) { cout << x; }
    void pr(char x) { cout << x; }
    void pr(const char* x) { cout << x; }
    void pr(const string& x) { cout << x; }
    void pr(bool x) { pr(x ? "true" : "false"); }
    template<class T> void pr(const complex<T>& x) { cout << x; }

    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T> void pr(const T& x);

    template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
        pr(t); pr(ts...);
    }
    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void pr(const T& x) {
        pr("{"); // const iterator needed for vector<bool>
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
        pr("}");
    }

    void ps() { pr("\n"); } // print w/ spaces
    template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
        pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
    }

    void pc() { pr("]\n"); } // debug w/ commas
    template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
        pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
    }
    #define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        cin.sync_with_stdio(0); cin.tie(0); // fast I/O
        cin.exceptions(cin.failbit); // ex. throws exception when you try to read letter into int
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
	a %= b; if (a == 0) return b == 1 ? 0 : -1;
	T x = invGeneral(b,a);
	return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
	T val;
	explicit operator T() const { return val; }
	modular() { val = 0; }
	modular(const ll& v) {
		val = (-MOD <= v && v <= MOD) ? v : v % MOD;
		if (val < 0) val += MOD;
	}

	// friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
	friend void pr(const modular& a) { pr(a.val); }
	friend void re(modular& a) { ll x; re(x); a = modular(x); }

	friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
	friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
	friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

	modular operator-() const { return modular(-val); }
	modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
	modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
	modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
	friend modular pow(modular a, ll p) {
		modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend modular inv(const modular& a) {
		auto i = invGeneral(a.val,MOD); assert(i != -1);
		return i;
	} // equivalent to return exp(b,MOD-2) if MOD is prime
	modular& operator/=(const modular& m) { return (*this) *= inv(m); }

	friend modular operator+(modular a, const modular& b) { return a += b; }
	friend modular operator-(modular a, const modular& b) { return a -= b; }
	friend modular operator*(modular a, const modular& b) { return a *= b; }

	friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

/**
 * Description: 1D range update and query. Set SZ to a power of 2.
 * Source: USACO Counting Haybales
 * Verification: SPOJ Horrible
 */

template<class T, int SZ> struct LazySeg {
	pair<T, T> mins[2*SZ];
	T lazy[2*SZ];
	pair<T, T> ID = mp(MOD, 0);
	LazySeg() {
		for(int i = 0; i < 2*SZ; i++){
			mins[i] = mp(0, 1);
		}
		memset(lazy,0,sizeof lazy);
	}
	void push(int ind, int L, int R) { // modify values for current node
		mins[ind].f += lazy[ind];
		if (L != R) lazy[2*ind] += lazy[ind], lazy[2*ind+1] += lazy[ind];
		lazy[ind] = 0; // pushed lazy to children
	}
	pair<T, T> comb(pair<T, T> a, pair<T, T> b){
		if(a.f == b.f) return mp(a.f, a.s+b.s);
		if(a.f > b.f) return b;
		return a;
	}
	void pull(int ind) { // recalc values for current node
		mins[ind] = comb(mins[2*ind], mins[2*ind+1]); }
	void build() { ROF(i,1,SZ) pull(i); }
	void upd(int lo, int hi, T inc, int ind = 1, int L = 0, int R = SZ-1) {
		push(ind,L,R);
		if (hi < L || R < lo) return;
		if (lo <= L && R <= hi) {
			lazy[ind] = inc;
			push(ind,L,R); return;
		}
		int M = (L+R)/2;
		upd(lo,hi,inc,2*ind,L,M); upd(lo,hi,inc,2*ind+1,M+1,R);
		pull(ind);
	}
	// minimum, number of minimums
	pair<T, T> qmin(int lo, int hi, int ind = 1, int L = 0, int R = SZ-1) {
		push(ind,L,R);
		if (lo > R || L > hi) return ID;
		if (lo <= L && R <= hi) return mins[ind];
		int M = (L+R)/2;
		return comb(qmin(lo,hi,2*ind,L,M), qmin(lo,hi,2*ind+1,M+1,R));
	}
	void setzero(int ind){
		upd(ind, ind, -qmin(ind, ind).f);
	}
};

int a[500005];
LazySeg<int, 1<<20> arr;
int n, q;

void undo(int pos){
	if(pos < 1) return;
	if(pos > n) return;
	int lr = 1;
    if(pos-1>= 1 && a[pos] > a[pos-1]){
    	lr--;
    }
    if(pos+1 <= n && a[pos] > a[pos+1]){
    	lr--;
    }
    arr.upd(a[pos], 1000000, -lr);
}

void redo(int pos){
	if(pos < 1) return;
	if(pos > n) return;
	int lr = 1;
    if(pos-1>= 1 && a[pos] > a[pos-1]){
    	lr--;
    }
    if(pos+1 <= n && a[pos] > a[pos+1]){
    	lr--;
    }
    arr.upd(a[pos], 1000000, lr);
}
int main() {
	setIO();
    // you should actually read the stuff at the bottom
    arr.build();
    for(int i = 1; i <= 1000000; i++){
    	arr.upd(i, i, MOD);
    }

    cin >> n >> q;

    for(int i = 1; i <= n; i++){
    	cin >> a[n+1-i];
    	arr.setzero(a[n+1-i]);
    }
    for(int i = 1; i <= n; i++){
    	redo(i);
    }
    for(int i = 0; i < q; i++){
    	int pos, x;
    	cin >> pos >> x;
    	pos = n+1-pos;
    	//a[pos] is not included anymore
    	arr.upd(a[pos], a[pos], MOD);
    	//we undo the operations of this position
    	undo(pos-1);
    	undo(pos);
    	undo(pos+1);

    	a[pos] = x;

    	//x is gonna get included now
    	arr.upd(a[pos], a[pos], -MOD);
    	redo(pos-1);
    	redo(pos);
    	redo(pos+1);

    	pi res = arr.qmin(a[1], 1000000);
    	cout << res.s << "\n";

    	/*for(int i = 1; i <= n; i++){
    		cout << a[i] << " " << arr.qmin(a[i], a[i]).f << ", ";
    	}
    	cout << "\n";*/

    }
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?), set tle
	* do smth instead of nothing and stay organized
*/


#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 500000;
const int MAX_VAL = 1000000;
const int MAX_AINT = 1 + 1000000 + 1;
const int INF = 1000000000;

struct Node {
	int val, freq;
} aint[1+4*MAX_AINT];

int lazy[1+4*MAX_AINT];
bool activated[MAX_AINT];

int v[1+MAX_N+1];

Node combine(Node a, Node b) {
	int minval = min(a.val, b.val);
	int freq = 0;

	if(a.val == minval)
		freq += a.freq;
	if(b.val == minval)
		freq += b.freq;

	return {minval, freq}; // superposition
}

void init(int l = 0, int r = MAX_AINT - 1, int nod = 1) {
	int mid = (l + r) / 2;
	if(l < r) {
		init(l, mid, 2 * nod);
		init(mid + 1, r, 2 * nod + 1);
		aint[nod] = combine(aint[2 * nod], aint[2 * nod + 1]);
	} else
		aint[nod] = {INF, 1};
}

void pushLazy(int l, int r, int nod) {
	aint[nod].val += lazy[nod];
	if(l < r) {
		lazy[2 * nod] += lazy[nod];
		lazy[2 * nod + 1] += lazy[nod];
	}
	lazy[nod] = 0;
}

void update(int i, int j, int val, int l = 0, int r = MAX_AINT - 1, int nod = 1) {
	pushLazy(l, r, nod);
	if(r < i || j < l || j < i) return;

	if(i <= l && r <= j) {
		lazy[nod] += val;
		pushLazy(l, r, nod);
	} else {
		int mid = (l + r) / 2;
		update(i, j, val, l, mid, 2 * nod);
		update(i, j, val, mid + 1, r, 2 * nod + 1);
		aint[nod] = combine(aint[2 * nod], aint[2 * nod + 1]);
	}
}

int query() {
	if(aint[1].val == 1)
		return aint[1].freq;
	return 0;
}

// a == b is absurd
// if a < b, then they will be different in range a...b-1
void updateDifference(int a, int b, int val) {
	if(a > b)
		swap(a, b);

	update(a, b - 1, val);
}

int main() {
	int N, Q;
	scanf("%d%d", &N, &Q);

	v[0] = 1000001;
	v[N + 1] = 0;

	init();

	// Activate margins
	//update(v[0], v[0], -INF);
	update(v[N + 1], v[N + 1], -INF);

	for(int i = 1; i <= N; ++i) {
		scanf("%d", &v[i]);
		update(v[i], v[i], -INF);
	}

	for(int i = 0; i <= N; ++i)
		updateDifference(v[i], v[i + 1], 1);

	for(int i = 0; i < Q; ++i) {
		int pos, x;
		scanf("%d%d", &pos, &x);

		updateDifference(v[pos - 1], v[pos], -1);
		updateDifference(v[pos], v[pos + 1], -1);
		update(v[pos], v[pos], INF);

		v[pos] = x;

		updateDifference(v[pos - 1], v[pos], +1);
		updateDifference(v[pos], v[pos + 1], +1);
		update(v[pos], v[pos], -INF);

		printf("%d\n", query() - 1);
	}

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <climits>
#include <queue>
#include <set>
#include <cmath>
#include <map>
#include <bitset>
#include <fstream>
#include <tr1/unordered_map>
#include <assert.h>

#define x first
#define y second
#define y1 Y1
#define y2 Y2
#define mp make_pair
#define pb push_back
#define DEBUG(x) cout << #x << " = " << x << endl;

using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

template <typename T> inline int Chkmax (T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline int Chkmin (T &a, T b) { return a > b ? a = b, 1 : 0; }
template <typename T> inline T read ()
{
	T sum = 0, fl = 1; char ch = getchar();
	for (; !isdigit(ch); ch = getchar()) if (ch == '-') fl = -1;
	for (; isdigit(ch); ch = getchar()) sum = (sum << 3) + (sum << 1) + ch - '0';
	return sum * fl;
}

inline void proc_status ()
{
	ifstream t ("/proc/self/status");
	cerr << string (istreambuf_iterator <char> (t), istreambuf_iterator <char> ()) << endl;
}

const int MAXN = 5e5;
const int MAXM = 1e6 + 1;

int N, Q;
int A[MAXN + 5], times[MAXM + 5];

namespace SEG
{
#define mid ((l + r) >> 1)
#define ls o << 1
#define rs o << 1 | 1
#define lson ls, l, mid
#define rson rs, mid + 1, r

	const int MAX_NODE = MAXM << 2;

	struct info
	{
		int min, cnt, chk, tag;

		info (int _min = 0, int _cnt = 0, int _chk = 0, int _tag = 0) { min = _min, cnt = _cnt, chk = _chk, tag = _tag; }

		inline info operator + (const info &rhs) const
		{
			info o;
			o.tag = 0;
			o.min = min < rhs.min ? min : rhs.min;

			if (min < rhs.min) o.cnt = cnt;
			else if (min > rhs.min) o.cnt = rhs.cnt;
			else o.cnt = cnt + rhs.cnt;

			return o;
		}

	} node[MAX_NODE + 5];

	inline void push_up (int o) { node[o] = node[ls] + node[rs]; }

	inline void push_down (int o)
	{
		int &tag = node[o].tag;
		if (!tag) return ;
		node[ls].min += tag, node[ls].tag += tag;
		node[rs].min += tag, node[rs].tag += tag;
		tag = 0;
	}

	inline void build (int o, int l, int r)
	{
		if (l == r)
		{
			return ;
		}
		build (lson), build (rson);
		push_up (o);
	}

	inline void update (int o, int l, int r, int x, int y, int val)
	{
		if (x > y) return ;
		if (x <= l && r <= y)
		{
			node[o].min += val, node[o].tag += val;
			return ;
		}

		push_down (o);
		if (x <= mid) update (lson, x, y, val);
		if (y > mid) update (rson, x, y, val);

		push_up (o);
	}

	inline void insert (int o, int l, int r, int x)
	{
		if (l == r)
		{
			node[o].chk = node[o].cnt = 1;
			return ;
		}
		push_down (o);
		if (x <= mid) insert (lson, x);
		else insert (rson, x);
		push_up (o);
	}

	inline void erase (int o, int l, int r, int x)
	{
		if (l == r)
		{
			node[o].chk = node[o].cnt = 0;
			return ;
		}
		push_down (o);
		if (x <= mid) erase (lson, x);
		else erase (rson, x);
		push_up (o);
	}

#undef mid
}

inline void Init ()
{
	SEG :: build (1, 1, MAXM);

	A[0] = MAXM, A[N + 1] = 0;
	for (int i = 1; i <= N + 1; ++i)
	{
		int l = min (A[i], A[i - 1]) + 1, r = max (A[i], A[i - 1]);
		SEG :: update (1, 1, MAXM, l, r, 1);
	}

	for (int i = 1; i <= N; ++i) ++times[A[i]], SEG :: insert (1, 1, MAXM, A[i]);
}

inline void Update (int l, int r, int val) { SEG :: update (1, 1, MAXM, l, r, val); }

inline void Solve ()
{
	Init ();
	while (Q--)
	{
		int x = read<int>(), y = read<int>();

		Update (min (A[x], A[x - 1]) + 1, max (A[x], A[x - 1]), -1);
		Update (min (A[x], A[x + 1]) + 1, max (A[x], A[x + 1]), -1);
		Update (min (y, A[x - 1]) + 1, max (y, A[x - 1]), 1);
		Update (min (y, A[x + 1]) + 1, max (y, A[x + 1]), 1);

		if ((--times[A[x]]) == 0) SEG :: erase (1, 1, MAXM, A[x]);
		if ((++times[y]) == 1) SEG :: insert (1, 1, MAXM, y);

		A[x] = y;

		printf("%d\n", SEG :: node[1].cnt);
	}
}

inline void Input ()
{
	N = read<int>(), Q = read<int>();
	for (int i = 1; i <= N; ++i) A[i] = read<int>();
}

int main ()
{

#ifdef hk_cnyali
	freopen("H.in", "r", stdin);
	freopen("H.out", "w", stdout);
#endif

	Input ();
	Solve ();

	return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

const int INF = 1e9 + 5;

struct segment_change {
    int to_add;
    bool toggle_active;

    segment_change(int _to_add = 0, bool _toggle_active = false) : to_add(_to_add), toggle_active(_toggle_active) {}

    void reset() {
        to_add = 0;
        toggle_active = false;
    }

    bool has_change() const {
        return to_add != 0 || toggle_active;
    }

    // Return the combined result of applying this segment change followed by `other`.
    segment_change combine(const segment_change &other) const {
        return segment_change(to_add + other.to_add, toggle_active ^ other.toggle_active);
    }
};

struct segment {
    int minimum, count_of_min;
    bool active;

    segment(int _minimum = INF, int _count_of_min = 0, bool _active = false)
        : minimum(_minimum), count_of_min(_count_of_min), active(_active) {}

    void apply(int, const segment_change &change) {
        minimum += change.to_add;
        active ^= change.toggle_active;
    }

    void join(const segment &other) {
        if (other.active) {
            if (!active || other.minimum < minimum)
                *this = other;
            else if (other.minimum == minimum)
                count_of_min += other.count_of_min;
        }
    }

    void join(const segment &a, const segment &b) {
        *this = a;
        join(b);
    }

    int get_goal_count(int goal) const {
        return (active && minimum == goal) ? count_of_min : 0;
    }
};

pair<int, int> right_half[32];

struct min_count_seg_tree {
    int tree_n = 0;
    vector<segment> tree;
    vector<segment_change> changes;

    min_count_seg_tree(int n = -1) {
        if (n >= 0)
            init(n);
    }

    void init(int n) {
        tree_n = 1;

        while (tree_n < n)
            tree_n *= 2;

        tree.assign(2 * tree_n, segment());
        changes.assign(tree_n, segment_change());
    }

    // Builds our tree from an array in O(n).
    void build(const vector<segment> &initial) {
        int n = initial.size();
        init(n);
        assert(n <= tree_n);

        for (int i = 0; i < n; i++)
            tree[tree_n + i] = initial[i];

        for (int position = tree_n - 1; position > 0; position--)
            tree[position].join(tree[2 * position], tree[2 * position + 1]);
    }

    void push_down(int position, int length) {
        if (!changes[position].has_change())
            return;

        if (2 * position < tree_n) {
            changes[2 * position] = changes[2 * position].combine(changes[position]);
            changes[2 * position + 1] = changes[2 * position + 1].combine(changes[position]);
        }

        tree[2 * position].apply(length / 2, changes[position]);
        tree[2 * position + 1].apply(length / 2, changes[position]);
        changes[position].reset();
    }

    // Calls push_down for all necessary nodes in order to query the range [a, b).
    void push_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;

        for (int up = 31 - __builtin_clz(tree_n); up > 0; up--) {
            int x = a >> up, y = b >> up;
            push_down(x, 1 << up);
            if (x != y) push_down(y, 1 << up);
        }
    }

    void join_and_apply(int position, int length) {
        tree[position].join(tree[2 * position], tree[2 * position + 1]);
        tree[position].apply(length, changes[position]);
    }

    // Calls join for all necessary nodes after updating the range [a, b).
    void join_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;
        int length = 1;

        while (a > 1) {
            a /= 2;
            b /= 2;
            length *= 2;
            join_and_apply(a, length);
            if (a != b) join_and_apply(b, length);
        }
    }

    template<typename T_range_op>
    void process_range(int a, int b, bool needs_join, T_range_op &&range_op) {
        if (a == b) return;
        push_all(a, b);
        int original_a = a, original_b = b;
        int length = 1, r_size = 0;

        for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2, length *= 2) {
            if (a & 1)
                range_op(a++, length);

            if (b & 1)
                right_half[r_size++] = {--b, length};
        }

        for (int i = r_size - 1; i >= 0; i--)
            range_op(right_half[i].first, right_half[i].second);

        if (needs_join)
            join_all(original_a, original_b);
    }

    segment query(int a, int b) {
        assert(0 <= a && a <= b && b <= tree_n);
        segment answer;

        process_range(a, b, false, [&](int position, int) {
            answer.join(tree[position]);
        });

        return answer;
    }

    void update(int a, int b, const segment_change &change) {
        assert(0 <= a && a <= b && b <= tree_n);

        process_range(a, b, true, [&](int position, int length) {
            tree[position].apply(length, change);

            if (position < tree_n)
                changes[position] = changes[position].combine(change);
        });
    }
};

const int MAX = 1e6 + 5;

int N, Q;
vector<int> A;
min_count_seg_tree tree;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> N >> Q;
    A.resize(N);

    for (int &a : A)
        cin >> a;

    tree.init(MAX);
    tree.build(vector<segment>(MAX, segment(0, 1, false)));

    for (int i = 0; i < N; i++)
        tree.update(A[i], A[i] + 1, segment_change(0, true));

    for (int i = 0; i < N - 1; i++)
        if (A[i] < A[i + 1])
            tree.update(A[i], A[i + 1], segment_change(+1));

    for (int q = 0; q < Q; q++) {
        int position, x;
        cin >> position >> x;
        position--;

        tree.update(A[position], A[position] + 1, segment_change(0, true));
        if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(-1));
        if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(-1));

        A[position] = x;

        tree.update(A[position], A[position] + 1, segment_change(0, true));
        if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(+1));
        if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(+1));

        cout << tree.tree[1].get_goal_count(0) << '\n';
    }
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

namespace IO {
    const int BUFFER_SIZE = 1 << 15;

    char input_buffer[BUFFER_SIZE];
    int input_pos = 0, input_len = 0;

    char output_buffer[BUFFER_SIZE];
    int output_pos = 0;

    char number_buffer[100];
    uint8_t lookup[100];

    void _update_input_buffer() {
        input_len = fread(input_buffer, sizeof(char), BUFFER_SIZE, stdin);
        input_pos = 0;

        if (input_len == 0)
            input_buffer[0] = EOF;
    }

    inline char next_char(bool advance = true) {
        if (input_pos >= input_len)
            _update_input_buffer();

        return input_buffer[advance ? input_pos++ : input_pos];
    }

    template<typename T>
    inline void read_int(T &number) {
        bool negative = false;
        number = 0;

        while (!isdigit(next_char(false)))
            if (next_char() == '-')
                negative = true;

        do {
            number = 10 * number + (next_char() - '0');
        } while (isdigit(next_char(false)));

        if (negative)
            number = -number;
    }

    template<typename T, typename... Args>
    inline void read_int(T &number, Args &... args) {
        read_int(number);
        read_int(args...);
    }

    void _flush_output() {
        fwrite(output_buffer, sizeof(char), output_pos, stdout);
        output_pos = 0;
    }

    inline void write_char(char c) {
        if (output_pos == BUFFER_SIZE)
            _flush_output();

        output_buffer[output_pos++] = c;
    }

    template<typename T>
    inline void write_int(T number, char after = '\0') {
        if (number < 0) {
            write_char('-');
            number = -number;
        }

        int length = 0;

        while (number >= 10) {
            uint8_t lookup_value = lookup[number % 100];
            number /= 100;
            number_buffer[length++] = (lookup_value & 15) + '0';
            number_buffer[length++] = (lookup_value >> 4) + '0';
        }

        if (number != 0 || length == 0)
            write_char(number + '0');

        for (int i = length - 1; i >= 0; i--)
            write_char(number_buffer[i]);

        if (after)
            write_char(after);
    }

    void init() {
        // Make sure _flush_output() is called at the end of the program.
        bool exit_success = atexit(_flush_output) == 0;
        assert(exit_success);

        for (int i = 0; i < 100; i++)
            lookup[i] = (i / 10 << 4) + i % 10;
    }
}

const int INF = 1e9 + 5;

struct segment_change {
    int to_add;
    bool toggle_active;

    segment_change(int _to_add = 0, bool _toggle_active = false) : to_add(_to_add), toggle_active(_toggle_active) {}

    void reset() {
        to_add = 0;
        toggle_active = false;
    }

    bool has_change() const {
        return to_add != 0 || toggle_active;
    }

    // Return the combined result of applying this segment change followed by `other`.
    segment_change combine(const segment_change &other) const {
        return segment_change(to_add + other.to_add, toggle_active ^ other.toggle_active);
    }
};

struct segment {
    int minimum, count_of_min;
    bool active;

    segment(int _minimum = INF, int _count_of_min = 0, bool _active = false)
        : minimum(_minimum), count_of_min(_count_of_min), active(_active) {}

    void apply(int, const segment_change &change) {
        minimum += change.to_add;
        active ^= change.toggle_active;
    }

    void join(const segment &other) {
        if (other.active) {
            if (!active || other.minimum < minimum)
                *this = other;
            else if (other.minimum == minimum)
                count_of_min += other.count_of_min;
        }
    }

    void join(const segment &a, const segment &b) {
        *this = a;
        join(b);
    }

    int get_goal_count(int goal) const {
        return (active && minimum == goal) ? count_of_min : 0;
    }
};

pair<int, int> right_half[32];

struct min_count_seg_tree {
    int tree_n = 0;
    vector<segment> tree;
    vector<segment_change> changes;

    min_count_seg_tree(int n = -1) {
        if (n >= 0)
            init(n);
    }

    void init(int n) {
        tree_n = 1;

        while (tree_n < n)
            tree_n *= 2;

        tree.assign(2 * tree_n, segment());
        changes.assign(tree_n, segment_change());
    }

    // Builds our tree from an array in O(n).
    void build(const vector<segment> &initial) {
        int n = initial.size();
        init(n);
        assert(n <= tree_n);

        for (int i = 0; i < n; i++)
            tree[tree_n + i] = initial[i];

        for (int position = tree_n - 1; position > 0; position--)
            tree[position].join(tree[2 * position], tree[2 * position + 1]);
    }

    void push_down(int position, int length) {
        if (!changes[position].has_change())
            return;

        if (2 * position < tree_n) {
            changes[2 * position] = changes[2 * position].combine(changes[position]);
            changes[2 * position + 1] = changes[2 * position + 1].combine(changes[position]);
        }

        tree[2 * position].apply(length / 2, changes[position]);
        tree[2 * position + 1].apply(length / 2, changes[position]);
        changes[position].reset();
    }

    // Calls push_down for all necessary nodes in order to query the range [a, b).
    void push_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;

        for (int up = 31 - __builtin_clz(tree_n); up > 0; up--) {
            int x = a >> up, y = b >> up;
            push_down(x, 1 << up);
            if (x != y) push_down(y, 1 << up);
        }
    }

    void join_and_apply(int position, int length) {
        tree[position].join(tree[2 * position], tree[2 * position + 1]);
        tree[position].apply(length, changes[position]);
    }

    // Calls join for all necessary nodes after updating the range [a, b).
    void join_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;
        int length = 1;

        while (a > 1) {
            a /= 2;
            b /= 2;
            length *= 2;
            join_and_apply(a, length);
            if (a != b) join_and_apply(b, length);
        }
    }

    template<typename T_range_op>
    void process_range(int a, int b, bool needs_join, T_range_op &&range_op) {
        if (a == b) return;
        push_all(a, b);
        int original_a = a, original_b = b;
        int length = 1, r_size = 0;

        for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2, length *= 2) {
            if (a & 1)
                range_op(a++, length);

            if (b & 1)
                right_half[r_size++] = {--b, length};
        }

        for (int i = r_size - 1; i >= 0; i--)
            range_op(right_half[i].first, right_half[i].second);

        if (needs_join)
            join_all(original_a, original_b);
    }

    segment query(int a, int b) {
        assert(0 <= a && a <= b && b <= tree_n);
        segment answer;

        process_range(a, b, false, [&](int position, int) {
            answer.join(tree[position]);
        });

        return answer;
    }

    void update(int a, int b, const segment_change &change) {
        assert(0 <= a && a <= b && b <= tree_n);

        process_range(a, b, true, [&](int position, int length) {
            tree[position].apply(length, change);

            if (position < tree_n)
                changes[position] = changes[position].combine(change);
        });
    }
};

const int MAX = 1e6 + 5;

int main() {
    IO::init();

    int N, Q;
    IO::read_int(N, Q);
    vector<int> A(N);

    for (int &a : A)
        IO::read_int(a);

    min_count_seg_tree tree(MAX);
    vector<segment> initial(MAX, segment(0, 1, false));

    for (int i = 0; i < N; i++)
        initial[A[i]].active = true;

    vector<int> delta(MAX, 0);

    for (int i = 0; i < N - 1; i++)
        if (A[i] < A[i + 1]) {
            delta[A[i]]++;
            delta[A[i + 1]]--;
        }

    int sum = 0;

    for (int i = 0; i < MAX; i++) {
        sum += delta[i];
        initial[i].minimum = sum;
    }

    tree.build(initial);

    for (int q = 0; q < Q; q++) {
        int position, x;
        IO::read_int(position, x);
        position--;

        tree.update(A[position], A[position] + 1, segment_change(0, true));

        if (0 < position && position < N - 1 && A[position - 1] < A[position] && A[position] < A[position + 1]) {
            tree.update(A[position - 1], A[position + 1], segment_change(-1));
        } else {
            if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(-1));
            if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(-1));
        }

        A[position] = x;

        tree.update(A[position], A[position] + 1, segment_change(0, true));

        if (0 < position && position < N - 1 && A[position - 1] < A[position] && A[position] < A[position + 1]) {
            tree.update(A[position - 1], A[position + 1], segment_change(+1));
        } else {
            if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(+1));
            if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(+1));
        }

        IO::write_int(tree.tree[1].get_goal_count(0), '\n');
    }
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

const int INF = 1e9 + 5;

struct segment_change {
    int to_add;
    bool toggle_active;

    segment_change(int _to_add = 0, bool _toggle_active = false) : to_add(_to_add), toggle_active(_toggle_active) {}

    void reset() {
        to_add = 0;
        toggle_active = false;
    }

    bool has_change() const {
        return to_add != 0 || toggle_active;
    }

    // Return the combined result of applying this segment change followed by `other`.
    segment_change combine(const segment_change &other) const {
        return segment_change(to_add + other.to_add, toggle_active ^ other.toggle_active);
    }
};

struct segment {
    int minimum, count_of_min;
    bool active;

    segment(int _minimum = INF, int _count_of_min = 0, bool _active = false)
        : minimum(_minimum), count_of_min(_count_of_min), active(_active) {}

    void apply(int, const segment_change &change) {
        minimum += change.to_add;
        active ^= change.toggle_active;
    }

    void join(const segment &other) {
        if (other.active) {
            if (!active || other.minimum < minimum)
                *this = other;
            else if (other.minimum == minimum)
                count_of_min += other.count_of_min;
        }
    }

    void join(const segment &a, const segment &b) {
        *this = a;
        join(b);
    }

    int get_goal_count(int goal) const {
        return (active && minimum == goal) ? count_of_min : 0;
    }
};

pair<int, int> right_half[32];

struct min_count_seg_tree {
    int tree_n = 0;
    vector<segment> tree;
    vector<segment_change> changes;

    min_count_seg_tree(int n = -1) {
        if (n >= 0)
            init(n);
    }

    void init(int n) {
        tree_n = 1;

        while (tree_n < n)
            tree_n *= 2;

        tree.assign(2 * tree_n, segment());
        changes.assign(tree_n, segment_change());
    }

    // Builds our tree from an array in O(n).
    void build(const vector<segment> &initial) {
        int n = initial.size();
        init(n);
        assert(n <= tree_n);

        for (int i = 0; i < n; i++)
            tree[tree_n + i] = initial[i];

        for (int position = tree_n - 1; position > 0; position--)
            tree[position].join(tree[2 * position], tree[2 * position + 1]);
    }

    void push_down(int position, int length) {
        if (!changes[position].has_change())
            return;

        if (2 * position < tree_n) {
            changes[2 * position] = changes[2 * position].combine(changes[position]);
            changes[2 * position + 1] = changes[2 * position + 1].combine(changes[position]);
        }

        tree[2 * position].apply(length / 2, changes[position]);
        tree[2 * position + 1].apply(length / 2, changes[position]);
        changes[position].reset();
    }

    // Calls push_down for all necessary nodes in order to query the range [a, b).
    void push_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;

        for (int up = 31 - __builtin_clz(tree_n); up > 0; up--) {
            int x = a >> up, y = b >> up;
            push_down(x, 1 << up);
            if (x != y) push_down(y, 1 << up);
        }
    }

    void join_and_apply(int position, int length) {
        tree[position].join(tree[2 * position], tree[2 * position + 1]);
        tree[position].apply(length, changes[position]);
    }

    // Calls join for all necessary nodes after updating the range [a, b).
    void join_all(int a, int b) {
        assert(0 <= a && a < b && b <= tree_n);
        a += tree_n;
        b += tree_n - 1;
        int length = 1;

        while (a > 1) {
            a /= 2;
            b /= 2;
            length *= 2;
            join_and_apply(a, length);
            if (a != b) join_and_apply(b, length);
        }
    }

    template<typename T_range_op>
    void process_range(int a, int b, bool needs_join, T_range_op &&range_op) {
        if (a == b) return;
        push_all(a, b);
        int original_a = a, original_b = b;
        int length = 1, r_size = 0;

        for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2, length *= 2) {
            if (a & 1)
                range_op(a++, length);

            if (b & 1)
                right_half[r_size++] = {--b, length};
        }

        for (int i = r_size - 1; i >= 0; i--)
            range_op(right_half[i].first, right_half[i].second);

        if (needs_join)
            join_all(original_a, original_b);
    }

    segment query(int a, int b) {
        assert(0 <= a && a <= b && b <= tree_n);
        segment answer;

        process_range(a, b, false, [&](int position, int) {
            answer.join(tree[position]);
        });

        return answer;
    }

    void update(int a, int b, const segment_change &change) {
        assert(0 <= a && a <= b && b <= tree_n);

        process_range(a, b, true, [&](int position, int length) {
            tree[position].apply(length, change);

            if (position < tree_n)
                changes[position] = changes[position].combine(change);
        });
    }
};

const int MAX = 1e6 + 5;

int N, Q;
vector<int> A;
min_count_seg_tree tree;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> N >> Q;
    A.resize(N);

    for (int &a : A)
        cin >> a;

    tree.init(MAX);
    vector<segment> initial(MAX, segment(0, 1, false));

    for (int i = 0; i < N; i++)
        initial[A[i]].active = true;

    vector<int> delta(MAX, 0);

    for (int i = 0; i < N - 1; i++)
        if (A[i] < A[i + 1]) {
            delta[A[i]]++;
            delta[A[i + 1]]--;
        }

    int sum = 0;

    for (int i = 0; i < MAX; i++) {
        sum += delta[i];
        initial[i].minimum = sum;
    }

    tree.build(initial);

    for (int q = 0; q < Q; q++) {
        int position, x;
        cin >> position >> x;
        position--;

        tree.update(A[position], A[position] + 1, segment_change(0, true));
        if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(-1));
        if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(-1));

        A[position] = x;

        tree.update(A[position], A[position] + 1, segment_change(0, true));
        if (position > 0 && A[position - 1] < A[position]) tree.update(A[position - 1], A[position], segment_change(+1));
        if (position < N - 1 && A[position] < A[position + 1]) tree.update(A[position], A[position + 1], segment_change(+1));

        cout << tree.tree[1].get_goal_count(0) << '\n';
    }
}