// Arup Guha
// 9/8/2026
// Basic Disjoint Set Class

import java.util.*;

public class testdj {

	public static void main(String[] args) {
		
		/**** Test #1
		
		djset mine = new djset(10);
		boolean tmp = mine.union(0, 2);
		System.out.println("first union "+tmp);
		tmp = mine.union(3, 5);
		System.out.println("2nd union "+tmp);
		tmp = mine.union(0, 5);
		System.out.println("3rd union "+tmp);
		tmp = mine.union(6, 8);
		System.out.println("4th union "+tmp);
		System.out.println(mine);
		
		tmp = mine.union(2, 3);
		System.out.println("5th union "+tmp);
		****/
		
		/*** Test #2 ***/
		Random r = new Random();
		
		// Create a new disjoint set.
		int n = 1000000, cnt = 0;
		djset mine = new djset(n);
		
		// Keep going until everyone connected.
		while (mine.getNumComp() > 1) {
			
			// Pick a random pair, not necessarily distinct.
			int u = r.nextInt(n);
			int v = r.nextInt(n);
			cnt++;
			
			// Union the two sets (put a road between them)
			mine.union(u,v);
			
		}
		
		// See how long it took.
		System.out.println("Took "+cnt+" random unions");
	}
}

class djset {

	private int numComp;
	private int n;
	private int[] parent;

	// Constructor.
	public djset(int myn) {
		n = myn;
		numComp = n;
		parent = new int[n];
		
		// Everyone starts off as their own parent (separate trees).
		for (int i=0; i<n; i++)
			parent[i] = i;
	}
	
	public int getNumComp() {
		return numComp;
	}
	
	public int find(int u) {
	
		// We got to the root, return it.
		if (parent[u] == u) return u;
		
		// Get the answer, reset u's parent, and return.
		/*** This is path compression. ***/
		return parent[u] = find(parent[u]);
	}
	
	public boolean union(int u, int v) {
	
		// Update with roots.
		u = find(u);
		v = find(v);
		
		// No union operation actually conducted.
		if (u == v) return false;
		
		// Attach v to u.
		parent[v] = u;
		numComp--;
		return true;
	}
	
	// For testing purposes.
	public String toString() {
		String res = "";
		for (int i=0; i<n; i++)
			res = res + parent[i]+",";
		return res;
	}
}