#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
#define int long long
using namespace std;

template <typename X, typename T>
auto vectors(X x, T a) {
	return vector<T>(x, a);
}

template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
	auto cont = vectors(y, z, zs...);
	return vector<decltype(cont)>(x, cont);
}

template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
	rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
	return os;
}
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& x : v) { is >> x; }
	return is;
}

struct RMQ {
	using T = int;
	T operator()(const T& a, const T& b) { return min(a, b); };
	static constexpr T identity() { return INT_MAX; }
};
struct RMiQ {
	using T = int;
	T operator()(const T& a, const T& b) { return max(a, b); };
	static constexpr T identity() { return -INT_MAX; }
};

template <class Monoid>
class rangeUpdateQuery {
  private:
	using T = typename Monoid::T;
	Monoid op;
	const int n;
	vector<T> dat, lazy;
	T query(int a, int b, int k, int l, int r) {
		evaluate(k);

		if (b <= l || r <= a)
			return op.identity();
		else if (a <= l && r <= b)
			return dat[k];
		else {
			int vl = query(a, b, k * 2, l, (l + r) / 2);
			int vr = query(a, b, k * 2 + 1, (l + r) / 2, r);
			return op(vl, vr);
		}
	}
	inline void evaluate(int k) {
		if (lazy[k] == op.identity()) return;
		dat[k] = lazy[k];
		if (k < n) {
			lazy[2 * k]		= lazy[k];
			lazy[2 * k + 1] = lazy[k];
		}
		lazy[k] = op.identity();
	}
	inline void propTo(int k) { dat[k] = op(dat[2 * k], dat[2 * k + 1]); }
	void update(int a, int b, int k, int l, int r, T x) {
		evaluate(k);
		if (r <= a || b <= l) return;
		if (a <= l && r <= b) {
			lazy[k] = x;
			evaluate(k);
		} else if (l < b && a < r) {
			update(a, b, k * 2, l, (l + r) / 2, x);
			update(a, b, k * 2 + 1, (l + r) / 2, r, x);
			propTo(k);
			evaluate(k);
		}
	}
	int power(int n) {
		int res = 1;
		while (n >= res) res *= 2;
		return res;
	}

  public:
	rangeUpdateQuery(int n)
		: n(power(n)), dat(4 * n, op.identity()), lazy(4 * n, op.identity()) {}
	rangeUpdateQuery(const vector<T>& v)
		: n(power(v.size())), dat(4 * n), lazy(4 * n, op.identity()) {
		copy(begin(v), end(v), begin(dat) + n);
		for (int i = n - 1; i > 0; i--) propTo(i);
	}
	T query(int a, int b) { return query(a, b, 1, 0, n); }
	void update(int s, int t, int x) { update(s, t, 1, 0, n, x); }
	T get(int a) { return query(a, a + 1); };
	void out(int n) {
		rep(i, n + 1) { cout << get(i) << ' '; }
		cout << endl;
		// rep(i,n){ range(j,i,n){ cout << i << ' ' << j + 1 << ' ' << query(i +
		// 0,j + 1) << endl; } }
	}
	void out() {
		rep(i, n * 2) { cout << i << " " << dat[i + 1] << endl; }
	}
};

class UnionFind {
  private:
	vector<int> par, depth;

  public:
	vector<int> cnt; // その集合の頂点数
	UnionFind() {}
	UnionFind(int n) { init(n); }
	void init(int n) {
		par   = vector<int>(n);
		depth = vector<int>(n, 0);
		cnt   = vector<int>(n, 1);
		rep(i, n) { par[i] = i; }
	}
	int find(int x) {
		if (par[x] == x) {
			return x;
		} else {
			return par[x] = find(par[x]);
		}
	}
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return;

		if (depth[x] < depth[y]) {
			par[x] = y;
			cnt[y] += cnt[x];
		} else {
			par[y] = x;
			cnt[x] += cnt[y];
			if (depth[x] == depth[y]) depth[x]++;
		}
	}
	bool same(int x, int y) { return find(x) == find(y); }
};

signed main() {
	int n, k;
	cin >> n >> k;
	vector<int> a(n);
	cin >> a;

	rangeUpdateQuery<RMQ> rmq(n);
	rangeUpdateQuery<RMiQ> rmiq(n);
	rep(i, n) { rmq.update(i, i + 1, a[i]); }
	rep(i, n) { rmiq.update(i, i + 1, a[i]); }

	UnionFind uni(n - k + 1);
	rep(i, n - k) {
		auto mini = rmq.query(i + 1, i + k);
		auto maxi = rmiq.query(i + 1, i + k);
		if (a[i] <= mini and maxi <= a[i + k]) { uni.unite(i, i + 1); }
	}

	vector<bool> sorted(n, false);
	int pre = -1;
	int cnt = 0;
	rep(i, n) {
		if (pre < a[i]) {
			cnt++;
			if (cnt >= k) sorted[i - k + 1] = true;
		} else {
			cnt = 1;
		}
		pre = a[i];
	}

	rep(i, n - k + 1) {
		if (sorted[i]) {
			rep(j, n - k + 1) {
				if (i == j) continue;
				if (sorted[j]) uni.unite(i, j);
			}
			break;
		}
	}

	set<int> ans;
	rep(i, n - k + 1) {
		ans.emplace(uni.find(i));
	}

	cout << ans.size() << endl;
}


Measured memory_bytes: 40960