#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace __gnu_pbds;
using namespace std;
#define int long long
//for set
// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;   
// for multiset
typedef tree<
pair<int, int>,
null_type,
less<pair<int, int>>,
rb_tree_tag,
tree_order_statistics_node_update> ordered_multiset;


#define ff first
#define ss second
#define endl "\n"
#define all(x) (x).begin(), (x).end()
// #define PI 3.1415926535897932384626433832795
#define PI acos(-1.0)
int MOD=1e9+7;
int powmod(int a,int l, int md){int res=1;while(l){if(l&1)res=res*a%md;l/=2;a=a*a%md;}return res;}
typedef long long ll; typedef vector<ll> vi; typedef pair<ll, ll> ii; typedef vector<ii> vii;
#define pb push_back
int __set(int b, int i) {return b|(1<<i);} //set ith bit
int __unset(int b, int i) {return b&(~(1UL<<i));}
int __check(int b, int i) {return b&(1<<i);} //returns 0 if ith bit is 0
int mul(int a, int b) {return ((a%MOD)*(b%MOD))%MOD;}
int add(int a, int b) {return (a+b)%MOD;}
int sub(int a, int b) {return (((a-b)%MOD)+MOD)%MOD;}
int __div(int a, int b) {return mul(a, powmod(b, MOD-2, MOD));} //if MOD is prime;
const ll inf = 0xFFFFFFFFFFFFFFFL; //very large number
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > pq; //for min priority_queue
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
clock_t time_p=clock();
void time()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}

// map<char, int> m;
// bool cmp(const pair< pair<int,int> , int>& a, const pair < pair<int,int> , int>& b) {
// 	return a.ff.ss < b.ff.ss;
// }
int mod=1e9+7;

class SegmentTreeMin {                                                        // the segment tree is stored like a heap array
	private: vi st, A;                                                     // recall that vi is: typedef vector<long long int> vi;
	 int n;
	 int left ( int p) { return p << 1; } 								   // same as binary heap operations
	 int right( int p) { return (p << 1) + 1; }
	void build( int p,  int L,  int R) { 									   // O(n)
		if (L == R)                                                        // as L == R, either one is fine
		st[p] = L;                                                         // store the index
		else {                                                             // recursively compute the values
			build(left(p) , L , (L + R) / 2);
			build(right(p), (L + R) / 2 + 1, R );
			 int p1 = st[left(p)], p2 = st[right(p)];
			st[p] = (A[p1] <= A[p2]) ? p1 : p2;
	} }
	 int rmq( int p,  int L,  int R,  int i,  int j) {                          // O(log n)
		if (i > R || j < L) return -1;                                    // current segment outside query range i.e completely to the right or left resp.
		if (L >= i && R <= j) return st[p];                               // inside query range
		                                                                  // compute the min position in the left and right part of the  interval
		 int p1 = rmq(left(p) , L , (L+R) / 2, i, j);
		 int p2 = rmq(right(p), (L+R) / 2 + 1, R , i, j);
		if (p1 == -1) return p2;                                          // if we try to access segment outside query
		if (p2 == -1) return p1;                                          // same as above
		return (A[p1] <= A[p2]) ? p1 : p2;                                // as in build routine
	}
	void update( int p,  int L,  int R,  int i,  int j) {
		if (A[st[left(p)]] <= A[st[right(p)]])
			st[p] = st[left(p)];
		else
			st[p] = st[right(p)];
	}
	void divide( int p,  int L,  int R,  int i,  int j,  int val){
		if (i > R || j < L) return;
		else if(L != R) {
			divide(left(p), L, (L+R) / 2, i, j, val);
			divide(right(p), (L+R) / 2 + 1, R, i, j, val);
			update(p , L, R, i, j);
		}
		else if(L == R) {
			A[st[p]] = val;
		}
	}
	public:
		SegmentTreeMin(const vi &_A) {
			A = _A; n = ( int)A.size();                                    // copy content for local usage
			st.assign(4 * n, 0);                                          // create large enough vector of zeroes
			build(1, 0, n - 1);                                           // recursive build
		}
		 int rmq( int i,  int j) { return rmq(1, 0, n - 1, i, j); }          // overloading
		 int rangeUpdate( int L,  int R,  int val) { 
			divide(1, 0, n - 1, L, R, val); 
		}
};

class SegmentTreeMax {                                                        // the segment tree is stored like a heap array
	private: vi st, A;                                                     // recall that vi is: typedef vector< int> vi;
	 int n;
	 int left ( int p) { return p << 1; } 								   // same as binary heap operations
	 int right( int p) { return (p << 1) + 1; }
	void build( int p,  int L,  int R) { 									   // O(n)
		if (L == R)                                                        // as L == R, either one is fine
		st[p] = L;                                                         // store the index
		else {                                                             // recursively compute the values
			build(left(p) , L , (L + R) / 2);
			build(right(p), (L + R) / 2 + 1, R );
			 int p1 = st[left(p)], p2 = st[right(p)];
			st[p] = (A[p1] >= A[p2]) ? p1 : p2;
	} }
	 int rmq( int p,  int L,  int R,  int i,  int j) {                          // O(log n)
		if (i > R || j < L) return -1;                                    // current segment outside query range i.e completely to the right or left resp.
		if (L >= i && R <= j) return st[p];                               // inside query range
		                                                                  // compute the min position in the left and right part of the  interval
		 int p1 = rmq(left(p) , L , (L+R) / 2, i, j);
		 int p2 = rmq(right(p), (L+R) / 2 + 1, R , i, j);
		if (p1 == -1) return p2;                                          // if we try to access segment outside query
		if (p2 == -1) return p1;                                          // same as above
		return (A[p1] >= A[p2]) ? p1 : p2;                                // as in build routine
	}
	void update( int p,  int L,  int R,  int i,  int j) {
		if (A[st[left(p)]] <= A[st[right(p)]])
			st[p] = st[left(p)];
		else
			st[p] = st[right(p)];
	}
	void divide( int p,  int L,  int R,  int i,  int j,  int val){
		if (i > R || j < L) return;
		else if(L != R) {
			divide(left(p), L, (L+R) / 2, i, j, val);
			divide(right(p), (L+R) / 2 + 1, R, i, j, val);
			update(p , L, R, i, j);
		}
		else if(L == R) {
			A[st[p]] = val;
		}
	}
	public:
		SegmentTreeMax(const vi &_A) {
			A = _A; n = ( int)A.size();                                    // copy content for local usage
			st.assign(4 * n, 0);                                          // create large enough vector of zeroes
			build(1, 0, n - 1);                                           // recursive build
		}
		 int rmq( int i,  int j) { return rmq(1, 0, n - 1, i, j); }          // overloading
		 int rangeUpdate( int L,  int R,  int val) { 
			divide(1, 0, n - 1, L, R, val); 
		}
};


int32_t main(void) {
	IOS;
	int n,k; cin>>n>>k;
	vi a(n);
	for(int i = 0; i < n; i++)
		cin>>a[i];
	// for(int i = 0; i <= n-k; i++) {
	// 	vi b=a;
	// 	cout<<i<<" "<<i+k-1<<endl;
	// 	sort(b.begin()+i, b.begin()+i+k);
	// 	for(int j: b) cout<<j<<" ";
	// 	cout<<endl;
	// }
	SegmentTreeMin stmin(a);
	SegmentTreeMax stmax(a);
	int longest[n];
	longest[n-1]=1;
	for(int i = n-2; i >= 0; i--) {
		if(a[i] < a[i+1])
			longest[i]=longest[i+1]+1;
		else longest[i]=1;
	}

	int cat[n]={};
	cat[0]=1; int cur=1;
	for(int i = 1; i < n; i++) {
		if(a[i-1] < a[i]) cat[i]=cur;
		else {
			cat[i]=cur+1; cur++;
		}
	}
	int ans=0,init=0;
	for(int i = 0; i < n; i++) {
		int lo = i, hi = i+k-1;
		if(hi >= n) break;
		if(cat[lo]==cat[hi]) init=1;
		else {
			if(lo-1 >= 0 && cat[lo-1]==cat[lo] && cat[hi-1]==cat[hi]) {
				// int end = lo+longest[lo]-1;
				int mn = a[stmin.rmq(lo,hi-1)], mx = a[stmax.rmq(lo,hi-1)];
				if(mx < a[hi] && mn > a[lo-1]){}
				else ans++;
			}
			else ans++;
		}
	}
	cout<<ans+init<<endl;
	time();
	return 0;
}

Measured memory_bytes: 20608