import std.stdio, std.algorithm, std.range, std.conv, std.string, std.math, std.container, std.typecons;
import core.stdc.stdio;
// foreach, foreach_reverse, writeln

alias P = Tuple!(int,int);

int k;
class UnionFind {
	int score;
	int[] data, cnt;
	this(int n) {
		data = new int[n];
		cnt = new int[n];
		data[] = -1;
		score = 0;
	}
	int find(int v) {
		if (data[v] < 0) return v;
		return data[v] = find(data[v]);
	}
	int calc(int v) {
		v = find(v);
		int size = -data[v];
		return min(max(0,size-k+1), cnt[v]);
	}
	void add(int v, int x) {
		score -= calc(v);
		cnt[find(v)] += x;
		score += calc(v);
	}
	bool join(int u, int v) {
		u = find(u);
		v = find(v);
		if (u == v) return false;
		if (data[u] > data[v]) swap(u,v);
		score -= calc(u);
		score -= calc(v);
		data[u] += data[v];
		cnt[u] += cnt[v];
		data[v] = u;
		score += calc(u);
		return true;
	}
}

void main() {
	int n, q;
	scanf("%d%d%d", &n, &k, &q);
	int[] a = new int[n];
	foreach (i; 0..n) scanf("%d", &a[i]);
	int l = -1, r = 1_000_000_000;
	bool judge(int x) {
		UnionFind uf = new UnionFind(n);
		P[] events;
		foreach (i; 0..n) {
			events ~= P(a[i],i);
			events ~= P(a[i]-x,n+i);
		}
		events.sort.reverse;
		bool[] added = new bool[n];
		foreach (event; events) {
			int i = event[1];
			if (i >= n) {
				i -= n;
				uf.add(i,-1);
				//writeln("del ",i," ",uf.score);
			} else {
				uf.add(i,1);
				if (i && added[i-1]) uf.join(i-1,i);
				if (i+1 < n && added[i+1]) uf.join(i+1,i);
				added[i] = true;
				//writeln("add ",i," ",uf.score);
				if (uf.score >= q) return true;
			}
		}
		return false;
	}
	while (l+1 < r) {
		int mid = (l+r)/2;
		if (judge(mid)) r = mid; else l = mid;
	}
	writeln(r);
}