Two pass

class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
    # time O(N) space O(N)
    # step1: create a hashset and put num into set
    # step2: loop through nums, check each num's neighbour if left neighbour not in the set(means num may be beginning of the sequence)
    # step3: create a experimental right neighbour and check if  right neighbour in the set.  if yes, increment right neighbour by one (extend the candidate sequence )keep while loop, record the count
    # step4: loop until  experimental right neighbour not in the set, exit while loop, update max_count
    # repeat step2 -4 until iteration of nums is over, return max_cnt
        _set = set(nums)
        max_cnt = 0
        for x in nums:
            if x-1 not in _set:
                y = x+1
                cnt = 1
                while y in _set:
                    cnt +=1
                    y +=1
                max_cnt = max(max_cnt,cnt) #  max(max_cnt, y-x), if want to ignore y 
        return max_cnt

UF solution

class UF:
    def __init__(self,n):
        self.parent = list(range(n))
        self.ranks = [1]*n
        
    def find(self,x):
        if x != self.parent[x]:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    def union(self,u,v):
        pu = self.find(u)
        pv = self.find(v)
        if pu == pv:
            return False
        if self.ranks[pu] < self.ranks[pv]:
            self.parent[pu] = pv
            self.ranks[pv] += self.ranks[pu]
        else:
            self.parent[pv] = pu
            self.ranks[pu] += self.ranks[pv]
        return True

class Solution:
# time O(N+MlogN)~ O(N)   space O(N)
    def longestConsecutive(self, nums: List[int]) -> int:
        n = len(nums)
        uf = UF(n)
        res= 0
        dic = {nums[i]:i for i in range(n)}
        for x in nums:
            if x-1  in dic:
                uf.union(dic[x],dic[x-1])
            if x+1 in dic:
                uf.union(dic[x],dic[x+1])
            px = uf.find(dic[x])
            res = max(res,uf.ranks[px])
        return res