#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
#include <cstdint>
using namespace std;
using LL = long long;


//ただのセグ木(min系構造体でなければいけないので注意)
//less、greaterをCompに入れよう
//自作構造体のoperator()定義済みなら何でもOK
//例：RMQ<int,less<int>>tree(N,INT_MAX);
template<typename T, typename Comp>
class RMQ {
private:
	const T DEF;//デフォルト値(minではINF、sumでは0など)
	vector<T> seg;//生データ
	int width;//セグ木の幅(配列の大きさではない！)
	T query_raw(int a, int b, int k, int l, int r)const {
		if (a >= r || b <= l)return DEF;
		if (a <= l && r <= b)return seg[k];
		return min(
			query_raw(a, b, 2 * k + 1, l, (l + r) / 2),
			query_raw(a, b, 2 * k + 2, (l + r) / 2, r), Comp());
	}
public:
	//サイズn、デフォルト値defのセグ木を作る
	RMQ(int n, T def) :DEF(def) {
		width = 1;
		while (width < n)width *= 2;
		seg.assign(width * 2 - 1, DEF);
	}
	//区間[a,b)のクエリの答えを取得する
	T query(int a, int b)const { return query_raw(a, b, 0, 0, width); }
	//x番目の要素をkに更新する
	void update(int k, T x) {
		k += width - 1;
		seg[k] = x;
		while (k > 0) {
			k = (k - 1) / 2;
			seg[k] = min(seg[2 * k + 1], seg[2 * k + 2], Comp());
		}
	}
	//配列ごと初期化する
	void init(const vector<T>& vec) {
		for (int i = 0; i < min(width, (int)vec.size()); ++i)
			seg[i + width - 1] = vec[i];
		for (int k = width - 2; k >= 0; --k)
			seg[k] = min(seg[2 * k + 1], seg[2 * k + 2], Comp());
	}
};


#include <vector>

class union_find {
private:
	vector<int>parent;
	vector<int>rank;
	vector<int>clump;
public:
	union_find(int siz) {
		parent.resize(siz);
		rank.resize(siz);
		clump.resize(siz);
		for (int i = 0; i < siz; ++i) {
			parent[i] = i;
			rank[i] = 0;
			clump[i] = 1;
		}
	}
	void unite(int x, int y) {
		int xr = find(x);
		int yr = find(y);
		if (xr == yr)return;
		if (rank[xr] > rank[yr]) {
			parent[yr] = xr;
			clump[xr] += clump[yr];
		}
		else if (rank[yr] > rank[xr]) {
			parent[xr] = yr;
			clump[yr] += clump[xr];
		}
		else if (xr != yr) {
			parent[yr] = xr;
			clump[xr] += clump[yr];
			++rank[xr];
		}
	}
	int find(int x) {
		if (parent[x] == x) {
			return x;
		}
		else {
			return parent[x] = find(parent[x]);
		}
	}
	bool check(int x, int y) {
		return find(x) == find(y);
	}
	int size(int x) {
		return clump[find(x)];
	}
};

LL N, K;
LL P[234567];

int main() {
	cin >> N >> K;
	RMQ<LL, less<LL>>small(N, 123456789);
	RMQ<LL, greater<LL>>large(N, -1);
	RMQ<LL, less<LL>>dif(N - 1, 123456789);
	union_find uf(N - K + 1);
	for (int i = 0; i < N; ++i) {
		cin >> P[i];
		small.update(i, P[i]);
		large.update(i, P[i]);
	}
	for (int i = 0; i < N; ++i) {
		if (i != N - 1) {
			dif.update(i, P[i] < P[i + 1] ? 1 : 0);
		}
	}
	vector<int>nakama;
	for (int i = 0; i < N - K; ++i) {
		LL sm = small.query(i + 1, i + K);
		LL la = large.query(i + 1, i + K);
		if (P[i] < sm && la < P[i + K]) {
			uf.unite(i, i + 1);
		}
	}
	for (int i = 0; i <= N - K; ++i) {
		if (dif.query(i, i + K - 1)) {
			nakama.push_back(i);
		}
	}
	for (int j = 1; j < nakama.size(); ++j) {
		uf.unite(nakama[0], nakama[j]);
	}
	set<int>S;
	for (int i = 0; i < N - K + 1; ++i) {
		S.insert(uf.find(i));
	}
	cout << S.size() << endl;
	return 0;
}


Measured memory_bytes: 25856