/*input
5 3
1 2 1 3 2
2 5 3
1 2 3
5 5 2
*/

#include <bits/stdc++.h>
#include <unistd.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define rep(i,j,n) for(i=j;i<n;i++)
#define repi(i,j,n) for(i=j;i>n;i--)
#define inf 1e18
#define M 1000000007
#define pie 3.141592653589793238
#define ll int
#define ld long double
#define vll vector<int>
#define vi vector<int>
#define pll pair<int,int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define vpll vector<pair<int,int> >
#define pb push_back
#define pf pop_front
#define F first
#define S second
#define endl '\n'
#define N 300010
#define UQ(x) (x).resize(distance((x).begin(),unique(x.begin(),x.end())))

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll power(ll a,ll m,ll mod){
	ll ans=1;
	while(m){
		if(m%2){
			ans*=a;
			ans%=(mod);
		}
		a=(a*a)%(mod);
		m>>=1;
	}
	return ans;
}

void init(ll* a,ll n,ll val){
	for(ll i=0;i<n;i++)
		a[i]=val;
}

ll n;

int a[N],sb[4*N],se[4*N];
ll top[4*N][5],c;
vll v;
vll e[N];
ll has[N];
vpll tmp;

int query(int l,int r,ll i){
    return upper_bound(e[i].begin(),e[i].end(),r)-lower_bound(e[i].begin(),e[i].end(),l);
}

void build(int node,int l,int r){
	ll i;
	tmp.clear();
	rep(i,l,r+1){
		if(has[a[i]])continue;
		tmp.pb({query(l,r,a[i]),a[i]});
		has[a[i]]=1;
	}
	sort(tmp.begin(),tmp.end());
	c=0;
	repi(i,tmp.size()-1,-1){
		if(c<5)top[node][c++]=tmp[i].S;
		has[tmp[i].S]=0;
	}
	if(l==r){
		return;
	}
	int mid=(l+r)/2;
	build(2*node,l,mid);
	build(2*node+1,mid+1,r);
}

void query1(int node,int l,int r,int l1,int r1){
	if(l1>r||r1<l)
		return ;
	if(l1>=l&&r1<=r){
		ll i;
		rep(i,0,5)if(top[node][i]!=-1)v.pb(top[node][i]);
		return ;
	}
	ll mid=(l1+r1)/2;
	query1(2*node,l,r,l1,mid);
	query1(2*node+1,l,r,mid+1,r1);
}

int main()
{
	ll T=1;
	scanf("%d%d",&n,&T);
	ll i,j,ans,k;
	ll l,r;
	rep(i,0,n)scanf("%d",&a[i]),e[a[i]].pb(i);
	memset(top,-1,sizeof(top));
	build(1,0,n-1);
	while(T--){
		scanf("%d%d%d",&l,&r,&k);
		--l,--r;
		v.clear();
		query1(1,l,r,0,n-1);
		sort(v.begin(),v.end());
		UQ(v);
		ans=-1;
		for(auto i : v){
			if(query(l,r,i)>(r-l+1)/k){
				ans=i;
				break;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


/*input
5 3
1 2 1 3 2
2 5 3
1 2 3
5 5 2
*/

#include <bits/stdc++.h>
#include <unistd.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define rep(i,j,n) for(i=j;i<n;i++)
#define repi(i,j,n) for(i=j;i>n;i--)
#define inf 1e18
#define M 1000000007
#define pie 3.141592653589793238
#define ll int
#define ld long double
#define vll vector<int>
#define vi vector<int>
#define pll pair<int,int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define vpll vector<pair<int,int> >
#define pb push_back
#define pf pop_front
#define F first
#define S second
#define endl '\n'
#define N 300010
#define UQ(x) (x).resize(distance((x).begin(),unique(x.begin(),x.end())))

using namespace std;
using namespace __gnu_pbds;

template<typename T>
using ordered_set=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll power(ll a,ll m,ll mod){
	ll ans=1;
	while(m){
		if(m%2){
			ans*=a;
			ans%=(mod);
		}
		a=(a*a)%(mod);
		m>>=1;
	}
	return ans;
}

void init(ll* a,ll n,ll val){
	for(ll i=0;i<n;i++)
		a[i]=val;
}

ll n;

int a[N],sb[4*N],se[4*N];
ll top[4*N][5],c;
vll v;
vll e[N];
bool has[N];
vpll tmp;

int query(int l,int r,ll i){
    return upper_bound(e[i].begin(),e[i].end(),r)-lower_bound(e[i].begin(),e[i].end(),l);
}

void build(int node,int l,int r){
	ll i;
	tmp.clear();
	rep(i,l,r+1){
		if(has[a[i]])continue;
		tmp.pb({query(l,r,a[i]),a[i]});
		has[a[i]]=1;
	}
	sort(tmp.begin(),tmp.end());
	c=0;
	repi(i,tmp.size()-1,-1){
		if(c<5)top[node][c++]=tmp[i].S;
		has[tmp[i].S]=0;
	}
	if(l<r){
		int mid=(l+r)>>1;
		build(2*node,l,mid);
		build(2*node+1,mid+1,r);
	}
}

void query1(int node,int l,int r,int l1,int r1){
	if(l1>r||r1<l)
		return ;
	if(l1>=l&&r1<=r){
		ll i;
		rep(i,0,5){if(top[node][i]==-1)break;v.pb(top[node][i]);}
		return ;
	}
	ll mid=(l1+r1)>>1;
	query1(2*node,l,r,l1,mid);
	query1(2*node+1,l,r,mid+1,r1);
}

int main()
{
	ll T=1;
	scanf("%d%d",&n,&T);
	ll i,j,ans,k;
	ll l,r;
	rep(i,0,n)scanf("%d",&a[i]),e[a[i]].pb(i);
	memset(top,-1,sizeof(top));
	build(1,0,n-1);
	while(T--){
		scanf("%d%d%d",&l,&r,&k);
		--l,--r;
		v.clear();
		query1(1,l,r,0,n-1);
		sort(v.begin(),v.end());
		UQ(v);
		ans=-1;
		for(auto i : v){
			if(query(l,r,i)>(r-l+1)/k){
				ans=i;
				break;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
//    if (!p) return 0;
//    if (x > v || x < u) return 0;
//    if (u == v) {
//        return p->val;
//    }
//    return get(x , p -> l , u , (u+v) >> 1) +
//    get(x , p -> r , ((u+v) >> 1) + 1, v);
    while (u!=v) {
        int g = (u+v)>>1;
        if (!p) return 0;
        if (x <= g) {
            p = p->l;
            v = g;
            if (!p) return 0;
        } else {
            p = p->r;
            u = g+1;
            if (!p) return 0;
        }
    }
    return p->val;
}
int a[maxn];
int rrr = 1;
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {

    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=10;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int rrr = 1;
int Rand(int n) {
    return (rrr * base + base) % n;
}
int main() {

    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }

    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=10;j++) {
            int x = l+ Rand( r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5+100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;
int get(int x,int val) {
    return upper_bound(vt[x].begin(),vt[x].end(),val) - vt[x].begin();
}
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {
    //freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i+1);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=30;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , r) - get(a[x-1] , l-1) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
//    if (!p) return 0;
//    if (x > v || x < u) return 0;
//    if (u == v) {
//        return p->val;
//    }
//    return get(x , p -> l , u , (u+v) >> 1) +
//    get(x , p -> r , ((u+v) >> 1) + 1, v);
    while (u!=v) {
        int g = (u+v)>>1;
        if (!p) return 0;
        if (x <= g) {
            p = p->l;
            v = g;
            if (!p) return 0;
        } else {
            p = p->r;
            u = g+1;
            if (!p) return 0;
        }
    }
    return p->val;
}
int a[maxn];
int rrr = 1;
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {

    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=5;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int main() {
   // freopen("a.inp" , "r", stdin);
    int n,q;
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=50;j++) {
            int x = l + rand() % (r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5+100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;
int get(int x,int val) {
    return upper_bound(vt[x].begin(),vt[x].end(),val) - vt[x].begin();
}
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {
   // freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i+1);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=50;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , r) - get(a[x-1] , l-1) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int main() {
    //freopen("a.inp" , "r", stdin);
    int n,q;
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=30;j++) {
            int x = l + rand() % (r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5+100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;
int get(int x,int val) {
    return upper_bound(vt[x].begin(),vt[x].end(),val) - vt[x].begin();
}
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {
    //freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i+1);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=10;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , r) - get(a[x-1] , l-1) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5+100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;
int get(int x,int val) {
    return upper_bound(vt[x].begin(),vt[x].end(),val) - vt[x].begin();
}
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {
//    freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i+1);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=45;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , r) - get(a[x-1] , l-1) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5 + 100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;

int get(int x, int val) {
    return upper_bound(vt[x].begin(), vt[x].end(), val) - vt[x].begin();
}

struct Node {
    Node * l, * r;
    int val;
    Node() {
        l = r = 0;
        val = 0;
    }
    Node(Node *l1, Node *r1, int val1) {
        l = l1;
        r = r1;
        val = val1;
    }
} *f[maxn];

Node *build(int l,int r) {
    if (l==r) {
        return new Node();
    }
    Node *left = build(l , (l+r)>>1);
    Node *right = build(((l+r) >> 1) + 1, r);
    return new Node(left,right,0);
}
Node *update(Node *p, int l, int r, int x) {
    if (!p) p = new Node();
    if (l > x || r < x) return p;
    if (l == r) {
        return new Node(p->l, p->r, p->val + 1);
    }
    Node *left = update(p->l , l , (l + r) >> 1, x);
    Node *right = update(p->r , ((l + r) >> 1) + 1, r, x);
    return new Node(left, right, left -> val + right->val);
}
int getKth(Node *p, Node *q, int l, int r, int x) {
    if (l==r) return l;
    int g = (l + r) >> 1;
    int sz = p -> l -> val - q -> l -> val;
    if (sz >= x) {
        return getKth(p->l, q->l, l , g , x);
    }
    else {
        return getKth(p -> r , q -> r , g + 1 , r , x - sz);
    }
}
int main() {
  //  freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n, q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    f[0] = build(1,n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i + 1);
        f[i + 1] = update(f[i] , 1, n , a[i]);
    }

    int l, r, k;
    for (int i = 0; i < q; i++) {
        bool ok = false;
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l + 1 ) / k + 1;
        for (int j = sl; j <= r - l + 1; j += sl) {
            int x = getKth(f[r], f[l - 1], 1, n, j);
            if (get(x , r) - get(x, l - 1) >= sl) {
                printf("%d\n", x);
                ok = true;
                break;
            }
        }
        if (!ok) puts("-1");
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
const int maxn = 3e5+100;
int a[maxn];
vector<int> vt[maxn];
int rrr = 1;
int get(int x,int val) {
    return upper_bound(vt[x].begin(),vt[x].end(),val) - vt[x].begin();
}
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {
 //   freopen("a.inp" , "r", stdin);
//    freopen("a.out", "w", stdout);
    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        vt[a[i]].push_back(i+1);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=45;j++) {
            int x = l + rand() % (r-l+1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , r) - get(a[x-1] , l-1) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int main() {
    //freopen("a.inp" , "r", stdin);
    int n,q;
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=20;j++) {
            int x = l + rand() % (r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
const int base = 1357;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int rrr = 1;
int Rand(int n) {
    rrr = (rrr * base + base) % n;
    return rrr;
}
int main() {

    int n,q;
    srand(time(0));
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }

    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=10;j++) {
            int x = l+ Rand( r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
struct Node {
    Node *l, *r;
    int val;
    Node() : l(0) , r(0), val(0) {}
    Node(Node *l, Node *r, int val): l(l), r(r), val(val) {}
};
const int maxn = 3e5+100;
Node *f[maxn];

Node* update(Node *p, int x, int l, int r) {
    if (!p) {
        p = new Node();
    }
    if (x < l || x > r) return p;
    if (l == r) {
        return new Node(p->l , p->r , p->val + 1);
    }
    Node *res = new Node();
    res->l = update(p->l, x, l, (l + r) >> 1);
    res->r = update(p->r, x, ((l + r) >> 1) + 1, r);
    res->val = (res->l->val) + (res->r->val);
    return res;
}

int get(int x, Node *p ,int u,int v) {
    if (!p) return 0;
    if (x > v || x < u) return 0;
    if (u == v) {
        return p->val;
    }
    return get(x , p -> l , u , (u+v) >> 1) +
    get(x , p -> r , ((u+v) >> 1) + 1, v);
}
int a[maxn];
int main() {

    int n,q;
    scanf("%d %d", &n , &q);
    for(int i=0;i<n;i++) {
        scanf("%d", &a[i]);
        f[i+1] = update(f[i] , a[i] , 1 , n);
    }
    int l,r,k;
    for(int i=0;i<q;i++) {
        int ans = 1e9;
        scanf("%d %d %d", &l, &r, &k);
        int sl = (r - l +1 ) / k + 1;
        for(int j=0;j<=10;j++) {
            int x = l + rand() % (r - l +1);
            // cout<<i<< " "<<x<<endl;
            // continue;
            if (get(a[x-1] , f[r],1,n) - get(a[x-1] , f[l-1] , 1, n) >= sl) {
                ans = min(ans , a[x-1]);
            }
        }
        if (ans == 1e9) puts("-1");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(1, l, mid, val);
    	return query(1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b){
    if(a.l/block !=b.l/block)   return a.l < b.l;
    if((a.l/block)&1)           return a.r < b.r;
    return a.r > b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = tree[pos<<1] + tree[pos<<1|1];
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
        if(l == r) {
            if(tree[pos] < val) return -1;
            return l;
        }
        int mid = (l+r)>>1;

        if(tree[pos] < val)
            return -1;
        int lft = -1;

        if(tree[pos<<1] >= val)
            lft = query(pos<<1, l, mid, val);
        if(lft != -1)
            return lft;

        if(tree[pos<<1|1] >= val)
            return query(pos<<1|1, mid+1, r, val);
        return -1;
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b){
    if(a.l/block !=b.l/block)   return a.l < b.l;
    if((a.l/block)&1)           return a.r < b.r;
    return a.r > b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAX                 110000
#define EPS                 1e-9
#define INF                 1e7
#define MOD                 1000000007
#define pb                  push_back
#define mp                  make_pair
#define fi                  first
#define se                  second
#define pi                  acos(-1)
#define sf                  scanf
#define pf                  printf
#define SIZE(a)             ((int)a.size())
#define All(S)              S.begin(), S.end()
#define Equal(a, b)         (abs(a-b) < EPS)
#define Greater(a, b)       (a >= (b+EPS))
#define GreaterEqual(a, b)  (a > (b-EPS))
#define fr(i, a, b)         for(register int i = (a); i < (int)(b); i++)
#define FastRead            ios_base::sync_with_stdio(false); cin.tie(NULL);
#define fileRead(S)         freopen(S, "r", stdin);
#define fileWrite(S)        freopen(S, "w", stdout);
#define Unique(X)           X.erase(unique(X.begin(), X.end()), X.end())
#define error(args...)      { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }

#define isOn(S, j)          (S & (1 << j))
#define setBit(S, j)        (S |= (1 << j))
#define clearBit(S, j)      (S &= ~(1 << j))
#define toggleBit(S, j)     (S ^= (1 << j))
#define lowBit(S)           (S & (-S))
#define setAll(S, n)        (S = (1 << n) - 1)

typedef unsigned long long ull;
typedef long long ll;
typedef map<int, int> mii;
typedef map<ll, ll>mll;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<long long>vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pair<int, int> > vii;
typedef vector<pair<ll, ll> >vll;

void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {                                                  // Debugger error(a, b, ....)
	cerr << *it << " = " << a << "\n";
	err(++it, args...);
}

//const int dx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};                                                      // Four side
//const int dxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};                     // Eight side
//----------------------------------------------------------------------------------------------------------

struct node {
    int val;
    node *lft, *rht;

    node(node *L = NULL, node *R = NULL, int v = 0) {
        lft = L;
        rht = R;
        val = v;
    }
};

node *presis[101000], *null = new node();

node *nCopy(node *x) {
    node *tmp = new node();
    if(x) {
        tmp->val = x->val;
        tmp->lft = x->lft;
        tmp->rht = x->rht;
    }
    return tmp;
}

// Single Position update
void insert(node *pos, ll l, ll r, ll idx) {
    if(l == r) {
        pos->val++;
        pos->lft = null;
        pos->rht = null;
        return;
    }

    ll mid = (l+r)>>1;

    if(idx <= mid) {
        pos->lft = nCopy(pos->lft);
        if(pos->rht == NULL)
            pos->rht = null;
        insert(pos->lft, l, mid, idx);
    }
    else {
        pos->rht = nCopy(pos->rht);
        if(pos->lft == NULL)
            pos->lft = null;
        insert(pos->rht, mid+1, r, idx);
    }

    pos->val++;
}

int query(node *RMax, node *LMax, int l, int r, int k) {                         // (LMax : past, RMax : updated)
    int Count = RMax->val - LMax->val;

    //printf("%d ---- %d :: %d [%d %d]\n", l, r, Count, RMax->val, LMax->val);

    // Search for the minimum val where Count is STRICTLY greater than k

    // Almost like binary search??

    if(Count <= k)
        return -1;

    if(l == r)
        return l;

    int mid = (l+r)>>1, ret = -1;

    if(RMax->lft && LMax->lft)                          // if we can go lft and it is valid
        ret = query(RMax->lft, LMax->lft, l, mid, k);

    if(ret == -1 && RMax->rht && LMax->rht)             // if we didnt find answer and we can go rhight and its also valid
        ret = query(RMax->rht, LMax->rht, mid+1, r, k);

    return ret;
}

// Create NULL node

int main() {
    int n, q, l, r, k, val, lim = 300000, pos;

    //lim = 3; //////////////////

    scanf("%d%d", &n, &q);
    null->lft = null->rht = null;
    presis[0] = new node();

    for(int i = 1; i <= n; ++i) {
        scanf("%d", &val);
        presis[i] = nCopy(presis[i-1]);
        insert(presis[i], 1, lim, val);
    }

    //cout << "DONE\n";

    while(q--) {
        scanf("%d%d%d", &l, &r, &k);

        if(l == 1)
            pos = query(presis[r], null, 1, lim, (r-l+1)/k);
        else
            pos = query(presis[r], presis[l-1], 1, lim, (r-l+1)/k);
        printf("%d\n", pos);
    }

    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

inline void fastIn(int &num) {          // Fast IO, with space and new line ignoring
    bool neg = false;
    register int c;
    num = 0;
    c = getchar();
    for( ; c != '-' && (c < '0' || c > '9'); c = getchar());
    if (c == '-') {
        neg = true;
        c = getchar();
    }
    for(; (c>47 && c<58); c=getchar())
        num = (num<<1) + (num<<3) + c - 48;
    if(neg)
        num *= -1;
}

inline void fastOut (int n) {
    if(n < 0) {
    	putchar('-');
    	n = -n;
    }
    int N = n, rev, count = 0;
    rev = N;

    if (N == 0) { putchar('0'); return ;}
    while ((rev % 10) == 0) { count++; rev /= 10;}                  //obtain the count of the number of 0s
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}  //store reverse of N in rev
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (count--) putchar('0');
    putchar('\n');
}

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 500;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b) {
    if(a.l/block !=b.l/block)   return a.l < b.l;
    return a.r < b.r;
}

int main() {

    int n, m;
    fastIn(n), fastIn(m);

    for(int i = 0; i < n; ++i)
        fastIn(v[i]);

    for(int i = 0; i < m; ++i) {
        fastIn(q[i].l), fastIn(q[i].r), fastIn(q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        fastOut(ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

inline void fastIn(int &num) {          // Fast IO, with space and new line ignoring
    bool neg = false;
    register int c;
    num = 0;
    c = getchar();
    for( ; c != '-' && (c < '0' || c > '9'); c = getchar());
    if (c == '-') {
        neg = true;
        c = getchar();
    }
    for(; (c>47 && c<58); c=getchar())
        num = (num<<1) + (num<<3) + c - 48;
    if(neg)
        num *= -1;
}

inline void fastOut (long long n) {
    long long N = n, rev, count = 0;
    rev = N;
    if (N == 0) { putchar('0'); return ;}
    while ((rev % 10) == 0) { count++; rev /= 10;}                  //obtain the count of the number of 0s
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}  //store reverse of N in rev
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (count--) putchar('0');
    putchar('\n');
}

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
    int64_t ord;
	int64_t gilbertOrder(int x, int y, int pow, int rotate) {
		if (pow == 0)
			return 0;
		int hpow = 1 << (pow-1);
		int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2);
		seg = (seg + rotate) & 3;
		const int rotateDelta[4] = {3, 0, 0, 1};
		int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
		int nrot = (rotate + rotateDelta[seg]) & 3;
		int64_t subSquareSize = int64_t(1) << (2*pow - 2);
		int64_t ans = seg * subSquareSize;
		int64_t add = gilbertOrder(nx, ny, pow-1, nrot);
		ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
		return ans;
	}
    void calOrder() {
    	ord = gilbertOrder(l, r, 21, 0);
    }
} q[MAX];

SegTree ST;
//const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
	return a.ord < b.ord;
}

int main() {

    int n, m;
    fastIn(n), fastIn(m);

    for(int i = 0; i < n; ++i)
        fastIn(v[i]);

    for(int i = 0; i < m; ++i) {
        fastIn(q[i].l), fastIn(q[i].r), fastIn(q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
        q[i].calOrder();
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        fastOut(ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            //cerr << l << " :: " << tree[pos] << endl;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b){
    if(a.l/block !=b.l/block)   return a.l < b.l;
    if((a.l/block)&1)           return a.r < b.r;
    return a.r > b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

inline void fastIn(int &num) {          // Fast IO, with space and new line ignoring
    bool neg = false;
    register int c;
    num = 0;
    c = getchar_unlocked();
    for( ; c != '-' && (c < '0' || c > '9'); c = getchar_unlocked());
    if (c == '-') {
        neg = true;
        c = getchar_unlocked();
    }
    for(; (c>47 && c<58); c=getchar_unlocked())
        num = (num<<1) + (num<<3) + c - 48;
    if(neg)
        num *= -1;
}

inline void fastOut (long long n) {
    long long N = n, rev, count = 0;
    rev = N;
    if (N == 0) { putchar_unlocked('0'); return ;}
    while ((rev % 10) == 0) { count++; rev /= 10;}                  //obtain the count of the number of 0s
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}  //store reverse of N in rev
    while (rev != 0) { putchar_unlocked(rev % 10 + '0'); rev /= 10;}
    while (count--) putchar_unlocked('0');
    putchar_unlocked('\n');
}

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
    int64_t ord;
	int64_t gilbertOrder(int x, int y, int pow, int rotate) {
		if (pow == 0)
			return 0;
		int hpow = 1 << (pow-1);
		int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2);
		seg = (seg + rotate) & 3;
		const int rotateDelta[4] = {3, 0, 0, 1};
		int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
		int nrot = (rotate + rotateDelta[seg]) & 3;
		int64_t subSquareSize = int64_t(1) << (2*pow - 2);
		int64_t ans = seg * subSquareSize;
		int64_t add = gilbertOrder(nx, ny, pow-1, nrot);
		ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
		return ans;
	}
    void calOrder() {
    	ord = gilbertOrder(l, r, 21, 0);
    }
} q[MAX];

SegTree ST;
//const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
	return a.ord < b.ord;
}

int main() {

    int n, m;
    fastIn(n), fastIn(m);

    for(int i = 0; i < n; ++i)
        fastIn(v[i]);

    for(int i = 0; i < m; ++i) {
        fastIn(q[i].l), fastIn(q[i].r), fastIn(q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
        q[i].calOrder();
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        fastOut(ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            //cerr << l << " :: " << tree[pos] << endl;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

int64_t gilbertOrder(int x, int y, int pow, int rotate) {
	if (pow == 0)
		return 0;
	int hpow = 1 << (pow-1);
	int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2);
	seg = (seg + rotate) & 3;
	const int rotateDelta[4] = {3, 0, 0, 1};
	int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
	int nrot = (rotate + rotateDelta[seg]) & 3;
	int64_t subSquareSize = int64_t(1) << (2*pow - 2);
	int64_t ans = seg * subSquareSize;
	int64_t add = gilbertOrder(nx, ny, pow-1, nrot);
	ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
	return ans;
}

struct query {
    int l, r, k, id;
    int64_t ord;
    void calOrder() {
    	ord = gilbertOrder(l, r, 21, 0);
    }
} q[MAX];

SegTree ST;
//const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
	return a.ord < b.ord;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
        q[i].calOrder();
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = tree[pos<<1] + tree[pos<<1|1];
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
        if(l == r) {
            if(tree[pos] < val) return -1;
            return l;
        }
        int mid = (l+r)>>1;

        if(tree[pos] < val)
            return -1;
        int lft = -1;

        if(tree[pos<<1] >= val)
            lft = query(pos<<1, l, mid, val);
        if(lft != -1)
            return lft;

        if(tree[pos<<1|1] >= val)
            return query(pos<<1|1, mid+1, r, val);
        return -1;
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 580;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
    int b1 = a.l/block, b2 = b.l/block;
    if(b1 != b2)    return b1 < b2;
    if(b1&1)        return a.r > b.r;
    return a.r < b.r;
}

int main() {
    int n, m;
    cin >> n >> m;

    for(int i = 0; i < n; ++i)
        cin >> v[i];

    for(int i = 0; i < m; ++i) {
        cin >> q[i].l >> q[i].r >> q[i].k;
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(r < q[i].r)   ST.insert(v[++r]);
        while(r > q[i].r)   ST.erase(v[r--]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(l > q[i].l)   ST.insert(v[--l]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        cout << ans[i] << "\n";
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = tree[pos<<1] + tree[pos<<1|1];
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
        if(l == r) {
            if(tree[pos] < val) return -1;
            return l;
        }
        int mid = (l+r)>>1;

        if(tree[pos] < val)
            return -1;
        int lft = -1;

        if(tree[pos<<1] >= val)
            lft = query(pos<<1, l, mid, val);
        if(lft != -1)
            return lft;

        if(tree[pos<<1|1] >= val)
            return query(pos<<1|1, mid+1, r, val);
        return -1;
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 580;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b){
    if(a.l/block !=b.l/block)   return a.l < b.l;
    if((a.l/block)&1)           return a.r < b.r;
    return a.r > b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = tree[pos<<1] + tree[pos<<1|1];
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
        if(l == r) {
            if(tree[pos] < val) return -1;
            return l;
        }
        int mid = (l+r)>>1;

        if(tree[pos] < val)
            return -1;
        int lft = -1;

        if(tree[pos<<1] >= val)
            lft = query(pos<<1, l, mid, val);
        if(lft != -1)
            return lft;

        if(tree[pos<<1|1] >= val)
            return query(pos<<1|1, mid+1, r, val);
        return -1;
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 900;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a,query &b){
    if(a.l/block !=b.l/block)   return a.l < b.l;
    if((a.l/block)&1)           return a.r < b.r;
    return a.r > b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

inline void fastIn(int &num) {          // Fast IO, with space and new line ignoring
    bool neg = false;
    register int c;
    num = 0;
    c = getchar();
    for( ; c != '-' && (c < '0' || c > '9'); c = getchar());
    if (c == '-') {
        neg = true;
        c = getchar();
    }
    for(; (c>47 && c<58); c=getchar())
        num = (num<<1) + (num<<3) + c - 48;
    if(neg)
        num *= -1;
}

inline void fastOut (int n) {
    if(n < 0) {
    	putchar('-');
    	n = -n;
    }
    int N = n, rev, count = 0;
    rev = N;

    if (N == 0) { putchar('0'); return ;}
    while ((rev % 10) == 0) { count++; rev /= 10;}                  //obtain the count of the number of 0s
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}  //store reverse of N in rev
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (count--) putchar('0');
    putchar('\n');
}

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
//const int block = 700;
int v[MAX], cnt[MAX], ans[MAX], block;

bool cmp(query &a,query &b) {
    if(a.l/block !=b.l/block)   return a.l < b.l;
    return a.r < b.r;
}

int main() {

    int n, m;
    fastIn(n), fastIn(m);

    for(int i = 0; i < n; ++i)
        fastIn(v[i]);

    for(int i = 0; i < m; ++i) {
        fastIn(q[i].l), fastIn(q[i].r), fastIn(q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    block = sqrt(n);
    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        fastOut(ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

inline void fastIn(int &num) {          // Fast IO, with space and new line ignoring
    bool neg = false;
    register int c;
    num = 0;
    c = getchar();
    for( ; c != '-' && (c < '0' || c > '9'); c = getchar());
    if (c == '-') {
        neg = true;
        c = getchar();
    }
    for(; (c>47 && c<58); c=getchar())
        num = (num<<1) + (num<<3) + c - 48;
    if(neg)
        num *= -1;
}

inline void fastOut (int n) {
    if(n < 0) {
    	putchar('-');
    	n = -n;
    }
    int N = n, rev, count = 0;
    rev = N;

    if (N == 0) { putchar('0'); return ;}
    while ((rev % 10) == 0) { count++; rev /= 10;}                  //obtain the count of the number of 0s
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}  //store reverse of N in rev
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (count--) putchar('0');
    putchar('\n');
}

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
    int64_t ord;
	int64_t gilbertOrder(int x, int y, int pow, int rotate) {
		if (pow == 0)
			return 0;
		int hpow = 1 << (pow-1);
		int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2);
		seg = (seg + rotate) & 3;
		const int rotateDelta[4] = {3, 0, 0, 1};
		int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
		int nrot = (rotate + rotateDelta[seg]) & 3;
		int64_t subSquareSize = int64_t(1) << (2*pow - 2);
		int64_t ans = seg * subSquareSize;
		int64_t add = gilbertOrder(nx, ny, pow-1, nrot);
		ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
		return ans;
	}
    void calOrder() {
    	ord = gilbertOrder(l, r, 21, 0);
    }
} q[MAX];

SegTree ST;
//const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
	return a.ord < b.ord;
}

int main() {

    int n, m;
    fastIn(n), fastIn(m);

    for(int i = 0; i < n; ++i)
        fastIn(v[i]);

    for(int i = 0; i < m; ++i) {
        fastIn(q[i].l), fastIn(q[i].r), fastIn(q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
        q[i].calOrder();
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        fastOut(ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = tree[pos<<1] + tree[pos<<1|1];
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
        if(l == r) {
            if(tree[pos] < val) return -1;
            return l;
        }
        int mid = (l+r)>>1;

        if(tree[pos] < val)
            return -1;
        int lft = -1;

        if(tree[pos<<1] >= val)
            lft = query(pos<<1, l, mid, val);
        if(lft != -1)
            return lft;

        if(tree[pos<<1|1] >= val)
            return query(pos<<1|1, mid+1, r, val);
        return -1;
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

struct query {
    int l, r, k, id;
} q[MAX];

SegTree ST;
const int block = 580;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
    int b1 = a.l/block, b2 = b.l/block;
    if(b1 != b2)    return b1 < b2;
    if(b1&1)        return a.r > b.r;
    return a.r < b.r;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(r < q[i].r)   ST.insert(v[++r]);
        while(r > q[i].r)   ST.erase(v[r--]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(l > q[i].l)   ST.insert(v[--l]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAX                 110000
#define EPS                 1e-9
#define INF                 1e7
#define MOD                 1000000007
#define pb                  push_back
#define mp                  make_pair
#define fi                  first
#define se                  second
#define pi                  acos(-1)
#define sf                  scanf
#define pf                  printf
#define SIZE(a)             ((int)a.size())
#define All(S)              S.begin(), S.end()
#define Equal(a, b)         (abs(a-b) < EPS)
#define Greater(a, b)       (a >= (b+EPS))
#define GreaterEqual(a, b)  (a > (b-EPS))
#define fr(i, a, b)         for(register int i = (a); i < (int)(b); i++)
#define FastRead            ios_base::sync_with_stdio(false); cin.tie(NULL);
#define fileRead(S)         freopen(S, "r", stdin);
#define fileWrite(S)        freopen(S, "w", stdout);
#define Unique(X)           X.erase(unique(X.begin(), X.end()), X.end())
#define error(args...)      { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }

#define isOn(S, j)          (S & (1 << j))
#define setBit(S, j)        (S |= (1 << j))
#define clearBit(S, j)      (S &= ~(1 << j))
#define toggleBit(S, j)     (S ^= (1 << j))
#define lowBit(S)           (S & (-S))
#define setAll(S, n)        (S = (1 << n) - 1)

typedef unsigned long long ull;
typedef long long ll;
typedef map<int, int> mii;
typedef map<ll, ll>mll;
typedef map<string, int> msi;
typedef vector<int> vi;
typedef vector<long long>vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<pair<int, int> > vii;
typedef vector<pair<ll, ll> >vll;

void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {                                                  // Debugger error(a, b, ....)
	cerr << *it << " = " << a << "\n";
	err(++it, args...);
}

//const int dx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};                                                      // Four side
//const int dxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};                     // Eight side
//----------------------------------------------------------------------------------------------------------

struct node {
    int val;
    node *lft, *rht;

    node(node *L = NULL, node *R = NULL, int v = 0) {
        lft = L;
        rht = R;
        val = v;
    }
};

node *presis[301000], *null = new node();

node *nCopy(node *x) {
    node *tmp = new node();
    if(x) {
        tmp->val = x->val;
        tmp->lft = x->lft;
        tmp->rht = x->rht;
    }
    return tmp;
}

// Single Position update
void insert(node *pos, ll l, ll r, ll idx) {
    if(l == r) {
        pos->val++;
        pos->lft = null;
        pos->rht = null;
        return;
    }

    ll mid = (l+r)>>1;

    if(idx <= mid) {
        pos->lft = nCopy(pos->lft);
        if(pos->rht == NULL)
            pos->rht = null;
        insert(pos->lft, l, mid, idx);
    }
    else {
        pos->rht = nCopy(pos->rht);
        if(pos->lft == NULL)
            pos->lft = null;
        insert(pos->rht, mid+1, r, idx);
    }

    pos->val++;
}

int query(node *RMax, node *LMax, int l, int r, int k) {                         // (LMax : past, RMax : updated)
    int Count = RMax->val - LMax->val;

    //printf("%d ---- %d :: %d [%d %d]\n", l, r, Count, RMax->val, LMax->val);

    // Search for the minimum val where Count is STRICTLY greater than k

    // Almost like binary search??

    if(Count <= k)
        return -1;

    if(l == r)
        return l;

    int mid = (l+r)>>1, ret = -1;

    if(RMax->lft && LMax->lft)                          // if we can go lft and it is valid
        ret = query(RMax->lft, LMax->lft, l, mid, k);

    if(ret == -1 && RMax->rht && LMax->rht)             // if we didnt find answer and we can go rhight and its also valid
        ret = query(RMax->rht, LMax->rht, mid+1, r, k);

    return ret;
}

// Create NULL node

int main() {
    int n, q, l, r, k, val, lim = 300000, pos;

    //lim = 3; //////////////////

    scanf("%d%d", &n, &q);
    null->lft = null->rht = null;
    presis[0] = new node();

    for(int i = 1; i <= n; ++i) {
        scanf("%d", &val);
        presis[i] = nCopy(presis[i-1]);
        insert(presis[i], 1, lim, val);
    }

    //cout << "DONE\n";

    while(q--) {
        scanf("%d%d%d", &l, &r, &k);

        if(l == 1)
            pos = query(presis[r], null, 1, lim, (r-l+1)/k);
        else
            pos = query(presis[r], presis[l-1], 1, lim, (r-l+1)/k);
        printf("%d\n", pos);
    }

    return 0;
}


#include <bits/stdc++.h>
#define MAX 300010
using namespace std;

struct SegTree {
    int tree[3*MAX], n;
    void update(int pos, int l, int r, int idx, int val) {
        if(l == r) {
            tree[pos] += val;
            //cerr << l << " :: " << tree[pos] << endl;
            return;
        }
        int mid = (l+r)>>1;
        if(idx <= mid)
            update(pos<<1, l, mid, idx, val);
        else
            update(pos<<1|1, mid+1, r, idx, val);
        tree[pos] = max(tree[pos<<1], tree[pos<<1|1]);
    }
    int query(int pos, int l, int r, int val) {
        //cerr << pos << " [" << l << " -- " << r << "] " << tree[pos] << endl;
    	if(l == r) return l;
    	if(tree[pos] < val) return -1;
    	int mid = (l+r)>>1;
    	if(tree[pos<<1] >= val)
    		return query(pos<<1, l, mid, val);
    	return query(pos<<1|1, mid+1, r, val);
    }
    void insert(int val)    { update(1, 1, n, val, 1); }
    void erase(int val)     { update(1, 1, n, val, -1); }
    int query(int cnt)      { return query(1, 1, n, cnt); }
};

int64_t gilbertOrder(int x, int y, int pow, int rotate) {
	if (pow == 0)
		return 0;
	int hpow = 1 << (pow-1);
	int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2);
	seg = (seg + rotate) & 3;
	const int rotateDelta[4] = {3, 0, 0, 1};
	int nx = x & (x ^ hpow), ny = y & (y ^ hpow);
	int nrot = (rotate + rotateDelta[seg]) & 3;
	int64_t subSquareSize = int64_t(1) << (2*pow - 2);
	int64_t ans = seg * subSquareSize;
	int64_t add = gilbertOrder(nx, ny, pow-1, nrot);
	ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
	return ans;
}

struct query {
    int l, r, k, id;
    int64_t ord;
    void calOrder() {
    	ord = gilbertOrder(l, r, 21, 0);
    }
} q[MAX];

SegTree ST;
const int block = 700;
int v[MAX], cnt[MAX], ans[MAX];

bool cmp(query &a, query &b) {
	return a.ord < b.ord;
}

int main() {

    int n, m;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; ++i)
        scanf("%d", &v[i]);

    for(int i = 0; i < m; ++i) {
        scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].k);
        --q[i].l, --q[i].r, q[i].id = i;
        q[i].k = (q[i].r-q[i].l+1)/q[i].k;
    }

    sort(q, q+m, cmp);
    ST.n = n;
    //memset(ST.tree, 0, sizeof ST.tree);

    int l = 0, r = -1;
    for(int i = 0; i < m; ++i) {
        while(l > q[i].l)   ST.insert(v[--l]);
        while(r < q[i].r)   ST.insert(v[++r]);
        while(l < q[i].l)   ST.erase(v[l++]);
        while(r > q[i].r)   ST.erase(v[r--]);

        ans[q[i].id] = ST.query(q[i].k+1);
        //cout << "Query " << i << " " << q[i].id << " " << q[i].l << " " << q[i].r << " " << q[i].k+1 << " = " << ans[q[i].id] << endl;
    }

    for(int i = 0; i < m; ++i)
        printf("%d\n", ans[i]);
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 800)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 150)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 10)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 300)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 100)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 8)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 300)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 110)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 7)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 300)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 100)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 7)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 300)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 120)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 7)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 500)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 100)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, 10)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
const int B = 60;

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    mt19937 rnd(239);
    int n, q;
    scanf("%d %d", &n, &q);
    rep(i, 0, n)
    {
        scanf("%d", &a[i]);
        a[i]--;
        pos[a[i]].push_back(i);
    }
    while (q--)
    {
        int l, r, k;
        scanf("%d %d %d", &l, &r, &k);
        l--; r--;
        int ans = inf;
        if ((r - l + 1) <= B)
        {
            rep(i, l, r + 1)
            {
                int cnt = upper_bound(pos[a[i]].begin(), pos[a[i]].end(), r) - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                if (cnt * k > (r - l + 1))
                    ans = min(ans, a[i]);
            }
        }
        else
        {
            rep(x, 0, B)
            {
                int i = (int)rnd() % (r - l + 1);
                if (i < 0)
                    i += (r - l + 1);
                i += l;
                int cnt = upper_bound(pos[a[i]].begin(), pos[a[i]].end(), r) - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                if (cnt * k > (r - l + 1))
                    ans = min(ans, a[i]);
            }
        }
        cout << (ans < inf ? ans + 1 : -1) << "\n";
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
const int B = 2;

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    rep(i, 0, n)
    {
        scanf("%d", &a[i]);
        a[i]--;
        pos[a[i]].push_back(i);
    }
    while (q--)
    {
        int l, r, k;
        scanf("%d %d %d", &l, &r, &k);
        l--; r--;
        int ans = inf;
        if ((r - l + 1) <= B)
        {
            rep(i, l, r + 1)
            {
                int cnt = upper_bound(pos[a[i]].begin(), pos[a[i]].end(), r) - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                if (cnt * k > (r - l + 1))
                    ans = min(ans, a[i]);
            }
        }
        else
        {
            rep(x, 0, B)
            {
                int i = rand() % (r - l + 1) + l;
                int cnt = upper_bound(pos[a[i]].begin(), pos[a[i]].end(), r) - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                if (cnt * k > (r - l + 1))
                    ans = min(ans, a[i]);
            }
        }
        cout << (ans < inf ? ans + 1 : -1) << "\n";
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int a[N];
vector<int> pos[N];
int ttt[N];
int p = 0;
int ask[N];
bool used[N];

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    int n, q;
    scanf("%d %d", &n, &q);
    //n = 300000; q = 300000;
    rep(i, 0, n)
    {
    	scanf("%d", &a[i]);
    	//a[i] = rand() % n + 1;
    	a[i]--;
    	pos[a[i]].push_back(i);
    }
    while (q--)
    {
    	int l, r, k;
    	scanf("%d %d %d", &l, &r, &k);
    	//l = rand() % n + 1; r = rand() % n + 1; if (l > r) swap(l, r); k = rand() % 4 + 2;
    	l--; r--;
    	if ((r - l + 1) <= 300)
    	{
    		int ans = inf, best = -1;
    		rep(i, l, r + 1)
    		{
    			ttt[a[i]]++;
    			if (ttt[a[i]] > best || ttt[a[i]] == best && a[i] < ans)
    			{
    				ans = a[i];
    				best = ttt[a[i]];
    			}
    		}
    		if (best * k > (r - l + 1))
    			cout << ans + 1 << "\n";
    		else
    			cout << -1 << "\n";
    		rep(i, l, r + 1)
    			ttt[a[i]] = 0;
    	}
    	else
    	{
    		p = 0;
    		rep(x, 0, 250)
    		{
    			int i = rand() % (r - l + 1) + l;
    			ask[p++] = a[i];
    		}
    		vector<int> var;
    		rep(u, 0, k)
    		{
    			int ans = inf, best = -1;
    			rep(i, 0, p)
    			{
    				if (used[ask[i]])
    					continue;
    				ttt[ask[i]]++;
    				if (ttt[ask[i]] > best || ttt[ask[i]] == best && ask[i] < ans)
	    			{
	    				ans = ask[i];
	    				best = ttt[ask[i]];
	    			}
    			}
    			rep(i, 0, p)
    				ttt[ask[i]] = 0;
    			if (best != -1)
    			{
    				used[ans] = true;
    				var.push_back(ans);
    			}
    			else
    				break;
    		}
    		sort(var.begin(), var.end());
    		bool solved = false;
    		for (int x : var)
    		{
    			int cnt = upper_bound(pos[x].begin(), pos[x].end(), r) - lower_bound(pos[x].begin(), pos[x].end(), l);
    			if (k * cnt > (r - l + 1))
    			{
    				cout << x + 1 << "\n";
    				solved = true;
    				break;
    			}
    		}
    		for (int x : var)
    			used[x] = false;
    		if (!solved)
    			cout << -1 << "\n";
    	}
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdc++.h>

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = l; i < r; i++)
#define repb(i, r, l) for (int i = r; i > l; i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)

using namespace std;

const int N = 300000;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

struct query
{
    int l, r, k, id;
    query() {}
    query(int l, int r, int k, int id) : l(l), r(r), k(k), id(id) {}
};

int a[N];
vector<int> pos[N];
const int B = 70;

int main()
{
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    //ll TL = 0.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    mt19937 rnd(239);
    int n, q;
    scanf("%d %d", &n, &q);
    rep(i, 0, n)
    {
        scanf("%d", &a[i]);
        a[i]--;
    }
    vector<query> qqq[n];
    rep(i, 0, q)
    {
        int l, r, k;
        scanf("%d %d %d", &l, &r, &k);
        l--; r--;
        qqq[r].push_back({l, r, k, i});
    }
    int out[q];
    rep(r, 0, n)
    {
        pos[a[r]].push_back(r);
        for (auto &Q : qqq[r])
        {
            int l = Q.l, k = Q.k, len = (r - l + 1);
            int ans = inf;
            if ((r - l + 1) <= B)
            {
                rep(i, l, r + 1)
                {
                    int cnt = pos[a[i]].end() - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                    if (cnt * k > (r - l + 1))
                        ans = min(ans, a[i]);
                }
            }
            else
            {
                rep(x, 0, B)
                {
                    int i = (int)rnd() % (r - l + 1);
                    if (i < 0)
                        i += (r - l + 1);
                    i += l;
                    int cnt = pos[a[i]].end() - lower_bound(pos[a[i]].begin(), pos[a[i]].end(), l);
                    if (cnt * k > (r - l + 1))
                        ans = min(ans, a[i]);
                }
            }
            out[Q.id] = (ans < inf ? ans + 1 : -1);
        }
    }
    rep(i, 0, q)
        cout << out[i] << "\n";
    return 0;
}