#include <bits/stdc++.h>


using namespace std;
#define rep(i,n) for (int i = 0; i < (int)(n); ++i)
#define reps(i,n) for (int i = 1; i <= (int)(n); ++i)
#define repd(i,n) for (int i = (int)(n - 1); i >= 0; --i)
#define repds(i,n) for (int i = (int)(n); i > 0; --i)
#define loop(i,x,n) for (int i = (int)(x); i < (n); ++i)
#define loops(i,x,n) for (int i = (int)(x); i <= (n); ++i)
#define loopd(i,x,n) for (int i = (int)(x); i > (n); --i)
#define loopds(i,x,n) for (int i = (int)(x); i >= (n); --i)
#define itrep(i,s) for (auto i = begin(s); i != end(s); ++i)
#define itrepd(i,s) for (auto i = --end(s); i != begin(s); --i)
#define all(f,x,...) [&](decltype(x)& whole) { return (f)(begin(whole), end(whole), ##__VA_ARGS__); }(x)
#define rall(f,x,...) [&](decltype(x)& whole) { return (f)(rbegin(whole), rend(whole), ##__VA_ARGS__); }(x)
using ll = long long;
using ld = long double;
constexpr ll inf = static_cast<ll>(1e17);
constexpr int iinf = static_cast<int>(1e9);
constexpr double dinf = 1e10;
constexpr ld ldinf = 1e17;
ll mod = static_cast<ll>(1e9 + 7);
std::ostream& endn(std::ostream& os) { return os.put(os.widen('\n')); }
template<class T> constexpr int sz(const T& a) { return (int)a.size(); }
template<class T, class ... Args> constexpr void mins(T& a, Args... args) { a = min<T>({ a, args... }); }
template<class T, class... Args> constexpr void maxs(T& a, Args... args) { a = max<T>({ a,args... }); }
template<typename A, size_t N, typename T> constexpr void fillArray(A(&array)[N], const T& val) { std::fill((T*)array, (T*)(array + N), val); }

class UnionFind {
public:
    UnionFind() :data(0) {}
    UnionFind(int size) : data(size, -1) { }
    void resize(int size) { *this = { size }; }
    bool unionset(int x, int y) {
        x = root(x); y = root(y);
        if (x != y) {
            if (data[y] < data[x]) std::swap(x, y);
            data[x] += data[y]; data[y] = x;
        }
        return x != y;
    }
    bool findset(int x, int y) { return root(x) == root(y); }
    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
    int size(int x) { return -data[root(x)]; }

private:
    std::vector<int> data;
};

int n, k;
int p[200005];
UnionFind uf;
void solve() {
    cin >> n >> k;
    rep(i, n) cin >> p[i];
    uf.resize(n - k + 1);

    int r = 0;
    int z = -1;
    deque<int> minque, maxque;
    rep(l, n - k + 1) {
        while (r - l < k) {
            while (!minque.empty() && p[r] < minque.back()) minque.pop_back();
            minque.push_back(p[r]);
            while (!maxque.empty() && p[r] > maxque.back()) maxque.pop_back();
            maxque.push_back(p[r]);
            ++r;
        }

        if (maxque.size() == 1 && minque.size() == k) {
            if (z < 0)z = l;
            else uf.unionset(l, z);
        }
        if (minque.front() == p[l] && max(maxque.front(), p[r]) == p[r] && l + 1 < n - k + 1) uf.unionset(l, l + 1);

        if (minque.front() == p[l]) minque.pop_front();
        if (maxque.front() == p[l]) maxque.pop_front();
    }

    vector<bool> flag(n - k + 1, false);
    rep(i, n - k + 1) flag[uf.root(i)] = true;

    int ans = 0;
    rep(i, n - k + 1) if (flag[i]) ++ans;

    cout << ans << endn;

}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);

    solve();

    cout << flush;

    return 0;
}


Measured memory_bytes: 1920