// Arup Guha
// 1/23/2024
// Implementation of Disjoint Set with path compression

import java.util.*;

public class testdj {

	public static void main(String[] args) {
	
		Random r = new Random();
		djset mine = new djset(10);
		for (int i=0; i<12; i++) {
		
			// merge 2 random things.
			int a = r.nextInt(10);
			int b = r.nextInt(10);
			if (b == a) b = (b+1)%10;
			
			// Call union.
			System.out.println("union of "+a+" and "+b);
			boolean ans = mine.union(a, b);
			
			// Print basic result.
			if (ans) System.out.println("successful");
			else System.out.println("already together");
			
			// Print the object.
			System.out.println(mine);
		}
	}
}

class djset {
	
	private int n;
	private int[] par;
	
	// Constructor: n separate trees.
	public djset(int size) {
		n = size;
		par = new int[n];
		for (int i=0; i<n; i++)
			par[i] = i;
	}
	
	// Find the root of the tree storing u.
	private int find(int u) {
	
		// At top.
		if (par[u] == u) return u;
		
		// This does path compression.
		return par[u] = find(par[u]);
	}
	
	public boolean union(int u, int v) {
	
		// Get roots.
		u = find(u);
		v = find(v);
		
		// Same tree.
		if (u == v) return false;
		
		// Attach v to u.
		par[v] = u;
		return true;
	}
	
	// Returns string representation of the object.
	public String toString() {
		String res = "[";
		for (int i=0; i<n-1; i++)
			res = res + par[i] + ",";
		res = res + par[n-1]+"]";
		return res;
	}

}