#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define all(a) a.begin(), a.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
typedef long long ll;

template<typename Monoid>
struct SegmentTree{ //セグメント木
private:
    int sz = 1; vector<Monoid> node;
    using Func = function<Monoid(Monoid, Monoid)>;
    const Func pick; const Monoid init; //モノイドに対する操作と、その単位元
public:
    SegmentTree(vector<Monoid> vec, const Func f, const Monoid m): pick(f), init(m) {
        while(sz < (int)vec.size())sz <<= 1;
        node = vector<Monoid>(sz * 2 - 1, init);
        for(int i = 0; i < (int)vec.size(); i++){
            node[i + sz - 1] = vec[i]; 
        }
        for(int i = sz - 2; i >= 0; i--){
            node[i] = pick(node[i * 2 + 1], node[i * 2 + 2]);
        }
    }
    void update(int i, Monoid v){ //単一の要素を変更する
        for(node[(i += sz) - 1] = v; i >>= 1;){
            node[i - 1] = pick(node[i * 2 - 1], node[i * 2]);
        }
    }
    void add(int i, Monoid v){ //単一の要素にある値を加える
        update(i, node[i + sz - 1] + v);
    }
    Monoid get(int l, int r){ //区間取得
        Monoid vl = init, vr = init;
        for((l += sz), (r += sz); l < r; (l >>= 1), (r >>= 1)){
            if(l & 1)vl = pick(vl, node[(l++) - 1]);
            if(r & 1)vr = pick(node[(--r) - 1], vr);
        }
        return pick(vl, vr);
    }
    inline Monoid operator [] (int i){ //[]でアクセス
        return node[i + sz - 1];
    }
};

template<typename Monoid>
struct LazySegmentTree{ //遅延評価セグメント木 (1-indexed)
private:

    int sz = 1, hei = 0;
    vector<Monoid> node, lazy;
    using Func1 = function<Monoid(Monoid, Monoid)>; //同一の配列内の値どうしの演算
    using Func2 = function<Monoid(Monoid, Monoid, int)>; //遅延配列の値をマージする演算
    const Func1 pick_n, pick_l; const Func2 merge;
    const Monoid init_n, init_l;

    inline Monoid reflect(int i, int l){
        return lazy[i] == init_l ? node[i] : merge(node[i], lazy[i], l);
    }
    
    inline void propagate(int i, int l){ //遅延配列を伝搬させる
        if(lazy[i] == init_l)return;
        if(i < sz){
            lazy[i << 1] = pick_l(lazy[i << 1], lazy[i]);
            lazy[i << 1 | 1] = pick_l(lazy[i << 1 | 1], lazy[i]);
        }
        node[i] = merge(node[i], lazy[i], l);
        lazy[i] = init_l;
    }

public:

    LazySegmentTree(vector<Monoid> vec, Monoid m1, const Monoid m2, 
                    const Func1 f1, const Func1 f2, const Func2 f3)
                    : init_n(m1), init_l(m2), pick_n(f1), pick_l(f2), merge(f3) {
        while(sz < (int)vec.size())sz <<= 1, ++hei;
        node = vector<Monoid>(sz << 1, init_n);
        lazy = vector<Monoid>(sz << 1, init_l);
        for(int i = 0; i < (int)vec.size(); i++){
            node[i + sz] = vec[i];
        }
        for(int i = sz - 1; i >= 1; i--){
            node[i] = pick_n(node[i << 1], node[i << 1 | 1]);
        }
    }

    void update(int l, int r, Monoid v){ //区間の値に対する操作
        l += sz, r += sz - 1;
        for(int i = hei; i >= 0; i--){
            propagate(l >> i, 1 << i);
            propagate(r >> i, 1 << i);
        }
        for(int tl = l, tr = r + 1, i = 1; tl < tr; tl >>= 1, tr >>= 1, i <<= 1){
            if(tl & 1)lazy[tl] = pick_l(lazy[tl], v), propagate(tl++, i);
            if(tr & 1)lazy[--tr] = pick_l(lazy[tr], v), propagate(tr, i);
        }
        int i = 0;
        while(l >>= 1, r >>= 1, l > 0){
            node[l] = pick_n(reflect(l << 1, 1 << i), reflect(l << 1 | 1, 1 << i));
            node[r] = pick_n(reflect(r << 1, 1 << i), reflect(r << 1 | 1, 1 << i));
            i++;
        }
    }

    Monoid get(int l, int r){ //区間取得
        Monoid res = init_n;
        l += sz, r += sz - 1;
        for(int i = hei; i >= 0; i--){
            propagate(l >> i, 1 << i);
            propagate(r >> i, 1 << i);
        }
        int i = 1;
        for(++r; l < r; l >>= 1, r >>= 1, i <<= 1){
            if(l & 1)propagate(l, i), res = pick_n(res, node[l++]);
            if(r & 1)propagate(--r, i), res = pick_n(res, node[r]);
        }
        return res;
    }

    inline Monoid operator [] (int i){ //[]でアクセス
        return get(i, i + 1);
    }

};

// AtCoder Grand Contest 038
int main(){

    int N, K;
    cin >> N >> K;
    vector<int> a(N);
    rep(i, N)cin >> a[i];

    const int inf = 300000;
    auto minget = [](int x, int y){ return min(x, y); };
    auto maxget = [](int x, int y){ return max(x, y); };
    SegmentTree<int> mi(a, minget, inf), ma(a, maxget, -inf);
    LazySegmentTree<int> seg(vector<int>(N, 0), 0, 0, [](int x, int y){ return x + y; }, [](int x, int y){ return x + y; }, [](int x, int y, int l){ return x + y * l; });
    
    int ans = N - K + 1;
    int l = 0, r = 1;
    while(r <= N){
        while(r < N and a[r - 1] < a[r]){
            r++;
        }
        if(r - l >= K){
            seg.update(l, r - K + 1, 1);
        }
        l = r;
        r++;
    }
    int sum = seg.get(0, N);
    if(sum)ans -= sum - 1;
    rep(i, N - K){
        if(a[i] < mi.get(i + 1, i + K) and ma.get(i + 1, i + K) < a[i + K] and seg[i + 1] == 0)ans--;
    }

    cout << ans << endl;
    return 0;

}

Measured memory_bytes: 10032