#include <bits/stdc++.h>
using namespace std ;
#define ft first
#define sd second
#define pb push_back
#define all(x) x.begin(),x.end()
#define ll long long int
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define mp make_pair
#define sc1(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define scll1(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define pr1(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)
#define prll1(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)
#define pr_vec(v) for(int i=0;i<v.size();i++) cout << v[i] << " " ;
const int mod = 1000000000 + 7 ;
const int maxn = 300000 + 10 ;
/*
* C++ program to Implement AVL Tree
*/
#define pow2(n) (1 << (n))
using namespace std;
/*
* Node Declaration
*/
struct avl_node
{
int data , sz ;
struct avl_node *left;
struct avl_node *right;
} *root[maxn];
/*
* Class Declaration
*/
class avlTree
{
public:
int height(avl_node *);
int diff(avl_node *);
avl_node *rr_rotation(avl_node *);
avl_node *ll_rotation(avl_node *);
avl_node *lr_rotation(avl_node *);
avl_node *rl_rotation(avl_node *);
avl_node* balance(avl_node *);
avl_node* insert(avl_node *, int );
void display(avl_node *,avl_node *, int);
void inorder(avl_node *);
void preorder(avl_node *);
void postorder(avl_node *);
int getkthelement(avl_node *,int) ;
void freebst(avl_node *) ;
};
/*
* Main Contains Menu
*/
avlTree avl ;
int parent[maxn] , _rank[maxn] , setno[maxn] ;
vi adj[maxn] ;
void _union(int x,int y,int z){
x = setno[x] ;
y = setno[y] ;
setno[x] = setno[y] = -1 ;
if(x != y){
if(_rank[x] < _rank[y]){
parent[x] = y ;
setno[z] = y ;
_rank[y] += _rank[x] ;
for(int i=0;i<adj[x].size();i++){
root[y] = avl.insert(root[y],adj[x][i]) ;
adj[y].pb(adj[x][i]) ;
}
adj[x].clear() ;
avl.freebst(root[x]) ;
}else{
parent[y] = x ;
setno[z] = x ;
_rank[x] += _rank[y] ;
for(int i=0;i<adj[y].size();i++){
root[x] = avl.insert(root[x],adj[y][i]) ;
adj[x].pb(adj[y][i]) ;
}
adj[y].clear() ;
avl.freebst(root[y]) ;
}
}
}
int main()
{
int n , q , cnt = 0 ;
cin >> n >> q ;
for(int i=1;i<=n;i++){
parent[i] = i ;
_rank[i] = 1 ;
setno[i] = i ;
adj[i].pb(i) ;
root[i] = avl.insert(root[i],i) ;
}
while( q-- ){
string ch ;
cin >> ch ;
int x , y ;
sc2(x,y) ;
if(ch[0] == 'U'){
cnt ++ ;
_union(x,y,n+cnt) ;
}else{
x = setno[x] ; assert( x != -1 ) ;
printf("%d\n",avl.getkthelement(root[x],y)) ;
}
}
return 0;
}
/*
* Height of AVL Tree
*/
int avlTree::height(avl_node *temp)
{
int h = 0;
if (temp != NULL)
{
int l_height = height (temp->left);
int r_height = height (temp->right);
int max_height = max (l_height, r_height);
h = max_height + 1;
}
return h;
}
void avlTree::freebst(avl_node *root){
if(!root) return ;
freebst(root->left) ;
freebst(root->right) ;
delete root ;
}
/**
kth element in the bst
**/
int avlTree::getkthelement(avl_node *root,int k)
{
int left , right ;
left = (root->left) ? root->left->sz : 0 ;
right = (root->right) ? root->right->sz : 0 ;
if(left >= k)
return getkthelement(root->left,k) ;
else if(left+1 == k)
return root->data ;
else
return getkthelement(root->right,k-left-1) ;
}
/*
* Height Difference
*/
int avlTree::diff(avl_node *temp)
{
int l_height = height (temp->left);
int r_height = height (temp->right);
int b_factor= l_height - r_height;
return b_factor;
}
/*
* Right- Right Rotation
*/
avl_node *avlTree::rr_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->right;
parent->right = temp->left;
parent->sz = ( parent->left ? parent->left->sz : 0 ) + (parent->right ? parent->right->sz : 0) + 1 ;
temp->left = parent;
temp->sz = ( temp->left ? temp->left->sz : 0 ) + (temp->right ? temp->right->sz : 0) + 1 ;
return temp;
}
/*
* Left- Left Rotation
*/
avl_node *avlTree::ll_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->left;
parent->left = temp->right;
parent->sz = ( parent->left ? parent->left->sz : 0 ) + (parent->right ? parent->right->sz : 0) + 1 ;
temp->right = parent;
temp->sz = ( temp->left ? temp->left->sz : 0 ) + (temp->right ? temp->right->sz : 0) + 1 ;
return temp;
}
/*
* Left - Right Rotation
*/
avl_node *avlTree::lr_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->left;
parent->left = rr_rotation(temp);
parent->sz = ( parent->left ? parent->left->sz : 0 ) + (parent->right ? parent->right->sz : 0) + 1 ;
return ll_rotation (parent);
}
/*
* Right- Left Rotation
*/
avl_node *avlTree::rl_rotation(avl_node *parent)
{
avl_node *temp;
temp = parent->right;
parent->right = ll_rotation (temp);
parent->sz = ( parent->left ? parent->left->sz : 0 ) + (parent->right ? parent->right->sz : 0) + 1 ;
return rr_rotation (parent);
}
/*
* Balancing AVL Tree
*/
avl_node *avlTree::balance(avl_node *temp)
{
int bal_factor = diff (temp);
if (bal_factor > 1)
{
if (diff (temp->left) > 0)
temp = ll_rotation (temp);
else
temp = lr_rotation (temp);
}
else if (bal_factor < -1)
{
if (diff (temp->right) > 0)
temp = rl_rotation (temp);
else
temp = rr_rotation (temp);
}
return temp;
}
/*
* Insert Element into the tree
*/
avl_node *avlTree::insert(avl_node *root, int value)
{
if (root == NULL)
{
root = new avl_node;
root->data = value;
root->left = NULL;
root->right = NULL;
root->sz = 1 ;
return root;
}
else if (value < root->data)
{
root->left = insert(root->left, value);
root->sz = ( (root->left) ? root->left->sz : 0 ) + ( (root->right) ? root->right->sz : 0 ) + 1 ;
root = balance (root);
}
else if (value >= root->data)
{
root->right = insert(root->right, value);
root->sz = ( (root->left) ? root->left->sz : 0 ) + ( (root->right) ? root->right->sz : 0 ) + 1 ;
root = balance (root);
}
root->sz = ( (root->left) ? root->left->sz : 0 ) + ( (root->right) ? root->right->sz : 0 ) + 1 ;
return root;
}