#include <bits/stdc++.h>
using namespace std;
void divideByZero(const char *error) {
  printf(error);
  fclose(stdout);
  int a = 234;
  a = a / (a - a);
}
long parseLong() {
  long temp;
  scanf("%ld", &temp);
  return temp;
}
const long N = 101000;
long memoMinA[N][20], memoMaxA[N][20], a[N], memoArgMin[3 * N], dp[N];
long n;
void initMemoMinA() {
  for (long i = 0; i < n; i++) memoMinA[i][0] = a[i];
  for (long j = 0; (1 << j) <= n; j++)
    for (long i = 0; i + (1 << j) < n; i++)
      memoMinA[i][j + 1] = min(memoMinA[i][j], memoMinA[i + (1 << j)][j]);
}
long getMinA(long l, long r) {
  if (l >= r) divideByZero("empty inerval for min");
  long log = 0;
  for (; 1 << log <= (r - l); log++)
    ;
  log--;
  return min(memoMinA[l][log], memoMinA[r - (1 << log)][log]);
}
void initMemoMaxA() {
  for (long i = 0; i < n; i++) memoMaxA[i][0] = a[i];
  for (long j = 0; (1 << j) <= n; j++)
    for (long i = 0; i + (1 << j) < n; i++)
      memoMaxA[i][j + 1] = max(memoMaxA[i][j], memoMaxA[i + (1 << j)][j]);
}
long getMaxA(long l, long r) {
  if (l >= r) divideByZero("empty inerval for min");
  long log = 0;
  for (; 1 << log <= (r - l); log++)
    ;
  log--;
  return max(memoMaxA[l][log], memoMaxA[r - (1 << log)][log]);
}
void initSegmentTree(long node, long b, long e) {
  if (b == e) {
    memoArgMin[node] = b;
    return;
  }
  initSegmentTree(node * 2, b, (b + e) / 2);
  initSegmentTree(1 + node * 2, 1 + (b + e) / 2, e);
  memoArgMin[node] = dp[memoArgMin[node * 2]] < dp[memoArgMin[1 + node * 2]]
                         ? memoArgMin[node * 2]
                         : memoArgMin[1 + node * 2];
}
long getArgMin(long node, long b, long e, long i, long j) {
  if (e < i || b > j) return -1;
  if (i <= b && e <= j) return memoArgMin[node];
  long ansL = getArgMin(2 * node, b, (b + e) / 2, i, j),
       ansR = getArgMin(1 + 2 * node, 1 + (b + e) / 2, e, i, j);
  if (ansL == -1) return ansR;
  if (ansR == -1) return ansL;
  return dp[ansL] < dp[ansR] ? ansL : ansR;
}
void updateTree(long node, long b, long e, long ind, long val) {
  if (b == e) {
    if (b != ind) divideByZero("update tree ended up in a strange place");
    dp[ind] = val;
    memoArgMin[node] = ind;
    return;
  }
  if (ind <= (b + e) / 2)
    updateTree(2 * node, b, (b + e) / 2, ind, val);
  else
    updateTree(1 + 2 * node, 1 + (b + e) / 2, e, ind, val);
  memoArgMin[node] = dp[memoArgMin[node * 2]] < dp[memoArgMin[1 + node * 2]]
                         ? memoArgMin[node * 2]
                         : memoArgMin[1 + node * 2];
}
long bSearch(long i, long s) {
  long good = i, bad = 0;
  if (getMaxA(bad, i) - getMinA(bad, i) <= s) return bad;
  while (good - bad > 1) {
    long m = (good + bad) / 2;
    if (getMaxA(m, i) - getMinA(m, i) <= s)
      good = m;
    else
      bad = m;
  }
  return good;
}
int main() {
  long s, l;
  scanf("%ld %ld %ld", &n, &s, &l);
  for (long i = 0; i < n; i++) scanf("%ld", &a[i]);
  initMemoMinA();
  initMemoMaxA();
  long inf = 999999;
  for (long i = 0; i <= n; i++) updateTree(1, 0, n, i, inf);
  dp[0] = 0;
  updateTree(1, 0, n, 0, dp[0]);
  for (long i = 1; i <= n; i++) {
    long j = bSearch(i, s);
    if (j == -1 || j > i - l) continue;
    dp[i] = 1 + dp[getArgMin(1, 0, n, j, i - l)];
    updateTree(1, 0, n, i, dp[i]);
  }
  printf("%ld", dp[n] < inf ? dp[n] : -1);
  return 0;
}
