#pragma region Include
#include <bits/stdc++.h>
// #include <algorithm>
// #include <bitset>
// #include <climits>
// #include <cmath>
// #include <iostream>
// #include <iterator>
// #include <map>
// #include <queue>
// #include <sstream>
// #include <stack>
// #include <unordered_map>
// #include <unordered_set>
// #include <vector>
#pragma endregion

using namespace std;

#pragma region Macros
typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define dump(x) \
  cout << "Line " << __LINE__ << " : " << #x << " = " << (x) << endl
template <class T>
using VV = vector<vector<T>>;

template <typename T>
ostream& operator<<(ostream& os, vector<T>& vec) {
  os << "[";
  rep(i, vec.size()) os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  os << "]";
  return os;
}

template <typename T>
ostream& operator<<(ostream& os, vector<vector<T>>& mat) {
  os << "[";
  rep(i, mat.size()) os << mat[i] << (i + 1 == mat.size() ? "" : ",\n ");
  os << "]";
  return os;
}

template <typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  for (T& x : vec) is >> x;
  return is;
}

template <typename V, typename H>
void resize(vector<V>& vec, const H head) {
  vec.resize(head);
}

template <typename V, typename H, typename... T>
void resize(vector<V>& vec, const H& head, const T... tail) {
  vec.resize(head);
  for (auto& v : vec) resize(v, tail...);
}
constexpr double EPS = 1e-10;
const int INF = 0x3f3f3f3f;
#pragma endregion

class UnionFind {
 public:
  vector<int> par;
  vector<int> rank;
  int size;

  UnionFind(int N) : par(N), rank(N), size(N) {
    for (int i = 0; i < N; ++i) {
      par[i] = i;
      rank[i] = 0;
    }
  }

  int root(int x) {
    if (par[x] == x) return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) return;
    if (rank[rx] < rank[ry]) {
      par[rx] = ry;
    } else {
      par[ry] = rx;
      if (rank[rx] == rank[ry]) rank[rx]++;
    }
    --size;
    return;
  }

  bool same(int x, int y) { return root(x) == root(y); }

  int parent(int x) { return root(x); }

  int component() { return size; }
};

// 1-indexed
template <typename Monoid>
struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  // f: compare function, INI:initial value
  vector<Monoid> data;
  int n;
  F comp;
  const Monoid INI;
  SegmentTree(int x, const F f, const Monoid& M) : comp(f), INI(M) {
    n = 1;
    while (n < x) n <<= 1;
    data.assign(2 * n, INI);
  }
  // order=0: small, order=1: large
  SegmentTree(int x, bool order, const Monoid& M) : INI(M) {
    if (!order) {
      comp = [](Monoid a, Monoid b) { return min(a, b); };
    } else {
      comp = [](Monoid a, Monoid b) { return max(a, b); };
    }
    n = 1;
    while (n < x) n <<= 1;
    data.assign(2 * n, INI);
  }

  SegmentTree(vector<Monoid>& v, bool order, const Monoid& M) : INI(M) {
    if (!order) {
      comp = [](Monoid a, Monoid b) { return min(a, b); };
    } else {
      comp = [](Monoid a, Monoid b) { return max(a, b); };
    }
    int x = v.size();
    n = 1;
    while (n < x) n <<= 1;
    data.assign(2 * n, INI);
    for (int i = 0; i < x; ++i) set(i, v[i]);
    build();
  }

  void set(int i, Monoid& p) { data[i + n] = p; }

  void build() {
    for (int i = n - 1; i > 0; --i) {
      data[i] = comp(data[2 * i], data[2 * i + 1]);
    }
  }

  void update(int i, Monoid& p) {
    i += n;
    data[i] = p;
    while (i >>= 1) {
      data[i] = comp(data[2 * i], data[2 * i + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = INI, R = INI;
    for (a += n, b += n; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = comp(L, data[a++]);
      if (b & 1) R = comp(data[--b], R);
    }
    return comp(L, R);
  }

  Monoid operator[](const int& i) const { return data[i + n]; }
};

int main() {
  int N, K;
  cin >> N >> K;
  vi A(N);
  cin >> A;
  SegmentTree<int> small(A, 0, INF);
  SegmentTree<int> large(A, 1, -INF);

  // ruisekiwa
  vi sum(N, 0);
  rep(i, N - 1) sum[i + 1] = sum[i] + (A[i] < A[i + 1] ? 1 : 0);
  // dump(sum);

  UnionFind uf(N - K + 1);
  int index = -1;  // unchanged index

  rep(i, N - K + 1) {
    // dump(sum[i]);
    // dump(sum[i + K - 1]);
    // dump(sum[i + K - 1] - sum[i]);
    // dump(uf.par);

    if (sum[i + K - 1] - sum[i] == K - 1) {
      if (index != -1) {
        uf.unite(i, index);
      } else {
        index = i;
      }
    }
    int curmin = small.query(i + 1, i + K);
    int curmax = large.query(i + 1, i + K);
    if (i == N - K) continue;
    if (A[i] < curmin && curmax < A[i + K]) uf.unite(i, i + 1);
  }
  // dump(uf.component());
  // dump(uf.par);
  cout << uf.component() << endl;

  return 0;
}

Measured memory_bytes: 7424