#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
#define REP(i, n) for (int i = 0; (i64)(i) < (i64)(n); ++i)

#ifdef ENABLE_DEBUG
template <typename T>
void debug(T value) {
  cerr << value;
}
template <typename T, typename... Ts>
void debug(T value, Ts... args) {
  cerr << value << ", ";
  debug(args...);
}
#define DEBUG(...)                              \
  do {                                          \
    cerr << " \033[33m (L" << __LINE__ << ") "; \
    cerr << #__VA_ARGS__ << ":\033[0m ";        \
    debug(__VA_ARGS__);                         \
    cerr << endl;                               \
  } while (0)
#else
#define debug(...)
#define DEBUG(...)
#endif

template <class Monoid>
struct SegTree {
  using Func = function<Monoid(Monoid, Monoid)>;
  const Func F;
  const Monoid UNITY;
  int size;
  vector<Monoid> dat;

  SegTree(int n, const Func f, const Monoid &unity)
      : F(f), UNITY(unity), size(n), dat(2 * n, unity) {}

  // Sets i-th value (0-indexed) to x for initial setup.
  // build() must be called after set() calls.
  void set(int i, const Monoid &x) { dat[size + i] = x; }
  void build() {
    for (int k = size - 1; k > 0; --k) {
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
    }
  }

  // Sets i-th value (0-indexed) to x.
  void update(int i, const Monoid &x) {
    int k = size + i;
    dat[k] = x;
    while (k > 1) {
      k >>= 1;
      dat[k] = F(dat[k * 2], dat[k * 2 + 1]);
    }
  }

  // Queries by [l,r) range (0-indexed, open interval).
  Monoid fold(int l, int r) {
    l += size;
    r += size;
    Monoid vleft = UNITY, vright = UNITY;
    for (; l < r; l >>= 1, r >>= 1) {
      if (l & 1) vleft = F(vleft, dat[l++]);
      if (r & 1) vright = F(dat[--r], vright);
    }
    return F(vleft, vright);
  }

  // Queries by a single index (0-indexed).
  Monoid operator[](int i) { return dat[size + i]; }

  /* debug */
  void print() {
    for (int i = 0; i < size; ++i) {
      cout << (*this)[i];
      if (i != size - 1) cout << ",";
    }
    cout << endl;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  const i64 INF = 200001;
  i64 N, K;
  cin >> N >> K;
  vector<i64> P(N);
  for (auto &x : P) cin >> x;
  SegTree<i64> mins(
      N, [](i64 x, i64 y) { return min(x, y); }, INF);
  SegTree<i64> maxs(
      N, [](i64 x, i64 y) { return max(x, y); }, -1);
  REP(i, N) {
    mins.set(i, P[i]);
    maxs.set(i, P[i]);
  }
  mins.build();
  maxs.build();

  vector<int> lsorted(N), rsorted(N);
  for (int i = 0; i < N; ++i) {
    lsorted[i] = 1;
    if (i > 0 && P[i - 1] <= P[i]) {
      lsorted[i] = lsorted[i - 1] + 1;
    }
    int j = N - 1 - i;
    rsorted[j] = 1;
    if (i > 0 && P[j] <= P[j + 1]) {
      rsorted[j] = rsorted[j + 1] + 1;
    }
  }

  set<tuple<int, int>> sorted_ranges;
  bool nochange = false;
  for (int l = 0; l <= N - K; ++l) {
    int r = l + K;  // exclusive
    assert(r <= N);
    if (r - lsorted[r - 1] <= l) {
      DEBUG(nochange, l, r);
      nochange = true;
      continue;
    }
    i64 mine = mins.fold(l, r);
    i64 maxe = maxs.fold(l, r);
    int al = l;
    if (l - 1 >= 0 && P[l - 1] < mine) {
      al = l - lsorted[l - 1];
    }
    int ar = r;
    if (r < N && P[r] > maxe) {
      ar = r + rsorted[r];
    }
    sorted_ranges.emplace(al, ar);
  }
  int ans = sorted_ranges.size() + int(nochange);
  cout << ans << endl;
  /*
    for (auto [l, r] : sorted_ranges) {
      cerr << "- [" << l << " " << r << "] ------" << endl;
      REP(i, l) { cerr << P[i] << ' '; }
      cerr << "| ";
      vector<i64> tmp;
      tmp.reserve(r - l + 1);
      for (int i = l; i <= r; ++i) {
        tmp.push_back(P[i]);
      }
      sort(tmp.begin(), tmp.end());
      for (auto p : tmp) {
        cerr << p << ' ';
      }
      cerr << "|";
      for (int i = r + 1; i < N; ++i) {
        cerr << " " << P[i];
      }
      cerr << endl;
    }
    */
}


Measured memory_bytes: 21896