#include <bits/stdc++.h>
#include <functional> // for less  
#include <iostream>  
#define ll long long
#define ull unsigned long long 
#define ld long double
#define all(ar) ar.begin(), ar.end()
#define mp make_pair
#define sot(bello) bello.begin(),bello.end()
#define bitc  __builtin_popcountl
#define fr(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (int i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (int i = n - 1; i >= 0; i--)
#define fill(ar,val) rep(i,sizeof(ar)/sizeof(ll)) ar[i]=val
#define fill0(ar) fill((ar), 0)
#define foreach(it,ar) for ( typeof(ar.begin()) it = ar.begin(); it != ar.end(); it++ )
#define fillinf(ar, n) fr(i,0,(n)) ar[i] = INF
#define MAXN   100010 
#define MOD 1000000007
#define debug(x) cout<<#x<<": "<<x<<endl
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}
#define dbug(x) cout<<#x<<": "<<x<<" "
auto clk=clock();
#define PI 3.1415926535897932385
#define fi first
#define se second
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}

# define INF LLONG_MAX
const int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
const int dx8[]={-1,-1,-1,0,1,1,1,0}, dy8[]={-1,0,1,1,1,0,-1,-1};
/* This Template is authored by Ankit Anvesh */


using namespace std;


mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// gcd for negatives too
/* ll gcd(ll a, ll b) {
 if (a == 0) return b;
 if (b == 0) return a;
 if (b < 0) return gcd(a, -1 * b);
 if (a < 0) return gcd(-1 * a, b);
 if (a > b) return gcd(b, a);
 return gcd(b%a, a);
}
 */


//gcd


//do not use n , N , C


// Using iterators in C++ 
//set<ll>:: iterator it;
// string to integer stuuu()
// string to long long stoll()
// string to float stof
// string.substr(position,length);
// integer to string to_string();
    
 
   


int n;

int minVal(int x, int y) { return (x < y)? x: y; }  
  
// A utility function to get the  
// middle index from corner indexes.  
int getMid(int s, int e) { return s + (e -s)/2; }  
  
/* A recursive function to get the 
minimum value in a given range  
of array indexes. The following  
are parameters for this function.  
  
    st --> Pointer to segment tree  
    index --> Index of current node in the  
           segment tree. Initially 0 is  
           passed as root is always at index 0  
    ss & se --> Starting and ending indexes  
                of the segment represented  
                by current node, i.e., st[index]  
    qs & qe --> Starting and ending indexes of query range */
int RMQUtil(int *st, int ss, int se, int qs, int qe, int index)  
{  
    // If segment of this node is a part  
    // of given range, then return  
    // the min of the segment  
    if (qs <= ss && qe >= se)  
        return st[index];  
  
    // If segment of this node 
    // is outside the given range  
    if (se < qs || ss > qe)  
        return INT_MAX;  
  
    // If a part of this segment 
    // overlaps with the given range  
    int mid = getMid(ss, se);  
    return minVal(RMQUtil(st, ss, mid, qs, qe, 2*index+1),  
                RMQUtil(st, mid+1, se, qs, qe, 2*index+2));  
}  
  
// Return minimum of elements in range 
// from index qs (quey start) to  
// qe (query end). It mainly uses RMQUtil()  
int RMQ(int *st, int n, int qs, int qe)  
{  
    // Check for erroneous input values  
    if (qs < 0 || qe > n-1 || qs > qe)  
    {  
        cout<<"Invalid Input";  
        return -1;  
    }  
  
    return RMQUtil(st, 0, n-1, qs, qe, 0);  
}  
  
// A recursive function that constructs 
// Segment Tree for array[ss..se].  
// si is index of current node in segment tree st  
int constructSTUtil(int arr[], int ss, int se, 
                                int *st, int si)  
{  
    // If there is one element in array, 
    // store it in current node of  
    // segment tree and return  
    if (ss == se)  
    {  
        st[si] = arr[ss];  
        return arr[ss];  
    }  
  
    // If there are more than one elements,  
    // then recur for left and right subtrees  
    // and store the minimum of two values in this node  
    int mid = getMid(ss, se);  
    st[si] = minVal(constructSTUtil(arr, ss, mid, st, si*2+1),  
                    constructSTUtil(arr, mid+1, se, st, si*2+2));  
    return st[si];  
}  
  
/* Function to construct segment tree  
from given array. This function allocates 
memory for segment tree and calls constructSTUtil() to  
fill the allocated memory */
int *constructST(int arr[], int n)  
{  
    // Allocate memory for segment tree  
  
    //Height of segment tree  
    int x = (int)(ceil(log2(n)));  
  
    // Maximum size of segment tree  
    int max_size = 2*(int)pow(2, x) - 1;  
  
    int *st = new int[max_size];  
  
    // Fill the allocated memory st  
    constructSTUtil(arr, 0, n-1, st, 0);  
  
    // Return the constructed segment tree  
    return st;  
}






 
  
/*  A recursive function to get the sum of 
    values in given range of the array.  
    The following are parameters for this 
    function. 
  
    st       -> Pointer to segment tree 
    node     -> Index of current node in  
                the segment tree . 
    ss & se  -> Starting and ending indexes  
                of the segment represented 
                by current node, i.e., st[node] 
    l & r    -> Starting and ending indexes  
                of range query */
int MaxUtil(int* st, int ss, int se, int l,  
            int r, int node) 
{ 
    // If segment of this node is completely 
    // part of given range, then return  
    // the max of segment 
    if (l <= ss && r >= se) 
        return st[node]; 
  
    // If segment of this node does not 
    // belong to given range 
    if (se < l || ss > r) 
        return -1; 
  
    // If segment of this node is partially 
    // the part of given range 
    int mid = getMid(ss, se); 
      
    return max(MaxUtil(st, ss, mid, l, r,  
                       2 * node + 1), 
               MaxUtil(st, mid + 1, se, l,  
                       r, 2 * node + 2)); 
} 
  
/* A recursive function to update the nodes which 
   have the given index in their range. The following 
   are parameters st, ss and se are same as defined 
   above index -> index of the element to be updated.*/
void updateValue(int arr[], int* st, int ss, int se,  
                 int index, int value, int node) 
{ 
    if (index < ss || index > se)  
    { 
        cout << "Invalid Input" << endl; 
        return; 
    } 
      
    if (ss == se)  
    {    
        // update value in array and in segment tree 
        arr[index] = value; 
        st[node] = value; 
    } 
    else { 
            int mid = getMid(ss, se); 
              
            if (index >= ss && index <= mid) 
                updateValue(arr, st, ss, mid, index,  
                            value, 2 * node + 1); 
            else
                updateValue(arr, st, mid + 1, se,  
                            index, value, 2 * node + 2); 
              
            st[node] = max(st[2 * node + 1],  
                       st[2 * node + 2]); 
    } 
    return; 
} 
  
// Return max of elements in range from 
// index l (query start) to r (query end). 
int getMax(int* st, int n, int l, int r) 
{ 
    // Check for erroneous input values 
    if (l < 0 || r > n - 1 || l > r)  
    { 
        printf("Invalid Input"); 
        return -1; 
    } 
  
    return MaxUtil(st, 0, n - 1, l, r, 0); 
} 
  
// A recursive function that constructs Segment 
// Tree for array[ss..se]. si is index of  
// current node in segment tree st 
int constructSTUtil1(int arr[], int ss, int se,  
                    int* st, int si) 
{ 
    // If there is one element in array, store 
    // it in current node of segment tree and return 
    if (ss == se)  
    { 
        st[si] = arr[ss]; 
        return arr[ss]; 
    } 
  
    // If there are more than one elements, then 
    // recur for left and right subtrees and  
    // store the max of values in this node 
    int mid = getMid(ss, se); 
      
    st[si] = max(constructSTUtil1(arr, ss, mid, st,  
                                 si * 2 + 1), 
                 constructSTUtil1(arr, mid + 1, se,  
                                 st, si * 2 + 2)); 
      
    return st[si]; 
} 
  
/* Function to construct segment tree from given array. 
   This function allocates memory for segment tree.*/
int* constructST1(int arr[], int n) 
{ 
    // Height of segment tree 
    int x = (int)(ceil(log2(n))); 
  
    // Maximum size of segment tree 
    int max_size = 2 * (int)pow(2, x) - 1; 
  
    // Allocate memory 
    int* st = new int[max_size]; 
  
    // Fill the allocated memory st 
    constructSTUtil1(arr, 0, n - 1, st, 0); 
  
    // Return the constructed segment tree 
    return st; 
} 

int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll txt=1;
//cin>>txt;
while(txt--)
{  
   cin>>n;
    int k;
    cin>>k;
    int ar[n];
    rep(i,n) cin>>ar[i];
    int *st=constructST1(ar,n);
    int *st1=constructST(ar,n);
    int op=0;
    int mx=getMax(st,n,0,k-1);
    int mi=RMQ(st1,n,0,k-1);
  // debug(mx); debug(mi);
   stack<pair<int,int>> s;
   //s.push({ar[0],0});
   map<int,int> ma;
   rep(i,n){
       //if(i==0) continue;
        if(s.empty()){
            s.push({ar[i],i});
            if(s.size()==k){
                s.pop();
                ma[i]=1;
            }
            continue;
        }
        if(ar[i]>=s.top().first){
            s.push({ar[i],i});
            if(s.size()==k){
                while (s.empty()==false)
                {
                    s.pop();
                }
                ma[i-k+1]=1;
                
            }
        }
        else
        {
            while (s.empty()==false)
                {
                    s.pop();
                }
             s.push({ar[i],i});   
        }
        
   }
   ll oi=0;
   for(auto x:ma){
       //cout<<x.first<<" ";
       oi++;
   }
   //cout<<endl;
   if(ma[0]==0)
    op++;

    for(int i=k;i<=n-1;i++){
        /* if(ma[i-k+1]) continue; */
        if(ar[i]>=mx ){
            if(mi==ar[i-k]){

            }
            else
            {
                if(ma[i-k+1]==0)
                op++;
            }
            
            int moi=RMQ(st1,n,i-k+1,i);
            
            mi=moi;
            mx=ar[i];
        }
        else
        {
            mi=RMQ(st1,n,i-k+1,i);
            mx=getMax(st,n,i-k+1,i);
            if(ma[i-k+1]==0)
            op++;
        }
        
    }
    //debug(ma.size());
    if(oi){
        op++;
    }

    cout<<op<<endl;












}
//return 0;
}









Measured memory_bytes: 14464