#include <bits/stdc++.h>
template <typename T, class Container = std::vector<T>,
          class Compare = std::less<typename Container::value_type>>
class IntervalHeap {
 public:
  using container_type = Container;
  using value_compare = Compare;
  using value_type = typename container_type::value_type;
  using reference = typename container_type::reference;
  using const_reference = typename container_type::const_reference;
  using size_type = typename container_type::size_type;

 protected:
  container_type c;
  value_compare comp;

 private:
  static constexpr size_type z = ~static_cast<size_type>(1);
  bool normalize(const size_type x, const size_type y) {
    if (!comp(c[y], c[x])) return false;
    std::swap(c[x], c[y]);
    return true;
  }
  void build() {
    const size_type s = size() + 1;
    if (s & 1) {
      normalize(s & z, s);
      buildmin(s >> 1);
      buildmax(s >> 1);
      return;
    }
    if (s == 2) return;
    if (normalize(s, s >> 1 | 1)) buildmax(s >> 2);
    buildmin(s >> 1);
  }
  void buildmin(size_type i) {
    while (i > 1 && normalize(i & z, i << 1)) i >>= 1;
  }
  void buildmax(size_type i) {
    while (i > 1 && normalize(i << 1 | 1, i | 1)) i >>= 1;
  }

 public:
  explicit IntervalHeap(const value_compare &x = value_compare())
      : c(2), comp(x) {}
  bool empty() const { return c.size() == 2; }
  size_type size() const { return c.size() - 2; }
  const_reference min() const {
    assert(!empty());
    return c[2];
  }
  const_reference max() const {
    assert(!empty());
    return size() == 1 ? c[2] : c[3];
  }
  void push(const value_type &x) {
    c.push_back(x);
    build();
  }
  void push(value_type &&x) {
    c.push_back(std::move(x));
    build();
  }
  template <class... Args>
  void emplace(Args &&...args) {
    c.emplace_back(std::forward<Args>(args)...);
    build();
  }
  void pop_min() {
    assert(!empty());
    const size_type s = size() + 1;
    std::swap(c[2], c[s]);
    c.pop_back();
    size_type i = 4;
    while (i < s) {
      if ((i | 2) < s && !comp(c[i], c[i | 2])) i |= 2;
      if (!normalize(i >> 1 & z, i)) return;
      if ((i | 1) < s) normalize(i, i | 1);
      i <<= 1;
    }
  }
  void pop_max() {
    assert(!empty());
    const size_type s = size() + 1;
    if (s == 2) return pop_min();
    std::swap(c[3], c[s]);
    c.pop_back();
    size_type i = 5;
    while (i < s) {
      if ((i | 2) < s && !comp(c[i | 2], c[i])) i |= 2;
      if (!normalize(i, i >> 1 | 1)) return;
      normalize(i & z, i);
      i = (i & z) << 1 | 1;
    }
  }
};
template <typename T, class Compare = std::greater<T>>
class PairingHeap {
  static constexpr std::uint_fast64_t ALLOCSIZE = (std::uint_fast64_t)1 << 10;

 public:
  using value_type = T;
  using reference = value_type &;
  using const_reference = const value_type &;
  using size_type = std::uint_fast32_t;

 private:
  struct node_t {
    value_type data;
    node_t *left, *right;
  };
  node_t *root;
  size_type size_;
  static node_t *merge(node_t *x, node_t *y) {
    static const Compare comp = Compare();
    if (comp(y->data, x->data)) std::swap(x, y);
    x->right = y->left;
    y->left = x;
    return y;
  }

 public:
  PairingHeap() : root(nullptr), size_(0) {}
  const_reference top() const {
    assert(root);
    return root->data;
  }
  const_reference pop() {
    assert(root);
    --size_;
    const_reference ret = root->data;
    node_t *n = nullptr, *x = root->left, *y;
    while (x) {
      y = x;
      if (x->right) {
        x = x->right->right;
        y = merge(y, y->right);
      } else
        x = nullptr;
      y->right = n;
      n = y;
    }
    if (!n) {
      root = nullptr;
      return ret;
    }
    root = n;
    n = n->right;
    while (n) {
      x = n;
      n = n->right;
      root = merge(root, x);
    }
    return ret;
  }
  void push(const_reference data) {
    static node_t *pool = nullptr;
    static std::uint_fast64_t it = ALLOCSIZE;
    if (it == ALLOCSIZE) {
      pool = (node_t *)malloc(ALLOCSIZE * sizeof(node_t));
      it = 0;
    }
    node_t *top = &pool[it++];
    top->data = data;
    top->left = nullptr;
    root = root ? merge(root, top) : top;
    ++size_;
  }
  bool empty() const { return !root; }
  size_type size() const { return size_; }
  void meld(PairingHeap<T, Compare> &other) {
    size_ += other.size_;
    other.size_ = 0;
    if (other.root) {
      root = root ? merge(root, other.root) : other.root;
      other.root = nullptr;
    }
  }
};
class UnionFind {
 public:
  using size_type = std::size_t;
  using container_type = std::vector<size_type>;

 protected:
  container_type p, s;

 public:
  UnionFind() : p(), s() {}
  explicit UnionFind(const size_type size)
      : p(size), s(size, static_cast<size_type>(1)) {
    std::iota(p.begin(), p.end(), static_cast<size_type>(0));
  }
  size_type size() const { return p.size(); }
  bool empty() const { return p.empty(); }
  size_type find(size_type x) {
    assert(x < size());
    while (p[x] != x) x = p[x] = p[p[x]];
    return x;
  }
  bool same(const size_type x, const size_type y) {
    assert(x < size());
    assert(y < size());
    return find(x) == find(y);
  }
  size_type size(const size_type x) {
    assert(x < size());
    return s[find(x)];
  }
  bool unite(size_type x, size_type y) {
    assert(x < size());
    assert(y < size());
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (s[x] < s[y]) std::swap(x, y);
    s[x] += s[y];
    p[y] = x;
    return true;
  }
};
int main() {
  using uint = std::size_t;
  uint n, k, q;
  std::cin >> n >> k >> q;
  std::vector<uint> a(n), b(n);
  for (auto &&e : a) std::cin >> e;
  std::iota(b.begin(), b.end(), 0);
  std::sort(b.begin(), b.end(), [&a](uint x, uint y) { return a[x] > a[y]; });
  IntervalHeap<uint> H;
  std::vector<PairingHeap<uint>> P(n);
  UnionFind U(n);
  for (uint i = 0; i < n; ++i) P[i].push(a[i]);
  std::array<int, 2> dx = {-1, 1};
  std::vector<char> use(n, 0);
  uint ans = std::numeric_limits<uint>::max();
  for (const auto i : b) {
    use[i] = 1;
    for (const auto d : dx) {
      if (i + d < n && use[i + d]) {
        uint x = U.find(i + d);
        uint y = U.find(i);
        U.unite(x, y);
        if (U.find(x) != x) std::swap(x, y);
        P[x].meld(P[y]);
        while (P[x].size() >= k) H.emplace(P[x].pop());
      }
    }
    if (H.size() >= q) {
      while (H.size() > q) H.pop_max();
      ans = std::min(ans, H.max() - H.min());
    }
  }
  std::cout << ans << std::endl;
  return 0;
}
