<p>Given a string <code>s</code>, return the maximum number of occurrences of <strong>any</strong> substring under the following rules:</p>

<ul>
	<li>The number of unique characters in the substring must be less than or equal to <code>maxLetters</code>.</li>
	<li>The substring size must be between <code>minSize</code> and <code>maxSize</code> inclusive.</li>
</ul>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aababcaab&quot;, maxLetters = 2, minSize = 3, maxSize = 4
<strong>Output:</strong> 2
<strong>Explanation:</strong> Substring &quot;aab&quot; has 2 occurrences in the original string.
It satisfies the conditions, 2 unique letters and size 3 (between minSize and maxSize).
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aaaa&quot;, maxLetters = 1, minSize = 3, maxSize = 3
<strong>Output:</strong> 2
<strong>Explanation:</strong> Substring &quot;aaa&quot; occur 2 times in the string. It can overlap.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= maxLetters &lt;= 26</code></li>
	<li><code>1 &lt;= minSize &lt;= maxSize &lt;= min(26, s.length)</code></li>
	<li><code>s</code> consists of only lowercase English letters.</li>
</ul>

class Solution:
    def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
        
        dic = {}
        A = ord('a')-1
        P = 31
        M = 10**9+7

        def mod(n):
            return n%M
        for i in range(minSize, maxSize+1):
            arr = [0]*27
            hash = 0
            for j in range(0,i-1):
                curr = ord(s[j])-A
                arr[curr]+=1
                hash*=P
                hash = mod(hash)
                hash+=curr
                hash = mod(hash)
            
            hash= hash*P
            # print(hash, i, minSize, maxSize)
            for j in range(i-1,len(s)):
                curr = ord(s[j])-A
                arr[curr]+=1

                # i have string
                hash+=curr
                hash = mod(hash)

                count =0
                for l in arr:
                    if l!=0:
                        count+=1
                if count <=maxLetters:
                    if hash in dic:
                        dic[hash]+=1
                    else:
                        dic[hash]=1
                    
                
                hash = hash*P
                hash = mod(hash)
                prev = ord(s[j-i+1])-A
                hash = hash - (prev*(P**i))+M
                hash = mod(hash)

                arr[prev]-=1
        if not dic:
            return 0 
            
        return max(dic.values()) 


            
105100