class Solution:
    def findTheLongestSubstring(self, s: str) -> int:
        """tc O(N) sc O(2^M)
        use a counter to get # each vowels
        if in substring, if vowel = 0, can keep increasing 
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        
        main idea: bit mask. note it's not about counting number of each vowels in string. it's check if vowels is odd or even 
        e.g. if 'a' is odd, mask 00001, o
        update mask as looping each ch in s, track smallest idx for each mask combination
        
        if same mask seen, string between smallest(exclusive) and current (inclusive) index meet criteria
        ==>
        find max dist betwwen first and last index fir each mask comb
        """
        seen = {0:-1} # for case where s contains no vowels, longest substring applied is i-(-1) = i + 1
        res = mask = 0
        d={'a':1,'e':2,'i':4,'o':8,'u':16}
        for i,c in enumerate(s):
            #mask ^= 1 << ('aeiou'.find(c)+1) >> 1
            #idx = 'aeiou'.find(c) # in case find() return -1 
            idx = d.get(s[i],-1)
            if idx != -1:
                state = 1 << idx
            else:
                state = 0
            #state = state >> 1 
            mask = mask ^ state 
            if mask not in seen:
                seen[mask] = i #[!important] record index of first occurance of mask 
            res = max(res,i-seen[mask])  #string between smallest(exclusive) and current (inclusive) index meet criteria 
    
        return res