#include "omp.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <random>
#include <bitset>
#include <unordered_set>
#include <cassert>
#include <list>


using namespace std;

typedef long long ll;
typedef long double ld;


const int sze = 1 << 11, INF = 1e9 + 10;


signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n, k, q, mx = 0;
	cin >> n >> k >> q;

	vector<int> challengers(n), values(n);
	priority_queue<int, vector<int>> heap;


	for (int i = 0; i < n; ++i)
	{
		cin >> values[i];
		challengers[i] = values[i];
		mx = max(mx, values[i]);
	}

	int kick[sze];

	sort(challengers.begin(), challengers.end());
	challengers.erase(unique(challengers.begin(), challengers.end()), challengers.end());
	int ans = INF;

	for (int v : challengers)
	{
		int l = v - 1, r = mx + 1;

		while (r - l > 1)
		{
			priority_queue<pair<int, int>, vector<pair<int, int>>> tree;
			fill(kick, kick + n, 0);

			int m = (l + r) >> 1;
			int num = 0;

			int lb = 0, rb = 0, cnt = 0;
			while (lb < n)
			{
				while (rb < n && cnt != k)
				{
						tree.push(make_pair(-values[rb], rb));
						cnt++;
						rb++;

						while (tree.size() && kick[tree.top().second])
						{
							kick[tree.top().second] = 0;
							tree.pop();
						}
				}

				if (cnt != k)
					break;

				int vl = -tree.top().first;
				if (vl >= v && vl <= m)
				{
					num++;
					tree.pop();
				}
				else
				{
					kick[lb] = 1;
					lb++;
				}

				cnt--;
			}

			if (num >= q)
				r = m;
			else
				l = m;
		}

		if (r != mx + 1)
			ans = min(ans, r - v);
	}

	cout << ans;

	return 0;
}
