//g++ -std=c++14 test.cpp -o test.out

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <iomanip>
#include <vector>
#include <queue>
#include <stack>
#include <map> 
#include <unordered_map> 
#include <utility>
#include <limits.h>
#include <bitset>
#include <set>
using namespace std;
 
#define LL long long int
const LL INF = (1LL<<60);
const int INF_INT = 2147483647-1e6-1;
const LL mod = 1000000007ll;
const int mod_int = 1000000007;

//遅延伝搬なし、型を指定できるセグ木
template<typename Monoid>
struct SegmentTree {
    vector<Monoid> data;
    LL n;
    const function<Monoid(Monoid, Monoid)> f;
    const Monoid M;
    //std::functionを使うと関数やラムダ式を格納できる
    SegmentTree(LL x, const function<Monoid(Monoid, Monoid)> f, const Monoid &M) : f(f), M(M) {
        n = 1;
        while(n<x) n <<= 1;
        data.resize(2*n,M);
    }
    //一番下位のノード（実数値が保管されている）を書き換え
    void set(LL k, const Monoid &p) {
        data[k+n] = p;
    }
    //セグ木の全体を構築
    void build() {
        for(int k = n-1; k > 0; --k) {
            //ノードkには自分より下位の数のうち、関数fで判断された数を格納する
            //k=n~2*n-1はセグ木の一番下のノードが対応する
            data[k] = f(data[2*k + 0], data[2*k + 1]);
        }
    }
    //一番下位のノード（実数値が保管されている）を書き換えた上で、
    //そこより上のノードを順に更新していく
    void update(LL k, const Monoid &p) {
        k += n;
        data[k] = p;//一番下位のノード（実数値が保管されている）を書き換え
        while (k >>= 1) {
            data[k] = f(data[k*2], data[k*2 + 1]);
        }
    }
    Monoid query(LL a,LL b) {
        Monoid L = M, R = M;
        for(a += n, b += n; a<b; a >>= 1, b >>= 1) {
            if(a&1) L = f(L, data[a++]);
            if(b&1) R = f(data[--b], R);
        }
        return f(L,R);
    }
    //保管されている、一番下のノードの対応する位置の数値を返す
    Monoid operator[](const LL &k) const {
        return data[k+n];
    }
};

LL N,K;
LL P[200000];

LL ans = 0;

void solve(){
    SegmentTree<LL> segmin(N,[](LL a,LL b){return min(a,b);},INF);
    SegmentTree<LL> segmax(N,[](LL a,LL b){return max(a,b);},-INF);
    //セグ木の一番下のノードの、i番目にP[i]を格納
    for(int i=0;i<N;i++){
        segmin.update(i,P[i]);
        segmax.update(i,P[i]);
    }

    //0~iまで見た時、昇順になっていない隣り合う要素の組の数を
    //ascend_accum[i]とする
    vector<LL> ascend_accum(N,0);
    for(int i=1;i<N;i++){
        ascend_accum[i] = ascend_accum[i-1] + (P[i]<P[i-1]);
    }

    int left = 1;//ギリOK
    int right = K+1;//ギリout
    ans = 1;
    //ソートしなくても元々昇順であるような部分列が
    //既に出てきたかどうかをascend_prevとする
    bool ascend_prev = (ascend_accum[K-1]==0);
    for(left=1;right<=N;){
        LL segment_min = segmin.query(left,right);
        LL segment_max = segmax.query(left,right);
        // for(int i=0;i<N;i++){
        //     if(i<left || i>=right) cout << "  ";
        //     else cout << P[i] << " ";
        // }
        // cout << endl;
        bool ascend_now = (ascend_accum[right-1]-ascend_accum[left]==0);
        if(!(ascend_prev && ascend_now) && !(P[left-1]<segment_min && P[right-1]==segment_max)){
            if(ascend_now) ascend_prev = ascend_now;
            ans++;
        }
        left++;right++;
    }
}

int main(){
    cin >> N >> K;
    for(int i=0;i<N;i++){
    	cin >> P[i];
    }

    solve();

    cout << ans << endl;
    return 0;
}

Measured memory_bytes: 11520