//
//  main.cpp
//
 
#include <algorithm>
#include <array>
#include <assert.h>
#include <functional>
#include <iostream>
#include <iomanip>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
using namespace std;
 
using ll = long long;
using ull = unsigned long long;
 
template<typename T>
vector<T> make_vec_nd(T init, size_t size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, size_t size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

template<typename Monoid>
struct SegmentTree {
	using Op = function<Monoid(const Monoid& lhs, const Monoid& rhs)>;
	size_t width;
	vector<Monoid> node;
	Op op;
	Monoid unit;
 
	SegmentTree(const vector<Monoid>& elems, Op op, Monoid unit)
	: op(op)
	, unit(unit) {
		width = 1;
		while (width < elems.size()) {
			width *= 2;
		}
		node.resize(2 * width - 1, unit);
		for (size_t i = 0; i < elems.size(); i++) {
			node[i + width - 1] = elems[i];
		}
		for (size_t i = width - 2; i != numeric_limits<size_t>::max(); i--) {
			node[i] = op(node[2 * i + 1], node[2 * i + 2]);
		}
	}
	void update(size_t idx, Monoid elem) {
		idx += width - 1;
		node[idx] = elem;
		while (idx >= 1) {
			idx = (idx - 1) / 2;
			node[idx] = op(node[2 * idx + 1], node[2 * idx + 2]);
		}
	}
	Monoid query(size_t a, size_t b, size_t root) const {
		assert(0 <= a && b <= width);
		size_t left = root, right = root;
		while (left < width - 1) {
			left = 2 * left + 1;
		}
		left -= (width - 1);
		while (right < width - 1) {
			right = 2 * right + 2;
		}
		right -= (width - 1);
		right++;
		if (right <= a || b <= left) {
			return unit;
		}
		if (a <= left && right <= b) {
			return node[root];
		}
		Monoid ans_l = query(a, b, 2 * root + 1);
		Monoid ans_r = query(a, b, 2 * root + 2);
		return op(ans_l, ans_r);
	}
};

int main() {
	ll N, K;
	cin >> N >> K;
	vector<ll> pis;
	for (ll i = 0; i < N; i++) {
		ll pi;
		cin >> pi;
		pis.push_back(pi);
	}
	vector<ll> inv_r(N+1-K);
	vector<ll> inv_l(N+1-K);
	vector<ll> pis_rev;
	transform(pis.begin(), pis.end(), back_inserter(pis_rev),
				[](ll x){return -x;});
	reverse(pis_rev.begin(), pis_rev.end());
	for (ll i = 0; i < 2; i++) {
		const vector<ll>* src_p;
		vector<ll>* inv_p;
		if (i == 0) {
			src_p = &pis;
			inv_p = &inv_r;
		} else {
			src_p = &pis_rev;
			inv_p = &inv_l;
		}
		SegmentTree<ll> maxst(*src_p, [](ll lhs, ll rhs){return max(lhs, rhs);},
							  numeric_limits<ll>::min());
		for (ll i = 0; i < N+1-K; i++) {
			ll range_end = K+i;
			ll start;
			if (i == 0) {
				start = range_end - 1;
			} else {
				start = range_end - 1 - (*inv_p)[i-1]; 
			}
			while (true) {
				ll next = start - 1;
				if (next >= i && 
					maxst.query(range_end-K, next, 0) < (*src_p)[next]) {
					start = next;
					continue;
				}
				break;
			}
			if (maxst.query(range_end-K, range_end-1, 0) < (*src_p)[range_end-1]) {
				(*inv_p)[i] = 1 + range_end - 1 - start;
			} else {
				(*inv_p)[i] = 0;
			}
		}
	}
	reverse(inv_l.begin(), inv_l.end());
	set<ll> ranges;
	for (ll i = 0; i < N+1-K; i++) {
		ll left = i + inv_l[i];
		ll right = i + K - inv_r[i];
		if (right - left <= 0) {
			left = 0;
			right = 0;
		}
		ranges.insert(left << 32 | right);
//		cout << "[" << (left) << ", " << (right) << ")" << endl;
	}
	/*
	for (ll r : ranges) {
		cout << "[" << ((r & 0xffffffff00000000) >> 32) << ", " << (r & 0x00000000ffffffff) << ")" << endl;
	}
	*/
	cout << ranges.size() << endl;
}


Measured memory_bytes: 15852