What I did wrong during the contest

I didn't run the second example by hand, or read the second example in text. Therefore, I didn't realize that if two words are both oppsites
of the third word, they will be equivalent.

In the end I spent too much time reasoning about the how to update the hate state efficiently. By the way I realize my mistake it is too
late.

To keep track of hates, we just need to keep track of each UF components roots, and note that each member can not have more than 1 hate. This makes answering relationship query easier, compared to keeping track of hate at the non-root level

When we try adding (a op b)


1. OppositeA and b will be merged => addEq(OpA, b)

2. OppositeB and a will be merged => addEq(OpB, a)

3. The root of the two's group will be marked as oppsite

4. if any of the above step is invalid, revert the changes

When we tray adding (a eq b)


1. we need to add equal to addEq(OpA, OpB) as well

2. each check is to ensure that they do not hate each other already

For addEq, we just need to look up in the oppsite array and make sure their parents are not against each other