<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:
        codes, cur, p, mod, n, res, ss = [], 0, 27, (1<<31)-1, len(s), 0, []
        # for c in s:
#             cur = (cur*p + ord(c) - 96) % mod
#             codes.append(cur)
#             ss.append(ord(c)-97)
            
#         print(codes)
#         print(ss)
#         print()
        
        for sz in range(minSize, maxSize+1):
            wCntr, cCntr = defaultdict(int), [0]*26
            cur, power = 0, 1
            for c in s[:sz]:
                cur = (cur*p + ord(c) - 97) % mod
                power = power * p % mod
                cCntr[ord(c)-97] += 1
            cnts = sum(cnt > 0 for cnt in cCntr)
            if cnts <= maxLetters:
                wCntr[cur] += 1
            for i in range(sz, n):
                cc, dd = ord(s[i]) - 97, ord(s[i-sz]) - 97 
                if not cCntr[cc]:
                    cnts += 1
                cCntr[cc] += 1
                cCntr[dd] -= 1
                if not cCntr[dd]:
                    cnts -= 1
                cur = (cur * p - (ord(s[i-sz])-97) * power + ord(s[i]) - 97) % mod
                if cnts <= maxLetters:
                    wCntr[cur] += 1
            #     print(cur)
            # print(power, wCntr.items())
            res = max(res, max(wCntr.values(), default=0))
        return res
29900