#include <stdio.h>
#include <string.h>

#define N (100)

int dad[N];

/* if apply flag is on, connect two branches of the graph.
 * Returns true if the 2 nodes are connected
 */
int unionfind_slow(int a, int b, int apply) {
	int i=a, j=b;
	/* join a with the topmost parent */
	while (dad[i] > 0 ) i=dad[i];
	/* join b with the topmost parent */
	while (dad[j] > 0 ) j=dad[j];
	/* if to apply, join them */
	if (apply && i!=j) {
		dad[j]=i;
		return 1;
	}
	/* are they in the same tree? */
	return (i==j);
}

/* if apply flag is on, connect two branches of the graph.
 * Returns true if the 2 nodes are connected
 *
 * 1-lets put the best root in every node we transverse
 * 2-when unioning, select the tree with less nodes to
 *   have the other as parent it will keep it balanced.
 *   save the number of noded in the root as neg number
 */
int unionfind(int a, int b, int apply) {
	int t, i=a, j=b;
	/* join a with the topmost parent */
	while (dad[i]>0) i=dad[i];
	/* join b with the topmost parent */
	while (dad[j]>0) j=dad[j];

	/* apply the top most parent to all the nodes in the way*/
	while (dad[a]>0) { t=a; a=dad[a]; dad[t]=i; } 
	/* apply the top most parent to all the nodes in the way*/
	while (dad[b]>0) { t=b; b=dad[b]; dad[t]=i; } 

	if (apply && i!=j) {
		if (dad[j]<dad[i])
			{ dad[j] += dad[i]-1; dad[i]=j; }
		else
			{ dad[i] += dad[j]-1; dad[j]=i; }
		return 1;
	}

	/* are they in the same tree? */
	return (i==j);
}

int main(void) {
	memset(dad,sizeof(dad),0);


	/* lets union some prime numbers */
	unionfind(2,7,1);
	unionfind(3,11,1);
	unionfind(13,7,1);
	unionfind(5,7,1);
	unionfind(2,11,1);
	/* and some non prime */
	unionfind(8,1,1);
	unionfind(6,20,1);
	unionfind(1,6,1);

	printf("%d %d, %d\n", 2,7,unionfind(2,7,0));
	printf("%d %d, %d\n", 5,11,unionfind(5,11,0));
	printf("%d %d, %d\n", 5,8,unionfind(5,8,0));
	printf("%d %d, %d\n", 20,1,unionfind(20,1,0));
	
	return 0;
}

