class Solution:
    def minSubarray(self, A: List[int], p: int) -> int:
        """ tc O(N)  sc O(N)  
        case1 no need to remove sum(A) % p == 0   
        case2 there is a min length subarray A[i:j], =>  [total - sum(A[i:j])] % p == 0   ==> total%p == sum(A[i:j])%p = rem
                                            ==> 1. caculate running sum `rsum`, store `rsum%p`  2. find prev A[:i]'s rmod s.t. {psum(A[:j]) - psum(A[:i])}%p == rem   ==>    (psum(A[:j])- rem)%p = psum(A[:i]) , so we need just to record psum(A[:k]) and look up if previous there is psum(A[:pre]) exit   
        case3: impossible to remove  sum(A) < p 
        
        `rsum`: current prefix remainder; 
        `total`
        hmap track 1.running sum modulo 2. most recent position for that modulo 
        as loop array, look up a `comp` modulo in hmap and track min size 
        """
        rem =  sum(A)%p
        if rem == 0:
            return 0
        last,n = {0:-1},len(A)# 0:-1 when A[0] == remainder: we get min window size = 1   
        rmod,min_w = 0,n
        for i,a in enumerate(A):
            rmod = (rmod + a)%p  
            if (rmod - rem)%p in last: # (r_mod - mod + p)%p # here + p to make % non-negtive 
                min_w = min(min_w,i-last[(rmod - rem)%p]) # if compliment is recorded,try to update min   (j,i]
            last[rmod] = i 
        return min_w if min_w < n else -1