#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
using ll = long long;
using vec = vector<ll>;
using vect = vector<double>;
using Graph = vector<vector<ll>>;
#define loop(i, n) for (ll i = 0; i < n; i++)
#define Loop(i, m, n) for (ll i = m; i < n; i++)
#define pool(i, n) for (ll i = n; i >= 0; i--)
#define Pool(i, m, n) for (ll i = n; i >= m; i--)
#define mod 1000000007ll
//#define mod 998244353ll
#define flagcount __builtin_popcount
#define flag(x) (1ll << x)
#define flagadd(bit, x) bit |= flag(x)
#define flagpop(bit, x) bit &= ~flag(x)
#define flagon(bit, i) bit &flag(i)
#define flagoff(bit, i) !(bit & (1ll << i))
#define all(v) v.begin(), v.end()
#define low2way(v, x) lower_bound(all(v), x)
#define high2way(v, x) upper_bound(all(v), x)
#define idx_lower(v, x) (distance(v.begin(), low2way(v, x)))  //配列vでx未満の要素数を返す
#define idx_upper(v, x) (distance(v.begin(), high2way(v, x))) //配列vでx以下の要素数を返す
#define idx_lower2(v, x) (v.size() - idx_lower(v, x))         //配列vでx以上の要素数を返す
#define idx_upper2(v, x) (v.size() - idx_upper(v, x))         //配列vでxより大きい要素の数を返す
#define putout(a) cout << a << endl
#define Sum(v) accumulate(all(v), 0ll)
#define gcd(x, y) __gcd(x, y)
ll ctoi(char c)
{
    if (c >= '0' && c <= '9')
    {
        return c - '0';
    }
    return -1;
}
template <typename T>
string make_string(T N)
{
    string ret;
    T now = N;
    while (now > 0)
    {
        T x = now % 10;
        ret += (char)('0' + x);
        now /= 10;
    }
    reverse(all(ret));
    return ret;
}
template <typename T>
T lcm(T x, T y)
{
    T z = gcd(x, y);
    return x * y / z;
}
template <typename T>
bool primejudge(T n)
{
    if (n < 2)
        return false;
    else if (n == 2)
        return true;
    else if (n % 2 == 0)
        return false;
    double sqrtn = sqrt(n);
    for (T i = 3; i < sqrtn + 1; i++)
    {
        if (n % i == 0)
        {
            return false;
        }
        i++;
    }
    return true;
}
template <typename T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
//場合によって使い分ける
//const ll dx[4]={1,0,-1,0};
//const ll dy[4]={0,1,0,-1};
const ll dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
//2次元配列の宣言
//vector<vector<ll>> field(h, vector<ll>(w));

struct Segment_Tree_Beats
{
    const long long INF = 1e18 + 9;
    long long n, n0;
    vector<long long> fmax;   //最大値
    vector<long long> smax;   //2番目に大きい値
    vector<long long> fmax_c; //最大値の個数
    vector<long long> fmin;   //最小値
    vector<long long> smin;   //2番目に小さい値
    vector<long long> fmin_c; //最小値の個数
    vector<long long> sum;    //区間和
    vector<long long> len;    //区間の長さ
    vector<long long> ladd;   //遅延加算
    vector<long long> lval;   //遅延更新
    Segment_Tree_Beats(long long N) : n(N), fmax(4 * N), smax(4 * N), fmax_c(4 * N), fmin(4 * N), smin(4 * N),
                                      fmin_c(4 * N), sum(4 * N), len(4 * N), ladd(4 * N), lval(4 * N)
    {
        n0 = 1;
        while (n0 < n)
            n0 *= 2;
        len[0] = n0;
        for (long long i = 0; i < 2 * n0; i++)
        {
            lval[i] = INF;
        }
        for (long long i = 0; i < n0 - 1; i++)
        {
            len[2 * i + 1] = len[i] / 2;
            len[2 * i + 2] = len[i] / 2;
        }

        for (long long i = 0; i < n; i++)
        {
            long long nn = n0 - 1 + i;
            smax[nn] = -INF;
            smin[nn] = INF;
            fmax_c[nn] = 1;
            fmin_c[nn] = 1;
        }
        for (long long i = n; i < n0; i++)
        {
            long long nn = n0 - 1 + i;
            fmax[nn] = -INF;
            smax[nn] = -INF;
            fmin[nn] = INF;
            smin[nn] = INF;
        }
        for (long long i = n0 - 2; i >= 0; i--)
        {
            update(i);
        }
    }
    Segment_Tree_Beats(long long N, vector<long long> &A) : n(N), fmax(4 * N), smax(4 * N), fmax_c(4 * N), fmin(4 * N), smin(4 * N),
                                                            fmin_c(4 * N), sum(4 * N), len(4 * N), ladd(4 * N), lval(4 * N)
    {
        n0 = 1;
        while (n0 < n)
            n0 *= 2;
        len[0] = n0;
        for (long long i = 0; i < 2 * n0; i++)
        {
            lval[i] = INF;
        }
        for (long long i = 0; i < n0 - 1; i++)
        {
            len[2 * i + 1] = len[i] / 2;
            len[2 * i + 2] = len[i] / 2;
        }

        for (long long i = 0; i < n; i++)
        {
            long long nn = n0 - 1 + i;
            fmax[nn] = A[i];
            fmin[nn] = A[i];
            sum[nn] = A[i];
            smax[nn] = -INF;
            smin[nn] = INF;
            fmax_c[nn] = 1;
            fmin_c[nn] = 1;
        }
        for (long long i = n; i < n0; i++)
        {
            long long nn = n0 - 1 + i;
            fmax[nn] = -INF;
            smax[nn] = -INF;
            fmin[nn] = INF;
            smin[nn] = INF;
        }
        for (long long i = n0 - 2; i >= 0; i--)
        {
            update(i);
        }
    }
    void update_node_max(long long k, long long x)
    {
        sum[k] += (x - fmax[k]) * fmax_c[k];
        if (fmax[k] == fmin[k])
        {
            fmax[k] = x;
            fmin[k] = x;
        }
        else
        {
            if (fmax[k] == smin[k])
            {
                fmax[k] = x;
                smin[k] = x;
            }
            else
                fmax[k] = x;
        }
        //遅延処理
        if (lval[k] != INF && x < lval[k])
            lval[k] = x;
    }
    void update_node_min(long long k, long long x)
    {
        sum[k] += (x - fmin[k]) * fmin_c[k];
        if (fmin[k] == fmax[k])
        {
            fmin[k] = x;
            fmax[k] = x;
        }
        else
        {
            if (fmin[k] == smax[k])
            {
                fmin[k] = x;
                smax[k] = x;
            }
            else
                fmin[k] = x;
        }
        //遅延処理
        if (lval[k] != INF && lval[k] < x)
            lval[k] = x;
    }
    //全体加算
    void addall(long long k, long long x)
    {
        fmax[k] += x;
        fmin[k] += x;
        if (smax[k] != -INF)
            smax[k] += x;
        if (smin[k] != INF)
            smin[k] += x;
        sum[k] += len[k] * x;
        if (lval[k] != INF)
            lval[k] += x;
        else
            ladd[k] += x;
    }
    //全体更新
    void updateall(long long k, long long x)
    {
        fmax[k] = x;
        fmin[k] = x;
        smax[k] = -INF;
        smin[k] = INF;
        fmax_c[k] = len[k];
        fmin_c[k] = len[k];
        sum[k] = x * len[k];
        lval[k] = x;
        ladd[k] = 0;
    }
    //親->子への伝播
    void push(long long k)
    {
        if ((k - n0 + 1) >= 0)
            return;
        //遅延伝播
        if (lval[k] != INF)
        {
            updateall(2 * k + 1, lval[k]);
            updateall(2 * k + 2, lval[k]);
            lval[k] = INF;
            return;
        }
        if (ladd[k] != 0)
        {
            addall(2 * k + 1, ladd[k]);
            addall(2 * k + 2, ladd[k]);
            ladd[k] = 0;
        }
        for (int i = 1; i <= 2; i++)
        {
            if (fmax[k] < fmax[2 * k + i])
                update_node_max(2 * k + i, fmax[k]);
            if (fmin[k] > fmin[2 * k + i])
                update_node_min(2 * k + i, fmin[k]);
        }
    }
    //子->親への伝播
    void update(long long k)
    {
        sum[k] = sum[2 * k + 1] + sum[2 * k + 2];
        //最大値関連の更新(大きい方を優先)
        if (fmax[2 * k + 1] < fmax[2 * k + 2])
        {
            fmax[k] = fmax[2 * k + 2];
            fmax_c[k] = fmax_c[2 * k + 2];
            smax[k] = max(fmax[2 * k + 1], smax[2 * k + 2]);
        }
        if (fmax[2 * k + 1] > fmax[2 * k + 2])
        {
            fmax[k] = fmax[2 * k + 1];
            fmax_c[k] = fmax_c[2 * k + 1];
            smax[k] = max(fmax[2 * k + 2], smax[2 * k + 1]);
        }
        if (fmax[2 * k + 1] == fmax[2 * k + 2])
        {
            fmax[k] = fmax[2 * k + 1];
            fmax_c[k] = fmax_c[2 * k + 1] + fmax_c[2 * k + 2];
            smax[k] = max(smax[2 * k + 1], smax[2 * k + 2]);
        }
        //最小値関連の更新(小さい方を優先)
        if (fmin[2 * k + 1] < fmin[2 * k + 2])
        {
            fmin[k] = fmin[2 * k + 1];
            fmin_c[k] = fmin_c[2 * k + 1];
            smin[k] = min(fmin[2 * k + 2], smin[2 * k + 1]);
        }
        if (fmin[2 * k + 1] > fmin[2 * k + 2])
        {
            fmin[k] = fmin[2 * k + 2];
            fmin_c[k] = fmin_c[2 * k + 2];
            smin[k] = min(fmin[2 * k + 1], smin[2 * k + 2]);
        }
        if (fmin[2 * k + 1] == fmin[2 * k + 2])
        {
            fmin[k] = fmin[2 * k + 1];
            fmin_c[k] = fmin_c[2 * k + 1] + fmin_c[2 * k + 2];
            smin[k] = max(smin[2 * k + 1], smin[2 * k + 2]);
        }
    }
    //区間[a,b)内のiについてa[i]をmax(a[i],x)に更新
    void _update_max(long long x, long long a, long long b, long long k, long long l, long long r)
    {
        //区間をはみ出すorｘが最小値以下
        if (b <= l || r <= a || fmin[k] >= x)
            return;
        //(最小値)<x<(2番目に小さい値)のとき
        if (l >= a && r <= b && smin[k] > x)
        {
            update_node_min(k, x);
            return;
        }
        //親->子->親
        push(k);
        _update_max(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _update_max(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }
    //区間[a,b)内のiについてa[i]をmin(a[i],x)に更新
    void _update_min(long long x, long long a, long long b, long long k, long long l, long long r)
    {
        //区間をはみ出すorｘが最大値以上
        if (b <= l || r <= a || fmax[k] <= x)
            return;
        //(2番目に大きい値)<x<(最大値)のとき
        if (l >= a && r <= b && smax[k] < x)
        {
            update_node_max(k, x);
            return;
        }
        //親->子->親
        push(k);
        _update_min(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _update_min(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }
    //区間[a,b)に対する最大値クエリ
    long long _query_max(long long a, long long b, long long k, long long l, long long r)
    {
        if (b <= l || a >= r)
            return -INF; //区間外
        if (a <= l && r <= b)
            return fmax[k];
        push(k);
        long long L = _query_max(a, b, 2 * k + 1, l, (l + r) / 2);
        long long R = _query_max(a, b, 2 * k + 2, (l + r) / 2, r);
        return max(L, R);
    }
    //区間[a,b)に対する最小値クエリ
    long long _query_min(long long a, long long b, long long k, long long l, long long r)
    {
        if (b <= l || a >= r)
            return INF; //区間外
        if (a <= l && r <= b)
            return fmin[k];
        push(k);
        long long L = _query_min(a, b, 2 * k + 1, l, (l + r) / 2);
        long long R = _query_min(a, b, 2 * k + 2, (l + r) / 2, r);
        return min(L, R);
    }
    //区間[a,b)に対する区間和クエリ
    long long _query_sum(long long a, long long b, long long k, long long l, long long r)
    {
        if (b <= l || a >= r)
            return 0; //区間外
        if (a <= l && r <= b)
            return sum[k];
        push(k);
        long long L = _query_sum(a, b, 2 * k + 1, l, (l + r) / 2);
        long long R = _query_sum(a, b, 2 * k + 2, (l + r) / 2, r);
        return (L + R);
    }
    //区間[a,b)に対する区間加算クエリ
    void _query_add(long long x, long long a, long long b, long long k, long long l, long long r)
    {
        if (b <= l || a >= r)
            return; //区間外
        if (a <= l && r <= b)
        {
            addall(k, x);
            return;
        }
        push(k);
        _query_add(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _query_add(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }
    //区間[a,b)に対する区間更新クエリ
    void _query_val(long long x, long long a, long long b, long long k, long long l, long long r)
    {
        if (b <= l || a >= r)
            return; //区間外
        if (a <= l && r <= b)
        {
            updateall(k, x);
            return;
        }
        push(k);
        _query_val(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _query_val(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }
    //以下外から利用するメンバ関数を羅列///////////////////////////////////////
    //区間[l,r]内のiについてa[i]をmax(a[i],x)に更新
    void update_max(long long l, long long r, long long x)
    {
        _update_max(x, l, r + 1, 0, 0, n0);
    }
    //区間[l,r]内のiについてa[i]をmin(a[i],x)に更新
    void update_min(long long l, long long r, long long x)
    {
        _update_min(x, l, r + 1, 0, 0, n0);
    }
    //区間[l,r]内のiについてa[i]にxを加算
    void query_add(long long l, long long r, long long x)
    {
        _query_add(x, l, r + 1, 0, 0, n0);
    }
    //区間[l,r]内のiについてa[i]をxに更新
    void query_val(long long l, long long r, long long x)
    {
        _query_val(x, l, r + 1, 0, 0, n0);
    }
    //区間[l,r]に対する最大値クエリ
    long long query_max(long long l, long long r)
    {
        return _query_max(l, r + 1, 0, 0, n0);
    }
    //区間[l,r]に対する最小値クエリ
    long long query_min(long long l, long long r)
    {
        return _query_min(l, r + 1, 0, 0, n0);
    }
    //区間[l,r]に対する区間和クエリ
    long long query_sum(long long l, long long r)
    {
        return _query_sum(l, r + 1, 0, 0, n0);
    }
};
/*
<Segment Tree Beats>
様々なクエリに対応した万能遅延セグメント木(0-indexed)
Segment_Tree_Beats tree(N);もしくは
Segment_Tree_Beats tree(N,a);などで宣言(N:配列のサイズ,a:入れたい配列)
tree.update_max(l,r,x):区間[l,r]内のiについてa[i]をmax(a[i],x)に更新
tree.update_min(l,r,x):区間[l,r]内のiについてa[i]をmin(a[i],x)に更新
tree.query_add(l,r,x):区間[l,r]内のiについてa[i]にxを加算
tree.query_val(l,r,x):区間[l,r]内のiについてa[i]をxに更新
tree.query_max(l,r):区間[l,r]に対する最大値クエリ
tree.query_min(l,r):区間[l,r]に対する最小値クエリ
tree.query_sum(l,r):区間[l,r]に対する区間和クエリ
*/
/*
このunion_find木で出来ること
例)union_find tree(N);などで宣言(N:頂点数)
tree.same(x,y):要素xと要素yが同じグループに属するか判定
tree.unite(x,y):要素xが属する木と要素yが属するグループの併合
tree.size(x,y):要素xが属する木の頂点数を返す
(おまけ)
partial(union_find tree):treeがいくつの木からなるかを返す
※グループの分割が出来ないことに注意！
計算量O(α(N))(ほぼO(1))
*/
struct union_find
{
    vector<long long> par;  //親の番号　
    vector<long long> rank; //木の深さ(根のランクは0)
    vector<long long> siz;  //要素xが根なら木の頂点数を格納する
    //初期化子リストを用いた初期化
    union_find(long long N) : par(N), rank(N), siz(N)
    {
        for (long long i = 0; i < N; i++)
        {
            par[i] = i;
            rank[i] = 0;
            siz[i] = 1;
        }
    }
    //要素xが所属する木の根を再帰的に発見する
    long long root(long long x)
    {
        if (par[x] == x)
            return x;
        return par[x] = root(par[x]); //経路圧縮
    }
    //要素xが属する木と要素yが属する木の併合
    void unite(long long x, long long y)
    {
        long long rx = root(x);
        long long ry = root(y);
        if (rx == ry)
            return; //同じ木に属してたらそのまま
        if (rank[rx] < rank[ry])
        {
            par[rx] = ry; //根がryの木に併合
            siz[ry] = siz[rx] + siz[ry];
        }
        else
        {
            par[ry] = rx; //根がrxの木に併合
            siz[rx] = siz[rx] + siz[ry];
            if (rank[rx] == rank[ry])
                rank[rx]++;
        }
    }
    //要素xが属する木と要素yが属する木が同じならtrueを返す
    bool same(long long x, long long y)
    {
        return root(x) == root(y);
    }
    //要素xが属する木の頂点数を返す
    long long size(long long x)
    {
        return siz[root(x)];
    }
};
//union-find木による森がいくつの木からなるかを返す
long long partial(union_find tree)
{
    long long n = tree.siz.size();
    vector<bool> seen(n, false);
    long long ans = 0;
    for (long long i = 0; i < n; i++)
    {
        if (seen[tree.root(i)])
            continue;
        seen[tree.root(i)] = true;
        ans++;
    }
    return ans;
}
int main()
{
    cout << fixed << setprecision(30);
    ll N, K;
    cin >> N >> K;
    vector<ll> P(N);
    loop(i, N) cin >> P[i];
    union_find unitree(N - K + 1);
    //まず、昇順になっている部分を抽出する
    ll now = -1, count = 0, connect = -1;
    loop(i, N)
    {
        if (now < P[i])
            count++;
        else
            count = 1;
        now = P[i];
        if (count >= K)
        {
            if (connect != -1)
                unitree.unite(i - (K - 1), connect);
            connect = i - (K - 1);
        }
    }

    Segment_Tree_Beats tree(N, P);
    loop(i, N - K)
    {
        ll M = tree.query_max(1 + i, K - 1 + i);
        ll m = tree.query_min(1 + i, K - 1 + i);
        ll L = P[i], R = P[K + i];
        if (L < m && M < R)
        {
            unitree.unite(i, i + 1);
        }
    }
    ll ans = partial(unitree);
    putout(ans);
    return 0;
}


Measured memory_bytes: 76668