using System.Buffers;
using System.Runtime.CompilerServices;
using static IO;
public sealed class IO {
public static IO Cin = new();
static readonly StreamReader reader = new(Console.OpenStandardInput());
public static readonly StreamWriter writer = new(Console.OpenStandardOutput());
public static implicit operator int(IO _)
{
int c;
while ((c=reader.Peek()) != -1 && c < '0' && c != '-') reader.Read();
int ret = 0;
bool negative = false;
if ((c = reader.Read()) == '-') negative = true;
else ret = c - '0';
while ('0' <= (c = reader.Read()) && c <= '9') ret = ret * 10 + (c - '0');
return negative ? -ret : ret;
}
public static readonly ArrayPool<int> IntArrayPool = ArrayPool<int>.Create(2_000_000, 300_000);
}
sealed class Program {
static void Main() {
int n = Cin, q = Cin;
Node.InitArray = IntArrayPool.Rent(n);
for (int i = 0; i < n; i++) Node.InitArray[i] = Cin;
Node root = new(new(0, n - 1));
int min = root.Minimum, max = root.Maximum;
for(int i=0;i < q;i++) {
Range range = new(Cin - 1, Cin - 1);
int kth = Cin;
int low = min;
for(int high = max, mid; low < high; ) {
mid = (low + high) / 2;
if (root.LessCount(range, mid + 1) < kth) low = mid + 1;
else high = mid;
}
writer.WriteLine(low);
}
writer.Flush();
}
}
public readonly record struct Range(int Start, int End)
{
public readonly bool Include(in Range outer) => outer.Start <= Start && End <= outer.End;
public readonly bool Exclude(in Range outer) => outer.End < Start || End < outer.Start;
public readonly bool IsLeaf => Start == End;
public readonly int Count => 1 + End - Start;
}
sealed class Node {
public static int[] InitArray = null!;
readonly Range range;
readonly Node? left = null, right = null;
readonly int[] array;
readonly int n;
public Node(Range range) {
if ((this.range = range).IsLeaf) {
array = IntArrayPool.Rent(n = 1);
array[0] = InitArray[range.Start];
return;
}
int mid = (range.Start + range.End) / 2;
left = new(range with { End = mid });
right = new(range with { Start = mid + 1 });
array = IntArrayPool.Rent(n = range.Count);
int l = 0, r = 0;
for (int i = 0; i < n; i++) {
if ((l < left.n ? left.array[l] : int.MaxValue) < (r < right.n ? right.array[r] : int.MaxValue)) {
array[i] = left.array[l++];
} else {
array[i] = right.array[r++];
}
}
}
public int LessCount(Range query, int value) {
if (range.Exclude(query)) return 0;
if (range.Include(query)) {
if (range.IsLeaf) return array[0] < value ? 1 : 0;
return LowerBound(value);
}
return left!.LessCount(query, value) + right!.LessCount(query, value);
}
public int Minimum => array[0];
public int Maximum => array[n-1];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int LowerBound(int value) {
int low = 0;
for (int high = n; low < high; ) {
int mid = (low + high) / 2;
if (array[mid] < value) low = mid + 1;
else high = mid;
}
return low;
}
}