#ifndef AFDS_DSU
#define AFDS_DSU
#include<numeric>
#include<vector>structDSU{std::vector<int>fa,siz;DSU(intn):fa(n+1),siz(n+1,1){std::iota(fa.begin(),fa.end(),0);}inlineintfind(intx){returnfa[x]==x?x:fa[x]=find(fa[x]);}inlineboolsame(intx,inty){returnfind(x)==find(y);}// true if x and y were not in the same set, false otherwise.inlineboolmerge(intx,inty){intfx=find(x),fy=find(y);if(fx==fy)returnfalse;if(siz[fx]<siz[fy])std::swap(fx,fy);fa[fy]=fx,siz[fx]+=siz[fy],siz[fy]=0;returntrue;}// x -> y, a.k.a let x be son of y (disable merge by rank).inlinebooldirected_merge(intx,inty){intfx=find(x),fy=find(y);if(fx==fy)returnfalse;fa[fx]=fy,siz[fy]+=siz[fx],siz[fx]=0;returntrue;}};#endif // AFDS_DSU
#line 1 "src/alfred/data_structure/dsu.hpp"
#include<numeric>
#include<vector>structDSU{std::vector<int>fa,siz;DSU(intn):fa(n+1),siz(n+1,1){std::iota(fa.begin(),fa.end(),0);}inlineintfind(intx){returnfa[x]==x?x:fa[x]=find(fa[x]);}inlineboolsame(intx,inty){returnfind(x)==find(y);}// true if x and y were not in the same set, false otherwise.inlineboolmerge(intx,inty){intfx=find(x),fy=find(y);if(fx==fy)returnfalse;if(siz[fx]<siz[fy])std::swap(fx,fy);fa[fy]=fx,siz[fx]+=siz[fy],siz[fy]=0;returntrue;}// x -> y, a.k.a let x be son of y (disable merge by rank).inlinebooldirected_merge(intx,inty){intfx=find(x),fy=find(y);if(fx==fy)returnfalse;fa[fx]=fy,siz[fy]+=siz[fx],siz[fx]=0;returntrue;}};