#include <iostream>
using namespace std;
const int N = 100010;
struct Leftist_Tree_Node
{
int l, r;
int v, dist;
void init(int _v)
{
v = _v, dist = 1;
}
}tr[N];
int n, m;
int p[N];
bool st[N];
int find(int x)
{
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
inline bool cmp(int x, int y)
{
if (tr[x].v != tr[y].v) return tr[x].v < tr[y].v;
return x < y;
}
int merge(int x, int y)
{
if (!x || !y) return x + y;
if (cmp(y, x)) swap(x, y);
tr[x].r = merge(tr[x].r, y);
if (tr[tr[x].l].dist < tr[tr[x].r].dist) swap(tr[x].l, tr[x].r);
tr[x].dist = tr[tr[x].r].dist + 1;
return x;
}
int main()
{
int op, x, y;
tr[0].init(-2e9);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ )
{
scanf("%d", &x);
tr[i].init(x), p[i] = i;
}
while (m -- )
{
scanf("%d%d", &op, &x);
if (op == 1)
{
scanf("%d", &y);
int r1 = find(x), r2 = find(y);
if (st[x] || st[y] || r1 == r2) continue;
if (cmp(r2, r1)) swap(r1, r2);
p[r2] = r1;
merge(r1, r2);
}
else
{
int rt = find(x);
if (st[x]) puts("-1");
else
{
printf("%d\n", tr[rt].v);
if (cmp(tr[rt].r, tr[rt].l)) swap(tr[rt].l, tr[rt].r);
merge(tr[rt].l, tr[rt].r);
st[rt] = true;
p[rt] = tr[rt].l, p[tr[rt].l] = tr[rt].l;
}
}
}
return 0;
}