My first instinct was Union-Find and I started going down that road before realizing UNFRIEND completely breaks it.
Sort the events by timestamp, then process them in order using a Union-Find (Disjoint Set Union) data structure to maintain connected components. After each event, check if the number of components has reduced to 1; if so, return the current timestamp. If all events are processed and the graph is never fully connected, return -1.
Pro tip: Mention that you can optimize by tracking the number of components and only checking when a union occurs, and that you should handle duplicate timestamps carefully by processing all events at the same timestamp before checking connectivity.
Confirm that events are not sorted, timestamps may have duplicates, and that FRIEND/UNFRIEND events can be interleaved. Ask if N is large and if events can be numerous.
Select Union-Find with path compression and union by rank for efficient connectivity tracking. Use a list to store events and sort them by timestamp.
Sort events by timestamp. Iterate through events, applying FRIEND as union and UNFRIEND as a split (which may require rebuilding or using a dynamic connectivity structure if splits are frequent).
After each timestamp (or after processing all events at the same timestamp), check if the number of connected components is 1. If so, return that timestamp.
If no timestamp achieves full connectivity, return -1. Also consider cases where N=1 (already connected at time 0) or no events.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.