<p>You are given <code>n</code> item&#39;s value and label as two integer arrays <code>values</code> and <code>labels</code>. You are also given two integers <code>numWanted</code> and <code>useLimit</code>.</p>

<p>Your task is to find a subset of items with the <strong>maximum sum</strong> of their values such that:</p>

<ul>
	<li>The number of items is <strong>at most</strong> <code>numWanted</code>.</li>
	<li>The number of items with the same label is <strong>at most</strong> <code>useLimit</code>.</li>
</ul>

<p>Return the maximum sum.</p>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">values = [5,4,3,2,1], labels = [1,1,2,2,3], numWanted = 3, useLimit = 1</span></p>

<p><strong>Output:</strong> <span class="example-io">9</span></p>

<p><strong>Explanation:</strong></p>

<p>The subset chosen is the first, third, and fifth items with the sum of values 5 + 3 + 1.</p>
</div>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">values = [5,4,3,2,1], labels = [1,3,3,3,2], numWanted = 3, useLimit = 2</span></p>

<p><strong>Output:</strong> <span class="example-io">12</span></p>

<p><strong>Explanation:</strong></p>

<p>The subset chosen is the first, second, and third items with the sum of values 5 + 4 + 3.</p>
</div>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">values = [9,8,8,7,6], labels = [0,0,0,1,1], numWanted = 3, useLimit = 1</span></p>

<p><strong>Output:</strong> <span class="example-io">16</span></p>

<p><strong>Explanation:</strong></p>

<p>The subset chosen is the first and fourth items with the sum of values 9 + 7.</p>
</div>

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

<ul>
	<li><code>n == values.length == labels.length</code></li>
	<li><code>1 &lt;= n &lt;= 2 * 10<sup>4</sup></code></li>
	<li><code>0 &lt;= values[i], labels[i] &lt;= 2 * 10<sup>4</sup></code></li>
	<li><code>1 &lt;= numWanted, useLimit &lt;= n</code></li>
</ul>

class Solution:
    def largestValsFromLabels(self, values: List[int], labels: List[int], numWanted: int, useLimit: int) -> int:
        def mergeSort(A, B, i, p):
            if i >= p:
                return
            q = (i + p) // 2
            mergeSort(A, B, i, q)
            mergeSort(A, B, q + 1, p)
            merge(A, B, i, q, p)
        
        def merge(A, B, i, q, p):
            leftA = A[i:q + 1]  # left part of values
            leftB = B[i:q + 1]  # left part of labels
            rightA = A[q + 1:p + 1]  # right part of values
            rightB = B[q + 1:p + 1]  # right part of labels
            
            k = i
            l = r = 0
            
            # Merge both halves
            while l < len(leftA) and r < len(rightA):
                if leftA[l] >= rightA[r]:
                    A[k] = leftA[l]
                    B[k] = leftB[l]
                    l += 1
                else:
                    A[k] = rightA[r]
                    B[k] = rightB[r]
                    r += 1
                k += 1
            
            # Copy the remaining elements, if any
            while l < len(leftA):
                A[k] = leftA[l]
                B[k] = leftB[l]
                l += 1
                k += 1
            
            while r < len(rightA):
                A[k] = rightA[r]
                B[k] = rightB[r]
                r += 1
                k += 1

        # Sort values and labels by values in descending order
        mergeSort(values, labels, 0, len(values) - 1)

        label_count = {}
        total = 0
        items_selected = 0
        
        for value, label in zip(values, labels):
            if label_count.get(label, 0) < useLimit:
                total += value
                label_count[label] = label_count.get(label, 0) + 1
                items_selected += 1
                if items_selected == numWanted:
                    break

        return total
20500