#include<bits/stdc++.h>

#define debug(n) cerr << #n << ':' << n << endl;

using namespace std;

using  ll = long long;

template<class T,class U>
using umap = unordered_map<T,U>;

template<class T>
using uset = unordered_set<T>;

template<class T>
inline bool change_max(T&a, const T&b){
  if(b > a){
    a = b;
    return true;
  }
  return false;
}

template<class T>
inline bool change_min(T&a, const T&b){
  if(a > b){
    a = b;
    return true;
  }
  return false;
}

struct MaxSegmentTree{
  int size_;
  int length_;
  vector<ll> data_;
  umap<int, int> par_info_;
  umap<int, pair<int, int>> chil_info_;

  MaxSegmentTree(int size)
    :size_(CalcSize(size)), length_((size_+1)/2), data_(size_, -(1e+18))
  { Init(); }
  
  int CalcSize(int size)
  { int n = 1; while(n < size)n *= 2; return 2 * n - 1; }
  void Init(){
    for(int i = (size_/2)-1; i >= 0; --i){
      int l = i*2 + 1, r = i*2 + 2;
      par_info_[l] = i;
      par_info_[r] = i;
      chil_info_[i] = {l,r};
    }
  }
  
  void Set(int idx, ll x){
    int pos = (size_/2)+idx;
    data_[pos] = x;
    while(pos != 0){
      pos = par_info_[pos];
      ll l, r;tie(l, r) = chil_info_[pos];
      data_[pos] = max(data_[l], data_[r]);
    }
  }
  
  ll GetMax(int target_l, int target_r, int idx = 0,
	    int range_l = 0, int range_r = -1){
    if(range_r == -1){
      range_r = length_;
      if(target_l > target_r || target_l < 0 || target_r > length_){
	cerr << "SegmentTree GetMin target index error\n";
	cerr << "target_l:" << target_l << " target_r:" << target_r << endl;
	return -(1e+18);
      }
    }
    
    if(target_r <= range_l || target_l >= range_r) return -(1e+18);
    if(target_r >= range_r && target_l <= range_l) return data_[idx];

    int l, r; tie(l, r) = chil_info_[idx];
    int mid = (range_l + range_r)/2;

    ll val_l = GetMax(target_l, target_r, l, range_l, mid);
    ll val_r = GetMax(target_l, target_r, r, mid, range_r);

    return max(val_l, val_r);
  }  
};

struct MinSegmentTree{
  int size_;
  int length_;
  vector<ll> data_;
  umap<int, int> par_info_;
  umap<int, pair<int, int>> chil_info_;

  MinSegmentTree(int size)
    :size_(CalcSize(size)), length_((size_+1)/2), data_(size_, 1e+18)
  { Init(); }
  
  int CalcSize(int size)
  { int n = 1; while(n < size)n *= 2; return 2 * n - 1; }
  void Init(){
    for(int i = (size_/2)-1; i >= 0; --i){
      int l = i*2 + 1, r = i*2 + 2;
      par_info_[l] = i;
      par_info_[r] = i;
      chil_info_[i] = {l,r};
    }
  }
  
  void Set(int idx, ll x){
    int pos = (size_/2)+idx;
    data_[pos] = x;
    while(pos != 0){
      pos = par_info_[pos];
      ll l, r;tie(l, r) = chil_info_[pos];
      data_[pos] = min(data_[l], data_[r]);
    }
  }
  
  ll GetMin(int target_l, int target_r, int idx = 0,
	    int range_l = 0, int range_r = -1){
    if(range_r == -1){
      range_r = length_;
      if(target_l > target_r || target_l < 0 || target_r > length_){
	cerr << "SegmentTree GetMin target index error\n";
	cerr << "target_l:" << target_l << " target_r:" << target_r << endl;
	return 1e+18;
      }
    }
    
    if(target_r <= range_l || target_l >= range_r) return 1e+18;
    if(target_r >= range_r && target_l <= range_l) return data_[idx];

    int l, r; tie(l, r) = chil_info_[idx];
    int mid = (range_l + range_r)/2;

    ll val_l = GetMin(target_l, target_r, l, range_l, mid);
    ll val_r = GetMin(target_l, target_r, r, mid, range_r);

    return min(val_l, val_r);
  }
  
};


struct UFT{
  vector<int>p;
  
  UFT(int N):p(vector<int>(N,-1)){}
  int par(int a)   { if( p[a] >= 0 ){ p[a] = par( p[a] ); return p[a]; } return a;  }
  int size(int a)  { return -p[par(a)]; }
  bool	same(int a, int b) { return par(a) == par(b); }
  void unite(int a, int b){
    a = par(a);  b = par(b);
    if( a == b ) return;
    if( size(a) < size(b) )a^=b^=a^=b;
    p[a] -= size(b);
    p[b] = a;
  }
};


int main(){
  int n, k; cin >> n >> k;
  vector<int> p(n);
  MaxSegmentTree max_seg(n);
  MinSegmentTree min_seg(n);
  UFT uft(n);
  for(int i = 0; i < n; ++i){
    int x; cin >> x;
    max_seg.Set(i,x);
    min_seg.Set(i,x);   
    p[i] = x;
  }
  
  int prepre=-1;
  int cnt_sorted = 0, sorted_len = 1;
  for(int i = 1; i < n; ++i){
    if(p[i] > p[i-1]) sorted_len++;
    else {
      sorted_len = 1;
      prepre = -1;
    }
    if(sorted_len >= k){
      cnt_sorted++;
      if(prepre == -1)prepre = i;
      else {
	uft.unite(prepre, i);
      }
    }
  }
  int cnt_common = 0;
  int kaburi = 0;
  for(int i = k; i < n; ++i){
    int l = i-k+1, r = i, x = i-k, y = i;    
    if(max_seg.GetMax(l,r) < p[y] && min_seg.GetMin(l,r) > p[x]){
      cnt_common++;
      if(uft.same(i, i-1)) kaburi++;
    }
  }
  if(cnt_sorted > 0) cnt_sorted--;
  int dec = cnt_sorted + cnt_common - kaburi;
  int ans = n - k + 1 - dec;
  cout << ans << endl;
  return 0;
}


Measured memory_bytes: 88580