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;
    }
}