template <typename _Ty>
struct Node {
Node(const _Ty& d) : data(d) {}
_Ty data;
int rank = 0;
Node<_Ty>* p = nullptr;
};
template <typename _Ty>
void make_set(Node<_Ty>* node) {
node->p = node;
node->rank = 0;
}
template <typename _Ty>
void __link(Node<_Ty>* lhs, Node<_Ty>* rhs) {
if (lhs->rank > rhs->rank) {
rhs->p = lhs;
} else {
lhs->p = rhs;
if (lhs->rank == rhs->rank) {
rhs->rank++;
}
}
}
template <typename _Ty>
void union_set(Node<_Ty>* lhs, Node<_Ty>* rhs) {
__link(find_set(lhs), find_set(rhs));
}
template <typename _Ty>
Node<_Ty>* find_set(Node<_Ty>* node) {
if (node != node->p) {
node->p = find_set(node->p);
}
return node->p;
}