#include <iostream>
#include <vector>
#include <algorithm>
 
int allocArray[1'660'965 + 100'000];
int allocIndex = 0;
int* NewInt(int size) noexcept {
    int* ret = allocArray + allocIndex;
    allocIndex += size;
    return ret;
}
 
struct Range {
    int start, end;
    bool Include(Range outer) const noexcept { return outer.start <= start && end <= outer.end; }
    bool Exclude(Range outer) const noexcept { return outer.end < start || end < outer.start; }
    bool IsLeaf() const noexcept { return start == end; }
    int Count() const noexcept { return 1 + end - start; }
};
class Node {
public:
    inline static int* InitArray;
 
public:
    explicit Node(Range r) noexcept : range(r) {
        if (range.IsLeaf()) {
            (array = NewInt(n = 1))[0] = InitArray[range.start];
            return;
        }
 
        int mid = range.start + (range.end - range.start) / 2;
        left = new Node({ range.start, mid });
        right = new Node({ mid + 1, range.end });
 
        array = NewInt(n = range.Count());
        std::merge(left->array, left->array + left->n, right->array, right->array + right->n, array);
    }
    ~Node() {
        delete left;
        delete right;
    }
    int LessCount(Range query, int value) const noexcept {
        if (range.Exclude(query)) { return 0; }
        if (range.Include(query)) {
            return static_cast<int>(std::lower_bound(array, array + n, value) - array);
        }
 
        return left->LessCount(query, value) + right->LessCount(query, value);
    }
    int GetMinimum() const noexcept { return array[0]; }
    int GetMaximum() const noexcept { return array[n-1]; }
private:
    Range range;
    Node* left = nullptr, * right = nullptr;
    int* array;
    int n;
};
 
int main() noexcept {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, q;
    std::cin >> n >> q;
 
    Node::InitArray = NewInt(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> Node::InitArray[i];
    }
 
    Node* const root = new Node({ 0, n - 1 });
 
    const int minValue = root->GetMinimum();
    const int maxValue = root->GetMaximum();
 
    for (int i = 0; i < q; ++i) {
        int l, r, k;
        std::cin >> l >> r >> k;
        const Range query{ l - 1, r - 1 };
 
        int low = minValue;
        for (int high = maxValue, mid; low < high; ) {
            mid = low + (high - low) / 2;
            if (root->LessCount(query, mid + 1) < k) {
                low = mid + 1;
            }
            else {
                high = mid;
            }
        }
        std::cout << low << '\n';
    }
 
    return 0;
}