Given an array arr that represents a permutation of numbers from 1 to n. You have a binary string of size n that initially has all its bits set to zero.
At each step i (assuming both the binary string and arr are 1-indexed) from 1 to n, the bit at position arr[i] is set to 1. You are given an integer m and you need to find the latest step at which there exists a group of ones of length m. A group of ones is a contiguous substring of 1s such that it cannot be extended in either direction.
Return the latest step at which there exists a group of ones of length exactly m. If no such group exists, return -1.
 
Example 1:
Input: arr = [3,5,1,2,4], m = 1
Output: 4
Explanation:
Step 1: "00100", groups: ["1"]
Step 2: "00101", groups: ["1", "1"]
Step 3: "10101", groups: ["1", "1", "1"]
Step 4: "11101", groups: ["111", "1"]
Step 5: "11111", groups: ["11111"]
The latest step at which there exists a group of size 1 is step 4.
Example 2:
Input: arr = [3,1,5,4,2], m = 2
Output: -1
Explanation:
Step 1: "00100", groups: ["1"]
Step 2: "10100", groups: ["1", "1"]
Step 3: "10101", groups: ["1", "1", "1"]
Step 4: "10111", groups: ["1", "111"]
Step 5: "11111", groups: ["11111"]
No group of size 2 exists during any step.

Example 3:
Input: arr = [1], m = 1
Output: 1

Example 4:
Input: arr = [2,1], m = 2
Output: 2

 
Constraints:

n == arr.length
1 <= n <= 10^5
1 <= arr[i] <= n
All integers in arr are distinct.
1 <= m <= arr.length

Difficulty: interview

Starter code:

class Solution:
    def findLatestStep(self, arr: List[int], m: int) -> int:
        

Solutions:
["class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        A = arr\n        if m == len(A): \n            return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        if m == len(arr):\n            return m\n        \n        groupLen = [0 for i in range(len(arr) + 2)]\n        \n        latestStep = -1\n        \n        for step in range(len(arr)):\n            index = arr[step] - 1\n            left = groupLen[index - 1] \n            right = groupLen[index + 1]\n            groupLen[index - left] = groupLen[index + right] = 1 + left + right\n            \n            if left == m or right == m:\n                latestStep = step\n            \n        return latestStep", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sizes = [0] * (len(arr) + 2)\n        res = -1\n        cnt = 0\n        for step, cur in enumerate(arr, start=1):\n            l, r = sizes[cur - 1], sizes[cur + 1]\n            new_sz = l + 1 + r\n            sizes[cur - l] = sizes[cur + r] = new_sz\n            if l == m:\n                cnt -= 1\n            if r == m:\n                cnt -= 1\n            if new_sz == m:\n                cnt += 1\n            if cnt:\n                res = step\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        count=[0]*(n+2)\n        lens=[0]*(n+2)\n        res=-1\n        for i,a in enumerate(arr):\n            if lens[a]:\n                continue\n            l=lens[a-1]\n            r=lens[a+1]\n            t=l+r+1\n            lens[a]=lens[a-l]=lens[a+r]=t\n            count[l]-=1\n            count[r]-=1\n            count[t]+=1\n            if count[m]:\n                res=i+1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        cnt = 0\n        lm = {i: 0 for i in range(len(arr) + 2)}\n        for i, idx in enumerate(arr):\n            length = lm[idx - 1] + 1 + lm[idx + 1]\n            if lm[idx - 1] == m:\n                cnt -= 1\n            if lm[idx + 1] == m:\n                cnt -= 1\n            if length == m:\n                cnt += 1\n            if cnt > 0:\n                res = i + 1\n            lm[idx - lm[idx - 1]] = length\n            lm[idx + lm[idx + 1]] = length\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        L = [None for i in range(N)]\n        \n        num_m_groups = 0\n        latest_step = -1\n        \n        for i in range(N):\n            idx = arr[i]-1\n            \n            if( (idx==0 or L[idx-1]==None) and (idx==N-1 or L[idx+1]==None)):\n                L[idx] = (idx,idx)\n                diff = 1\n                if(m==diff):\n                    num_m_groups += 1\n            elif((idx==0 or L[idx-1]==None)):\n                x,y = L[idx+1]\n                if(y-x+1==m):\n                    num_m_groups -= 1\n                new_pair = (idx,y)\n                L[idx] = new_pair\n                L[y] = new_pair\n                if(y-idx+1==m):\n                    num_m_groups += 1\n            elif((idx==N-1 or L[idx+1]==None)):\n                x,y = L[idx-1]\n                if(y-x+1==m):\n                    num_m_groups -= 1\n                new_pair = (x,idx)\n                L[idx] = new_pair\n                L[x] = new_pair\n                if(idx-x+1==m):\n                    num_m_groups += 1\n            else:\n                x1,y1 = L[idx-1]\n                x2,y2 = L[idx+1]\n                if(y1-x1+1==m):\n                    num_m_groups -= 1\n                if(y2-x2+1==m):\n                    num_m_groups -= 1\n                new_pair = (x1,y2)\n                if(y2-x1+1==m):\n                    num_m_groups += 1\n                L[x1] = new_pair\n                L[y2] = new_pair\n            if(num_m_groups>0):\n                latest_step = i+1\n        return latest_step\n                \n               \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        nums = []\n        max_index = -1\n        correct_blocks = 0\n        latest_index = -1\n        for _ in range(len(arr)):\n            nums.append(0)\n        for i in range(len(arr)):\n            index = arr[i]-1\n            \n            if index == 0:\n                try:\n                    nums[index] = 1 + nums[index+1]\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index+1] == m:\n                        correct_blocks += 1\n                    if nums[index+1] != 0:\n                        val = 1 + nums[index+1]\n                        nums[index + nums[index+1]] = val\n                        nums[index+1] = val\n                except:\n                    return 1\n            elif index == len(arr)-1:\n                try:\n                    nums[index] = 1 + nums[index-1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] == m:\n                        correct_blocks += 1\n                    if nums[index-1] != 0:\n                        val = 1 + nums[index - 1]\n                        nums[index - nums[index-1]] = val\n                        nums[index-1] = val\n                except:\n                    return 1\n            else:\n                try:\n                    val = 1 + nums[index-1] + nums[index+1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] + nums[index+1] == m:\n                        correct_blocks += 1\n                    nums[index] = val\n                    if nums[index-1] != 0:\n                        nums[index - nums[index-1]] = val\n                        nums[index-1] = val\n                    if nums[index+1] != 0:\n                        nums[index + nums[index+1]] = val\n                        nums[index+1] =va;\n                except:\n                    pass\n            if correct_blocks > 0:\n                latest_index = i+1\n        return latest_index", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if (m == len(arr)):\n            return len(arr)\n        \n        bit_information = [0] * (len(arr) + 2)\n        target_group_size_counter = 0\n        ret = -2\n        \n        \n        for i in range(len(arr)):\n            total_length = 1 + bit_information[arr[i] - 1] + bit_information[arr[i] + 1]   \n            bit_information[arr[i]] = total_length\n            target_group_size_counter -= 1 if bit_information[arr[i] - 1] == m else 0\n            bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n            target_group_size_counter -= 1 if bit_information[arr[i] + 1] == m else 0\n            bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n            target_group_size_counter += 1 if total_length == m else 0\n            ret = i if target_group_size_counter > 0 else ret\n            \n        return ret + 1       ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        l = len(arr)\n        x = [[] for x in range(l+1)]\n        if l == m:\n            return l\n\n        last = -1\n        lens = [0 for x in range(l+1)]\n        for i in range(0,l):\n            cur = arr[i]\n            right = []\n            left = []\n            if cur+1 < l+1:\n                right = x[cur+1]\n            if cur-1 >= 0:\n                left = x[cur-1]\n\n            lv = rv = cur\n            ss = 1\n            if left:\n                lv = left[1]\n                ss += left[0]\n                lens[left[0]] -=1     \n                if left[0] == m:\n                    last = i\n            if right:\n                rv = right[2]\n                ss += right[0]\n                lens[right[0]] -=1\n                if right[0] == m:\n                    last = i\n            lens[ss]+=1\n            x[lv] = [ss,lv,rv]\n            x[rv] = [ss,lv,rv]\n\n\n        \n        return last\n        \n        for i in range(l-1, 0, -1):\n            cur = arr[i]\n            if lC[cur] or rC[cur]:  return i\n            if cur+m+1 <= l:\n                temp = True\n                for j in range(cur+1,cur+m+1):\n                    if rC[j]:\n                        rC[j] = False\n                        temp = False\n                        break\n                if temp: rC[cur+m+1]=True\n            if cur-m-1 >= 0:\n                temp = True\n                for j in range(cur-m, cur):\n                    if lC[j]: \n                        lC[j] = False\n                        temp = False\n                        break\n                if temp: lC[cur-m-1]=True\n        return -1\n            \n        \n        \n        \n        \n        mx = l\n        mxcount = 1\n        ls = [l]\n        for i in range(l-1,-1,-1):\n            cur = arr[i]\n            prev = 0\n            j = self.bisearch(cur,done,0,len(done))\n            val = done[j]\n            prev = done[j-1]\n\n            if m == val-cur-1 or m == cur-prev-1:\n                return i\n\n            done = done[:j] +[cur] + done[j:]\n            \n            \n        return -1\n    \n    def bisearch(self, cur: List[int], arr:List[int], i:int, j:int) -> int:\n        if i==j:\n            return j\n        if j-i <= 1:\n            if arr[i] < cur:\n                return j\n            else:\n                return i\n        mid = (j-i)//2\n        if cur < arr[i+mid]:\n            return self.bisearch(cur, arr, i, i+mid)\n        else:\n            return self.bisearch(cur, arr, i+mid,j)\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        count = defaultdict(int)\n        left = {}\n        right = {}\n        lastStep = -1\n        for step, n in enumerate(arr):\n            i = n-1\n            # print('----')\n            # print(step, i)\n            newLeft = i\n            newRight = i\n\n            if i > 0:\n                if i-1 in right:\n                    newLeft = right[i-1]\n                    del right[i-1]\n                    count[i-newLeft] -= 1\n            if i < N-1:\n                if i+1 in left:\n                    newRight = left[i+1]\n                    del left[i+1]                    \n                    count[newRight-i] -= 1\n\n\n            left[newLeft] = newRight\n            right[newRight] = newLeft\n            count[newRight - newLeft + 1] += 1\n            # print('left:',left)\n            # print('right:',right)\n            # print('count:',count)\n            if count[m] > 0:\n                lastStep = step + 1\n\n        return lastStep", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start_dic, end_dic = {}, {}\n        m_len_interval = []\n        latest = -1\n        for step, position in enumerate(arr):\n            if position -1 not in end_dic and position + 1 not in start_dic:\n                start_dic[position] = 1\n                end_dic[position] = 1\n                if m == 1: m_len_interval.append((position, position))\n            if position - 1 in end_dic and position + 1 not in start_dic:\n                length = end_dic[position - 1]\n                old_start_index = position - 1 - length + 1\n                old_end_index = position - 1\n                if length == m:\n                    m_len_interval.remove((old_start_index, old_end_index))\n                new_start_index = old_start_index\n                new_end_index = position\n                start_dic[new_start_index] = length + 1\n                del end_dic[old_end_index]\n                end_dic[new_end_index] = length + 1\n                if length + 1 == m:\n                    m_len_interval.append((new_start_index, new_end_index))\n            if position - 1 not in end_dic and position + 1 in start_dic:\n                length = start_dic[position + 1]\n                old_start_index = position + 1\n                old_end_index = old_start_index + length - 1\n                if length == m:\n                    m_len_interval.remove((old_start_index, old_end_index))\n                new_start_index = position\n                new_end_index = old_end_index\n                del start_dic[old_start_index]\n                start_dic[new_start_index] = length + 1\n                end_dic[new_end_index] = length + 1\n                if length + 1 == m:\n                    m_len_interval.append((new_start_index, new_end_index))\n            if position - 1 in end_dic and position + 1 in start_dic:\n                old_len_1 = end_dic[position - 1]\n                old_start_index_1 = position - 1 - old_len_1 + 1\n                old_end_index_1 = position - 1\n                if old_len_1 == m: m_len_interval.remove((old_start_index_1, old_end_index_1))\n                old_len_2 = start_dic[position + 1]\n                old_start_index_2 = position + 1\n                old_end_index_2 = position + 1 + old_len_2 - 1\n                if old_len_2 == m: m_len_interval.remove((old_start_index_2, old_end_index_2))\n                new_start = old_start_index_1\n                new_end = old_end_index_2\n                new_len = old_len_1 + 1 + old_len_2\n                if new_len == m: m_len_interval.append((new_start, new_end))\n                start_dic[new_start] = new_len\n                end_dic[new_end] = new_len\n                del start_dic[old_start_index_2]\n                del end_dic[old_end_index_1]\n            if m_len_interval: latest = step\n        return latest + 1 if latest != -1 else -1\n                \n                \n                \n                \n                \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        h = defaultdict(int)\n        result = -1\n        counter = defaultdict(int)\n        \n        for i in range(len(arr)):\n            n = arr[i] - 1\n\n            l = h[n - 1]\n            r = h[n + 1]\n\n            if l > 0 or r > 0:\n                newL = l + r + 1\n                if l > 0:\n                    h[n - l] = newL\n                    counter[l] -= 1\n                if r > 0:\n                    h[n + r] = newL\n                    counter[r] -= 1\n                h[n] = newL\n                counter[newL] += 1\n            else:\n                h[n] = 1\n                counter[1] += 1\n            if counter[m] > 0:\n                result = i + 1\n            # print(counter)\n        return result\n", "class Solution:\n    def isSorted(self, arr):\n        for i in range(1, len(arr)):\n            if arr[i] < arr[i-1]:\n                return False\n        return True\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        if m == length:\n            # Full string of 1s can only be found at last step\n            return m\n        \n        if self.isSorted(arr):\n            return m\n        \n        # Pad front and back to make boundary conditions easier\n        binary = [0] * (len(arr) + 2)\n        latest_step = -1\n        \n        for step in range(length):\n            pos = arr[step]\n            binary[pos] = 1\n            \n            # Examine positions directly to the left and right i.e., group boundaries\n            # Find/store the new group size at the new boundaries\n            left_len = binary[pos-1]\n            right_len = binary[pos+1]\n            new_len = left_len + right_len + 1\n            \n            if left_len == m or right_len == m:\n                # Target length persistent until prev step\n                latest_step = step\n                \n            binary[pos-left_len] = new_len\n            binary[pos+right_len] = new_len\n                \n        return latest_step\n            \n    def findLatestStepNaive2(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        if m == length:\n            # Full string of 1s can only be found at last step\n            return m\n        \n        if self.isSorted(arr):\n            return m\n        \n        binary = [1] * len(arr)\n        \n        for step in range(length-1, m-1, -1):\n            pos = arr[step] - 1\n            binary[pos] = 0\n            \n            # Note that at each step, only one group is getting split into two\n            # All other groups stay the same, so no need to iterate through entire string\n            left_len = 0\n            right_len = 0\n            for i in range(pos-1, -1, -1):\n                if binary[i]:\n                    left_len += 1\n                else:\n                    break\n            for i in range(pos+1, length):\n                if binary[i]:\n                    right_len += 1\n                else:\n                    break\n            \n            # Check only newly-formed groups.\n            if left_len == m or right_len == m:\n                return step\n        return -1\n\n    def findLatestStepNaive(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        if m == length:\n            # Full string of 1s can only be found at last step\n            return m\n        \n        if self.isSorted(arr):\n            return m\n        \n        binary = [1] * len(arr)\n        \n        for step in range(length-1, m-1, -1):\n            binary[arr[step] - 1] = 0\n\n            # Iterate through current binary string\n            current_group_len = 0\n            max_group_len = 0\n            for j in range(length):\n                if binary[j]:\n                    current_group_len += 1\n                elif current_group_len > 0:\n                    if current_group_len == m:\n                        return step\n                    max_group_len = max(max_group_len, current_group_len)\n                    current_group_len = 0\n            if current_group_len == m:\n                return step\n            max_group_len = max(max_group_len, current_group_len)\n            # If max drops below m, stop; subsequent passes will only add more 0s\n            if max_group_len < m:\n                return -1\n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        n = len(arr)\n        if m == n:\n            print(n)\n\n        def dfs(start: int, end: int, step: int, target: int):\n            if end > len(arr) or end < 1:\n                return -1\n            if start > len(arr) or start < 1:\n                return -1\n            if end < start:\n                return -1\n            if end - start + 1 < target:\n                return -1\n\n            if end - start + 1 == target:\n                return step\n            bp = arr[step - 1]\n            res = -1\n            if start <= bp <= end:\n                res = max(dfs(start, bp - 1, step - 1, target),\n                          dfs(bp + 1, end, step - 1, target))\n            else:\n                res = max(res, dfs(start, end, step - 1, target))\n            return res\n\n\n        return dfs(1, n, n, m)\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        \n        # my solution ... 1424 ms ... 77 % ... 27.7 MB ... 92 %\n        #  time: O(n)\n        # space: O(n)\n        \n        res = -1\n        e2s = {}  # e2s[5] = 3 \u8868\u793a 3-4-5 \u4f4d\u7f6e\u73b0\u5728\u5747\u4e3a1\u3002\u6b64\u65f6\u5fc5\u6709s2e[3] = 5\n        s2e = {}\n        cnt = {}  # cnt[3] = 8 \u8868\u793a\u6b64\u65f6\u6709 8 \u4e2a '111'\n        for i, v in enumerate(arr):  # i+1 \u662f\u5f53\u524d step\uff0cv\u662f\u5f53\u524dstep\u4ece0\u53d8\u4e3a1\u7684\u4f4d\u7f6e\uff0c\u5176\u4e24\u4fa7\u7684\u7d22\u5f15\u4e3av-1\u548cv+1\n            if v-1 not in e2s and v+1 not in s2e:\n                l, r = v, v\n            elif v-1 not in e2s and v+1 in s2e:\n                l, r = v, s2e[v+1]\n                del s2e[v+1]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            elif v-1 in e2s and v+1 not in s2e:\n                l, r = e2s[v-1], v\n                del e2s[v-1]\n                cnt[v-l] -= 1\n                if not cnt[v-l]:\n                    del cnt[v-l]\n            else:\n                l, r = e2s[v-1], s2e[v+1]  # \u4f4d\u7f6e v \u53d8\u4e3a 1 \u540e\uff0cv \u5de6\u4fa7\u6700\u8fdc 1 \u53ca v \u53f3\u4fa7\u6700\u8fdc 1\n                del e2s[v-1]\n                del s2e[v+1]\n                cnt[v-l] -= 1  # \u66f4\u65b0\u65e7\u7684\u9891\u6b21\n                if not cnt[v-l]:\n                    del cnt[v-l]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            s2e[l] = r\n            e2s[r] = l\n            cnt[r-l+1] = cnt.get(r-l+1, 0) + 1  # \u589e\u52a0\u65b0\u7684\u9891\u6b21\n            if m in cnt:\n                res = i + 1\n        return res\n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        \n        # my solution ... 1332 ms ... 80 % ... 27.5 MB ... 98 %\n        #  time: O(n)\n        # space: O(n)\n        \n        if m == len(arr):\n            return m\n        res = -1\n        e2s = {}  # e2s[5] = 3 \u8868\u793a 3-4-5 \u4f4d\u7f6e\u73b0\u5728\u5747\u4e3a1\u3002\u6b64\u65f6\u5fc5\u6709s2e[3] = 5\n        s2e = {}\n        cnt = {}  # cnt[3] = 8 \u8868\u793a\u6b64\u65f6\u6709 8 \u4e2a '111'\n        for i, v in enumerate(arr):  # i+1 \u662f\u5f53\u524d step\uff0cv\u662f\u5f53\u524dstep\u4ece0\u53d8\u4e3a1\u7684\u4f4d\u7f6e\uff0c\u5176\u4e24\u4fa7\u7684\u7d22\u5f15\u4e3av-1\u548cv+1\n            if v-1 not in e2s and v+1 not in s2e:\n                l, r = v, v\n            elif v-1 not in e2s and v+1 in s2e:\n                l, r = v, s2e[v+1]\n                del s2e[v+1]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            elif v-1 in e2s and v+1 not in s2e:\n                l, r = e2s[v-1], v\n                del e2s[v-1]\n                cnt[v-l] -= 1\n                if not cnt[v-l]:\n                    del cnt[v-l]\n            else:\n                l, r = e2s[v-1], s2e[v+1]  # \u4f4d\u7f6e v \u53d8\u4e3a 1 \u540e\uff0cv \u5de6\u4fa7\u6700\u8fdc 1 \u53ca v \u53f3\u4fa7\u6700\u8fdc 1\n                del e2s[v-1]\n                del s2e[v+1]\n                cnt[v-l] -= 1  # \u66f4\u65b0\u65e7\u7684\u9891\u6b21\n                if not cnt[v-l]:\n                    del cnt[v-l]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            s2e[l] = r\n            e2s[r] = l\n            cnt[r-l+1] = cnt.get(r-l+1, 0) + 1  # \u589e\u52a0\u65b0\u7684\u9891\u6b21\n            if m in cnt:\n                res = i + 1\n        return res\n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        len_arr = len(arr)\n        tot = 0\n        latest = -1\n        i1 = 0\n        lis = [[] for x in range(len_arr)]\n        for i in arr:\n            index = i-1\n            if(index > 0 and lis[index-1] and index < len_arr-1 and lis[index+1]):\n                if(lis[index-1][2] == m):\n                    tot -= 1\n                if(lis[index+1][2] == m):\n                    tot -= 1\n                start = lis[index-1][0]\n                end = lis[index+1][1]\n                lis1 = [start, end, lis[index-1][2]+1+lis[index+1][2]]\n                if(lis1[2] == m):\n                    tot += 1\n                lis[start] = lis1\n                lis[end] = lis1\n            elif(index > 0 and lis[index-1]):\n                if(lis[index-1][2] == m):\n                    tot -= 1\n                start = lis[index-1][0]\n                end = index\n                if(lis[index-1][2] + 1 == m):\n                    tot += 1\n                lis1 = [start, end, lis[index-1][2]+1]\n                lis[start] = lis1\n                lis[end] = lis1\n            elif(index < len_arr - 1 and lis[index+1]):\n                if(lis[index+1][2] == m):\n                    tot -= 1\n                start = index\n                end = lis[index+1][1]\n                if(lis[index+1][2] + 1 == m):\n                    tot += 1\n                lis1 = [start, end, lis[index+1][2]+1]\n                lis[end] = lis1\n                lis[start] = lis1\n            else:\n                lis[index] = [index, index, 1]\n                if(m == 1):\n                    tot += 1\n            if(tot > 0):\n                latest = i1+1\n            i1 += 1\n        return latest", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        hd, td = {}, {}\n        ld = {}\n        n = -1\n        for k, i in enumerate(arr):\n            if i-1 in td and i+1 in hd:\n                h = td[i-1]\n                t = hd[i+1]\n                hd[h] = t\n                td[t] = h\n                del hd[i+1]\n                del td[i-1]\n                ld[t-i] = ld[t-i]-1\n                ld[i-h] = ld[i-h]-1\n                if t-h+1 not in ld:\n                    ld[t-h+1] = 0\n                ld[t-h+1] = ld[t-h+1] + 1\n            elif i-1 in td:\n                h = td[i-1]\n                hd[h] = i\n                td[i] = h\n                del td[i-1]\n                ld[i-h] = ld[i-h] - 1\n                if i-h+1 not in ld:\n                    ld[i-h+1] = 0\n                ld[i-h+1] = ld[i-h+1] + 1\n            elif i+1 in hd:\n                t = hd[i+1]\n                hd[i] = t\n                td[t] = i\n                del hd[i+1]\n                ld[t-i] = ld[t-i] - 1\n                if t-i+1 not in ld:\n                    ld[t-i+1] = 0\n                ld[t-i+1] = ld[t-i+1] + 1\n            else:\n                hd[i] = i\n                td[i] = i\n                if 1 not in ld:\n                    ld[1] = 0\n                ld[1] = ld[1] + 1\n            if m in ld and ld[m] > 0:\n                n = k+1\n        return n\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        f = [ii for ii in range(n)]     # union find\n        b = [0 for ii in range(n)]      # whether turns to 1\n        s = [0 for ii in range(n)]      # sum\n        def findunion(n):\n            if f[n] == n:\n                return n\n            else:\n                f[n] = findunion(f[n])\n                return f[n]\n        \n        ans = -1\n        m_set = 0\n        for i in range(len(arr)):\n            item = arr[i]-1\n            b[item] = 1\n            s[item] = 1\n            tmp = 1\n            \n            if item < n-1 and b[item+1] == 1:\n                f[item+1] = item\n                s[item] = s[item+1]+1\n                if s[item+1] == m:\n                    m_set -= 1\n                tmp = s[item]\n                \n            if item > 0 and b[item-1] == 1:\n                fa = findunion(item-1)\n                f[item] = fa\n                if s[fa] == m:\n                    m_set -= 1\n                s[fa] = s[item] + s[fa]\n                tmp = s[fa]\n                \n            if tmp == m:\n                m_set += 1\n            if m_set > 0:  \n                ans = i+1\n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        l = len(arr)\n        x = [[] for x in range(l+1)]\n        if l == m:\n            return l\n\n        last = -1\n        lens = [0 for x in range(l+1)]\n        for i in range(0,l):\n            cur = arr[i]\n            right = []\n            left = []\n            if cur+1 < l+1:\n                right = x[cur+1]\n            if cur-1 >= 0:\n                left = x[cur-1]\n\n            lv = rv = cur\n            ss = 1\n            if left:\n                lv = left[1]\n                ss += left[0]\n                lens[left[0]] -=1     \n                if left[0] == m:\n                    last = i\n            if right:\n                rv = right[2]\n                ss += right[0]\n                lens[right[0]] -=1\n                if right[0] == m:\n                    last = i\n            lens[ss]+=1\n            x[lv] = [ss,lv,rv]\n            x[rv] = [ss,lv,rv]\n\n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        states = [None]*len(arr)\n        numSizeM = 0\n        latestM = -1\n        for i in range(len(arr)):\n            ind = arr[i]-1\n            if ind != 0 and ind != len(arr)-1 and states[ind-1] != None and states[ind+1] != None:\n                leftInd = ind - states[ind-1][0]\n                rightInd = ind + states[ind+1][1]\n                if states[leftInd][1] == m:\n                    numSizeM -= 1\n                if states[rightInd][0] == m:\n                    numSizeM -= 1\n                groupSize = states[leftInd][1] + 1 + states[rightInd][0]\n                states[leftInd][1] = groupSize\n                states[rightInd][0] = groupSize\n                if groupSize == m:\n                    numSizeM += 1\n            elif ind != 0 and states[ind-1] != None:\n                leftInd = ind - states[ind-1][0]\n                if states[leftInd][1] == m:\n                    numSizeM -= 1\n                groupSize = states[leftInd][1] + 1\n                states[leftInd][1] = groupSize\n                states[ind] = [groupSize, 1]\n                if groupSize == m:\n                    numSizeM += 1\n            elif ind != len(arr)-1 and states[ind+1] != None:\n                rightInd = ind + states[ind+1][1]\n                if states[rightInd][0] == m:\n                    numSizeM -= 1\n                groupSize = states[rightInd][0] + 1\n                states[rightInd][0] = groupSize\n                states[ind] = [1, groupSize]                \n                if groupSize == m:\n                    numSizeM += 1\n            else:\n                states[ind] = [1, 1]\n                if m == 1:\n                    numSizeM += 1\n            if numSizeM > 0:\n                latestM = i+1\n        return latestM", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        sizes = collections.defaultdict(int)\n        has = [0]*len(arr)\n        ends = {}\n        out = 0\n        for i, a in enumerate(arr):\n            has[a-1] += 1\n            if a-1 in ends and a+1 in ends:\n                length1 = a-1 - ends[a-1] + 1\n                length2 = ends[a+1] + 1 - (a+1)\n                temp1 = ends[a+1]\n                temp2 = ends[a-1]\n                ends[temp2] = temp1\n                ends[temp1] = temp2\n                sizes[length1] -= 1\n                sizes[length2] -= 1\n                sizes[length1 + 1 + length2] += 1\n            elif a-1 in ends:\n                length1 = a-1 - ends[a-1] + 1\n                ends[a] = ends[a-1]\n                ends[ends[a-1]] = a\n                sizes[length1] -= 1\n                sizes[length1+1] += 1\n            elif a + 1 in ends:\n                length1 = ends[a+1] - (a+1) + 1\n                ends[a] = ends[a+1]\n                ends[ends[a+1]] = a\n                sizes[length1] -= 1\n                sizes[length1+1] += 1\n            else:\n                ends[a] = a\n                sizes[1] += 1\n            \n            if sizes[m] > 0:\n                out = i+1\n        return out if out else -1", "class Solution:         \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        lengths = [0 for _ in range(n + 2)]\n        last_seen = -1\n        for step, i in enumerate(arr):\n            left_length = lengths[i - 1]\n            right_length = lengths[i + 1]\n            new_length = left_length + right_length + 1\n            lengths[i] = new_length\n            lengths[i - left_length] = new_length\n            lengths[i + right_length] = new_length\n            if left_length == m or right_length == m:\n                last_seen = step\n        return last_seen", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        l = collections.defaultdict(int)\n        count = collections.defaultdict(int)\n        step = 0\n        for num in arr:\n            step += 1\n            left, right = l[num-1], l[num+1]\n            l[num] = l[num-left] = l[num+right] = left+right+1\n            count[left+right+1] += 1\n            count[left] -= 1\n            count[right] -= 1\n            if count[m]:\n                ans = step\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        forward = [0] * len(arr)\n        backward = [0] * len(arr)\n        counter = collections.defaultdict(int)\n        res = -1\n        step = 1\n        \n        for i in arr:\n            i = i - 1\n            #print(counter)\n            if i - 1 >= 0 and i + 1 < len(arr):\n                curr = forward[i-1] + 1 + backward[i+1]\n                counter[forward[i-1]] -= 1\n                if counter[forward[i-1]] == 0:\n                    del counter[forward[i-1]]\n                counter[backward[i+1]] -= 1\n                if counter[backward[i+1]] == 0:\n                    del counter[backward[i+1]]\n                backward[i-forward[i-1]] = curr\n                forward[i+backward[i+1]] = curr\n                counter[curr] += 1\n            elif i == 0 and i + 1 == len(arr):\n                if m == 1:\n                    return step\n                else:\n                    break\n            elif i == 0:\n                curr = 1 + backward[i+1]\n                counter[backward[i+1]] -= 1\n                if counter[backward[i+1]] == 0:\n                    del counter[backward[i+1]]\n                backward[i] = curr\n                forward[i+backward[i+1]] = curr\n                counter[curr] += 1\n            else:\n                curr = forward[i-1] + 1\n                counter[forward[i-1]] -= 1\n                if counter[forward[i-1]] == 0:\n                    del counter[forward[i-1]]\n                forward[i] = curr\n                backward[i-forward[i-1]] = curr\n                counter[curr] += 1\n            \n            if counter[m] >= 1:\n                    res = step\n            \n            step += 1\n        \n        return res\n", "from collections import defaultdict\nfrom typing import *\nfrom bisect import *\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        Start = dict()\n        End = dict()\n        NumWithSize = defaultdict(int)\n        for i in range(n):\n            NumWithSize[0] += 1\n        step = 0\n        res = -1\n        for x in arr:\n            step += 1\n            x -= 1\n            NumWithSize[0] -= 1\n            if (x-1) in End:\n                leftSize = End[x-1] - Start[x-1] + 1\n                NumWithSize[leftSize] -= 1\n                if (x+1) in End:\n                    rightSize = End[x+1] - Start[x+1] + 1\n                    NumWithSize[rightSize] -= 1\n                    NumWithSize[leftSize + rightSize + 1] += 1\n                    Start[End[x+1]] = Start[x-1]\n                    End[Start[x-1]] = End[x+1]\n                else:\n                    # only merge with left\n                    NumWithSize[leftSize + 1] += 1\n                    Start[x] = Start[x-1]\n                    End[x] = x\n                    End[Start[x-1]] = x\n            elif (x+1) in End:\n                # only merge with right\n                rightSize = End[x+1] - Start[x+1] + 1\n                NumWithSize[rightSize] -= 1\n                NumWithSize[rightSize + 1] += 1\n                Start[x] = x\n                End[x] = End[x+1]\n                Start[End[x+1]] = x\n            else:\n                # make only 1 block siez\n                NumWithSize[1] += 1\n                Start[x] = End[x] = x\n            if NumWithSize[m] > 0:\n                res = step\n        return res\n\nprint((Solution().findLatestStep(arr = [3,5,1,2,4], m = 1))) # 4\nprint((Solution().findLatestStep(arr = [3,1,5,4,2], m = 2))) # -1\nprint((Solution().findLatestStep(arr = [1], m = 1))) # 1\nprint((Solution().findLatestStep(arr = [2,1], m = 2))) # 2\n", "class Solution:\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        barr = [None for i in range(n + 1)]\n        comp_l = defaultdict(lambda: 0)\n        \n        last = -1\n        for i, num in enumerate(arr):\n            low, high = num, num\n            \n            if num > 1 and barr[num - 1] is not None:\n                llow, lhigh = barr[num - 1]\n                comp_l[lhigh - llow + 1] -= 1\n                low = llow\n                \n            if num < len(barr) - 1 and barr[num + 1] is not None:\n                rlow, rhigh = barr[num + 1]\n                comp_l[rhigh - rlow + 1] -= 1\n                high = rhigh\n            \n            comp_l[high - low + 1] += 1\n            barr[low] = (low, high)\n            barr[high] = (low, high)\n            \n            if comp_l[m] > 0:\n                last = max(last, i+1)\n        return last\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start_dict = {}\n        end_dict = {}\n        m_dict = {}\n        last_step = -2\n        for i, num in enumerate(arr):\n            if num + 1 not in start_dict and num - 1 not in end_dict:\n                start = num\n                end = num\n            if num + 1 in start_dict and num-1 not in end_dict:\n                end = start_dict.pop(num+1)\n                start = num\n                m_dict[end - num].remove(num+1)\n            if num + 1 not in start_dict and num - 1 in end_dict:\n                start = end_dict.pop(num-1)\n                end = num\n                m_dict[num-start].remove(start)\n            if num + 1 in start_dict and num - 1 in end_dict:\n                end = start_dict.pop(num+1)\n                start = end_dict.pop(num-1)\n                m_dict[end-num].remove(num+1)\n                m_dict[num-start].remove(start)\n            start_dict[start] = end\n            end_dict[end] = start\n            m_dict.setdefault(end - start + 1, set()).add(start)\n            if m in m_dict and m_dict[m]:\n                last_step = i\n        return last_step+1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        \n        # my solution ... 1332 ms ... 80 % ... 27.5 MB ... 98 %\n        #  time: O(n)\n        # space: O(n)\n        \n        res = -1\n        e2s = {}  # e2s[5] = 3 \u8868\u793a 3-4-5 \u4f4d\u7f6e\u73b0\u5728\u5747\u4e3a1\u3002\u6b64\u65f6\u5fc5\u6709s2e[3] = 5\n        s2e = {}\n        cnt = {}  # cnt[3] = 8 \u8868\u793a\u6b64\u65f6\u6709 8 \u4e2a '111'\n        for i, v in enumerate(arr):  # i+1 \u662f\u5f53\u524d step\uff0cv\u662f\u5f53\u524dstep\u4ece0\u53d8\u4e3a1\u7684\u4f4d\u7f6e\uff0c\u5176\u4e24\u4fa7\u7684\u7d22\u5f15\u4e3av-1\u548cv+1\n            if v-1 not in e2s and v+1 not in s2e:\n                l, r = v, v\n            elif v-1 not in e2s and v+1 in s2e:\n                l, r = v, s2e[v+1]\n                del s2e[v+1]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            elif v-1 in e2s and v+1 not in s2e:\n                l, r = e2s[v-1], v\n                del e2s[v-1]\n                cnt[v-l] -= 1\n                if not cnt[v-l]:\n                    del cnt[v-l]\n            else:\n                l, r = e2s[v-1], s2e[v+1]  # \u4f4d\u7f6e v \u53d8\u4e3a 1 \u540e\uff0cv \u5de6\u4fa7\u6700\u8fdc 1 \u53ca v \u53f3\u4fa7\u6700\u8fdc 1\n                del e2s[v-1]\n                del s2e[v+1]\n                cnt[v-l] -= 1  # \u66f4\u65b0\u65e7\u7684\u9891\u6b21\n                if not cnt[v-l]:\n                    del cnt[v-l]\n                cnt[r-v] -= 1\n                if not cnt[r-v]:\n                    del cnt[r-v]\n            s2e[l] = r\n            e2s[r] = l\n            cnt[r-l+1] = cnt.get(r-l+1, 0) + 1  # \u589e\u52a0\u65b0\u7684\u9891\u6b21\n            if m in cnt:\n                res = i + 1\n        return res\n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        \n        lengths = [0] * (len(arr) + 2)\n        \n        ans = -1\n        \n        for (step, value) in enumerate(arr):\n            left, right = lengths[value-1], lengths[value+1]\n            \n            if left == m or right == m:\n                ans = step\n            \n            lengths[value - left] = lengths[value + right] = left + right + 1\n            \n        return ans\n        \n        \n#         N = len(arr) + 1\n        \n#         starts = dict()\n#         ends = dict()\n        \n#         num_groups = 0\n#         ans = -1\n        \n#         for (step, i) in enumerate(arr):\n            \n#             cur_range = [i, i]\n#             if i + 1 in starts:\n#                 cur_range[1] = starts[i+1]\n                \n#                 if starts[i+1] - i == m:\n#                     num_groups -= 1\n                \n#                 del starts[i+1]\n                \n#             if i - 1 in ends:\n#                 cur_range[0] = ends[i-1]\n                \n#                 if i - ends[i-1] == m:\n#                     num_groups -= 1\n#                 del ends[i-1]\n            \n#             starts[cur_range[0]] = cur_range[1]\n#             ends[cur_range[1]] = cur_range[0]\n            \n#             if cur_range[1] - cur_range[0] + 1 == m:\n#                 num_groups += 1\n            \n#             if num_groups > 0:\n#                 ans = step + 1\n#         return ans\n            \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m==len(arr): return m\n        \n        border=[0]*(len(arr)+2)\n        ans=-1\n        \n        for i in range(len(arr)):\n            left=right=arr[i]\n            if border[right+1]>0: right=border[right+1]\n            if border[left-1]>0: left=border[left-1]\n            border[left], border[right] = right, left\n            if (right-arr[i]==m) or (arr[i]-left ==m): ans=i\n        \n        return ans\n", "from collections import defaultdict\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        s = [0 for _ in arr]\n        ans = -1\n        for i, n in enumerate(arr):\n            num = n-1\n            left = s[num-1] if num > 0 else 0\n            right = s[num+1] if num < len(s)-1 else 0\n            total = left + right + 1\n            s[num-left] = total\n            s[num+right] = total\n            if left == m or right == m:\n                ans = i\n        if m == max(s):\n            return i+1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length_at_index = [0]*(len(arr)+2)\n        count_of_length = [0]*(len(arr)+1)\n        res = -1\n        for i,index in enumerate(arr):\n            left_length = length_at_index[index-1]\n            right_length = length_at_index[index+1]\n\n            new_length = left_length + right_length + 1\n            length_at_index[index] = new_length\n            length_at_index[index-left_length] = new_length\n            length_at_index[index+right_length] = new_length\n\n            count_of_length[left_length] -= 1\n            count_of_length[right_length] -= 1\n            count_of_length[new_length] += 1\n\n            if count_of_length[m] > 0:res = i+1\n        return res", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res\n", "import bisect \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        last = N - 1\n        groupStartWith = {0: last}\n        groupEndWith = {last: 0}\n        groupLength = {N: 1}\n        def decreaseGroupLength(oldlen):\n            if oldlen >= m:\n                oldlencount = groupLength.pop(oldlen)\n                if oldlencount > 1 :\n                    groupLength[oldlen] = oldlencount - 1\n                    \n        def increaseGroupLength(newlen):\n            if newlen >= m:\n                if newlen in groupLength:\n                    groupLength[newlen]  = groupLength[newlen] + 1\n                else :\n                    groupLength[newlen] = 1\n             \n        def getGroup(num):\n            if num  in groupStartWith: \n                right = groupStartWith.pop(num) \n                groupEndWith.pop(right)\n                return (num, right)\n            elif num in groupEndWith:\n                left = groupEndWith.pop(num)\n                groupStartWith.pop(left)\n                return (left, num)\n            \n            starts = sorted(list(groupStartWith.keys()))\n            index = bisect.bisect_left(starts, num) - 1\n            if index < 0:\n                return ()\n            left = starts[index]\n            right = groupStartWith[left]\n            if left <= num and num <= right:\n                groupStartWith.pop(left)\n                groupEndWith.pop(right)\n                return (left, right)\n            return ()\n                \n        def updateGroup(left, right): \n            if right - left + 1 >= m:\n                groupStartWith[left] = right\n                groupEndWith[right] = left\n            \n            \n        def removeNumber(num):\n            group = getGroup(num)\n            if len(group) == 0:\n                return ()\n            \n            left , right = group\n            res = ()\n            oldlen = right - left + 1\n            if oldlen < m:\n                return ()\n            decreaseGroupLength(oldlen)\n            \n            if num == left:\n                newlen = oldlen - 1\n                updateGroup(left + 1, right)\n                increaseGroupLength(newlen)\n                return (newlen,)\n            \n            if num == right:\n                newlen = oldlen - 1\n                updateGroup(left, right - 1)\n                increaseGroupLength(newlen)\n                return (newlen,)\n            \n            newLeftLen = num - left\n            newRightLen = right - num\n            \n            if newLeftLen >= m: \n                updateGroup(left, num - 1)\n                increaseGroupLength(newLeftLen)\n                res = res + (newLeftLen,)\n            \n            if newRightLen >= m:\n                updateGroup(num + 1, right)\n                increaseGroupLength(newRightLen)\n                res = res + (newRightLen,)\n             \n            return res\n\n        if m == N:\n            return m\n        \n        for i in range(N, 0 , -1): \n            #print(groupStartWith, i - 1, arr[i-1] - 1)\n            if m in removeNumber(arr[i-1] - 1): \n                #print(groupStartWith, i - 1, arr[i-1] - 1, '=')\n                return i - 1 \n            #print(groupStartWith, i - 1, arr[i-1] - 1, '-') \n                \n        return - 1 \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m>n: return -1\n        if m==n: return n\n        helper = [0]*(n+1)\n        res = -1\n        \n        for k, i in enumerate(arr):\n            helper[i] = l = r = i\n            if l>1 and helper[l-1]:\n                l = helper[l-1]\n                if r - l == m:\n                    res = k\n                helper[l], helper[r] = r, l\n            if r<n and helper[r+1]:\n                r = helper[r+1]\n                if r - i == m:\n                    res = k\n                helper[l], helper[r] = r, l\n                \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bits = [0]*(len(arr)+2)\n        answ = -1\n        num_groups = 0\n        for step, idx in enumerate(arr):\n            before = bits[idx-1]\n            after = bits[idx+1]\n            group = 1\n            if before + after == 0:\n                bits[idx] = 1\n            elif before == 0:\n                bits[idx] = after + 1\n                bits[idx+1] = 0\n                bits[idx+after] = after + 1\n                group = after + 1\n            elif after == 0:\n                bits[idx] = before + 1\n                bits[idx-1] = 0\n                bits[idx - before] = before + 1\n                group = before + 1\n            else:\n                bits[idx-1], bits[idx+1] = 0, 0\n                bits[idx-before], bits[idx+after] = before + after + 1, before + after + 1\n                group = before + after + 1\n            \n            if group == m:\n                num_groups += 1\n            if before == m:\n                num_groups -= 1\n            if after == m:\n                num_groups -= 1\n            \n            if num_groups > 0:\n                answ = step + 1\n                \n            \n        return answ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        groups = [(0, len(arr)+1)] # both start and end are exclusive\n        for i in range(len(arr)-1, -1, -1):\n            temp = []\n            for start, end in groups:\n                if start <= arr[i] < end:\n                    if end - arr[i] - 1 == m or arr[i] - 1 - start == m:\n                        return i\n                    if end - 1 - arr[i] > m:\n                        temp.append((arr[i], end))\n                    if arr[i] - 1 - start > m:\n                        temp.append((start, arr[i]))\n                elif end - 1 - start >= m:\n                    temp.append((start, end))\n            groups = temp\n        return -1\n    \n# [3,5,1,2,4]\n# 1\n# [3,5,1,2,4]\n# 2\n# [3,5,1,2,4]\n# 3\n# [1]\n# 1\n# [2,1]\n# 2\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        startwith = dict()\n        endwith = dict()\n        length = dict()\n        ans = -1\n        for i in range(len(arr)):\n            if arr[i]+1 in startwith:\n                if arr[i]-1 in endwith:\n                    new_start = endwith[arr[i]-1]\n                    new_end = startwith[arr[i]+1]\n                    old_start = endwith[arr[i]-1]\n                    old_end = arr[i]-1\n                    del endwith[arr[i]-1]\n                    length[old_end - old_start + 1] -= 1\n                else:\n                    new_start = arr[i]\n                    new_end = startwith[arr[i]+1]\n                old_start = arr[i]+1\n                old_end = startwith[arr[i]+1]\n                del startwith[arr[i]+1]\n                length[old_end - old_start + 1] -= 1 \n            elif arr[i]-1 in endwith:\n                new_start = endwith[arr[i]-1]\n                new_end = arr[i]\n                old_start = endwith[arr[i]-1]\n                old_end = arr[i]-1             \n                length[old_end - old_start + 1] -= 1\n                del endwith[arr[i]-1]\n            else:\n                new_start = arr[i]\n                new_end = arr[i]\n            length[new_end - new_start + 1] = length.get(new_end - new_start + 1, 0) + 1\n            startwith[new_start] = new_end\n            endwith[new_end] = new_start\n            if m in length and length[m] > 0: ans = i+1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        last_found = -1\n        #(start,end,size)\n        hash_size = {}\n        hash_chunks = {}\n        for i in range (len(arr)):\n            num = arr[i] - 1\n            if num == 0:\n                if (num + 1) not in hash_chunks:\n                    hash_chunks[num] = (num,num,1)\n                    hash_size[1] = 1 + hash_size.get(1,0)\n                else:\n                    (start,end,size) = hash_chunks[num + 1]\n                    new_start = num\n                    end = end\n                    new_size = size + 1\n                    hash_chunks[end] = (new_start,end,new_size)\n                    hash_chunks[num] = (new_start,end,new_size)\n                    hash_size[size] -= 1\n                    hash_size[new_size] = 1 + hash_size.get(new_size,0)\n            elif (num == len(arr) - 1):\n                if (num - 1) not in hash_chunks:\n                    hash_chunks[num] = (num,num,1)\n                    hash_size[1] = 1 + hash_size.get(1,0)\n                else:\n                    (start,end,size) = hash_chunks[num - 1]\n                    start = start\n                    new_end = num\n                    new_size = size + 1\n                    hash_chunks[start] = (start,new_end,new_size)\n                    hash_chunks[num] = (start,new_end,new_size)\n                    hash_size[size] -= 1\n                    hash_size[new_size] = 1 + hash_size.get(new_size,0)\n            else:\n                if ((num + 1) in hash_chunks) and ((num - 1) in hash_chunks):\n                    (f_start,f_end,f_size) = hash_chunks[num - 1]\n                    (b_start,b_end,b_size) = hash_chunks[num + 1]\n                    new_front = f_start\n                    new_end = b_end\n                    new_size = f_size + b_size + 1\n                    hash_chunks[f_start] = (new_front,new_end,new_size)\n                    hash_chunks[b_end] = (new_front,new_end,new_size)\n                    hash_size[f_size] -= 1\n                    hash_size[b_size] -= 1\n                    hash_size[new_size] = 1 + hash_size.get(new_size,0)\n                elif (num + 1) in hash_chunks:\n                    (start,end,size) = hash_chunks[num + 1]\n                    new_start = num\n                    end = end\n                    new_size = size + 1\n                    hash_chunks[end] = (new_start,end,new_size)\n                    hash_chunks[num] = (new_start,end,new_size)\n                    hash_size[size] -= 1\n                    hash_size[new_size] = 1 + hash_size.get(new_size,0)\n                elif (num - 1) in hash_chunks:\n                    (start,end,size) = hash_chunks[num - 1]\n                    start = start\n                    new_end = num\n                    new_size = size + 1\n                    hash_chunks[start] = (start,new_end,new_size)\n                    hash_chunks[num] = (start,new_end,new_size)\n                    hash_size[size] -= 1\n                    hash_size[new_size] = 1 + hash_size.get(new_size,0)\n                else:\n                    hash_chunks[num] = (num,num,1)\n                    hash_size[1] = 1 + hash_size.get(1,0)\n            if (m in hash_size) and (hash_size[m] > 0):\n                last_found = i + 1\n        return last_found\n\n    \n                    \n                    \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        left = [-1] * (n+2)\n        right = [-1] * (n+2)\n        \n        ans = -1\n        cnt = collections.Counter()\n        for i, v in enumerate(arr):\n            left[v] = right[v] = v\n            l = r = v\n            if left[v-1] != -1:\n                l = left[v-1]\n                cnt[v - l] -= 1\n            if right[v+1] != -1:\n                r = right[v+1]\n                cnt[r - v] -= 1\n            right[l] = r\n            left[r] = l\n            cnt[r - l + 1] += 1\n            if cnt[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, A, m):\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def find(x):\n            while x!=par[x]:\n                par[x] = par[par[x]]\n                x = par[x]\n            return x\n        \n        def union(x,y):\n            nonlocal count\n            \n            px, py = find(x), find(y)\n            if px==py:  return\n            if size[px]==m: count-=1\n            if size[py]==m: count-=1\n                \n            if size[px] > size[py]:    \n                par[py] = par[px]\n                size[px] += size[py]\n                if size[px]==m: count+=1\n                \n            else:\n                par[px] = par[py]\n                size[py] += size[px]\n                if size[py]==m: count+=1\n                    \n        count = 0\n        n = len(arr)+2\n        par = list(range(n))\n        size = [0]*n\n        res = -1\n        for i, el in enumerate(arr, 1):\n            size[el] = 1\n            if m==1:    count+=1\n            if size[el-1]:   union(el, el-1)\n            if size[el+1]:   union(el, el+1)\n            if count>0:    res = i\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ret = -1\n        n = len(arr)\n        length = [0]*(n+2)\n        count = [0]*(n+1)\n        \n        for i in range(n):\n            a = arr[i]\n            left = length[a-1]\n            right = length[a+1]\n            length[a] = length[a-left] = length[a+right] = left+right+1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m] > 0:\n                ret = i+1\n        return ret", "\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n: return m\n        length = [0] *(n + 2)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a-1], length[a+1]\n            if left == m or right == m:\n                res = i\n            length[a-left] = length[a+right] = left + right + 1\n        return res\n                \n                    \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        a,b,s,t=[0]*(len(arr)+2),[0]*(len(arr)+1),-1,0\n        for p,i in enumerate(arr,1):\n            j,k=a[i-1],a[i+1]\n            a[i]=a[i-j]=a[i+k]=j+k+1\n            if a[i]==m: t+=1\n            if j==m: t-=1\n            if k==m: t-=1\n            if t: s=p\n        return s", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        size = collections.Counter()\n        comp = [0 for _ in range(len(arr) + 2)]\n        for i, n in enumerate(arr):\n            left, right = comp[n - 1], comp[n + 1]\n            comp[n] = comp[n - left] = comp[n + right] = left + right + 1\n            size[left] -= 1\n            size[right] -= 1\n            size[comp[n]] += 1\n            if size[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        lengthStartingWith = {}\n        lengthEndingWith = {}\n        relevantStartingIndices = {}\n        \n        bestIndex = -1\n        for index,j in enumerate(arr):\n            print(index)\n            i = j-1\n            leftNeighbor = i-1\n            rightNeighbor = i+1\n            if(leftNeighbor in lengthEndingWith and rightNeighbor in lengthStartingWith):\n                leftLength = lengthEndingWith[leftNeighbor]\n                rightLength = lengthStartingWith[rightNeighbor]\n                lengthEndingWith.pop(leftNeighbor)\n                lengthStartingWith.pop(rightNeighbor)\n                if(rightNeighbor in relevantStartingIndices):\n                    relevantStartingIndices.pop(rightNeighbor)\n                lengthStartingWith[leftNeighbor-leftLength+1] = leftLength + rightLength + 1\n                if(leftLength + rightLength + 1 == m):\n                    relevantStartingIndices[leftNeighbor-leftLength+1] = True\n                else:\n                    if(leftNeighbor-leftLength+1 in relevantStartingIndices):\n                        relevantStartingIndices.pop(leftNeighbor-leftLength+1)\n                lengthEndingWith[rightNeighbor+rightLength-1] = leftLength + rightLength + 1\n                \n            \n            elif(leftNeighbor in lengthEndingWith):\n                leftLength = lengthEndingWith[leftNeighbor]\n                lengthEndingWith.pop(leftNeighbor)\n                lengthStartingWith[leftNeighbor-leftLength+1] = leftLength + 1\n                lengthEndingWith[i] = leftLength + 1\n                \n                if(leftLength + 1 == m):\n                    relevantStartingIndices[leftNeighbor-leftLength+1] = True\n                else:\n                    if(leftNeighbor-leftLength+1 in relevantStartingIndices):\n                        relevantStartingIndices.pop(leftNeighbor-leftLength+1)\n                \n            elif(rightNeighbor in lengthStartingWith):\n                rightLength = lengthStartingWith[rightNeighbor]\n                lengthStartingWith.pop(rightNeighbor)\n                lengthEndingWith[rightNeighbor+rightLength-1] = rightLength + 1\n                lengthStartingWith[i] = rightLength + 1\n                \n                if(rightNeighbor in relevantStartingIndices):\n                    relevantStartingIndices.pop(rightNeighbor)\n                if(rightLength + 1 == m):\n                    relevantStartingIndices[i] = True\n                else:\n                    if(i in relevantStartingIndices):\n                        relevantStartingIndices.pop(i)\n                \n            \n            else:\n                #print(\\\"here4\\\")\n                #print(i)\n                lengthEndingWith[i] = 1\n                lengthStartingWith[i] = 1\n                \n                if(m == 1):\n                    relevantStartingIndices[i] = True\n                else:\n                    if(i in relevantStartingIndices):\n                        relevantStartingIndices.pop(i)\n            \n            if(len(relevantStartingIndices) > 0):\n                bestIndex = index + 1\n        return bestIndex\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr): return m\n        length = [0] * (len(arr) + 2)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ta = [-1] * n\n        sg = [-1] * n\n        eg = [-1] * n\n        g = {}\n        step = 1\n        ans = -1\n        gc = {}\n        for v in arr:\n            idx = v - 1\n            wl = False\n            wr = False\n            if idx > 0 and eg[idx-1] > -1:\n                sgi = eg[idx-1]\n                ngl = g[sgi]\n                sg[sgi] = idx\n                eg[idx] = sgi\n                g[sgi] += 1\n                gc[ngl] -= 1\n                if ngl+1 not in gc:\n                    gc[ngl+1] = 0\n                gc[ngl+1] += 1\n                wl = True\n            if idx < n-1 and sg[idx+1] > -1:\n                sgi = idx+1\n                egi = sg[sgi]\n                ngl = g[sgi]\n                eg[egi] = idx\n                sg[idx] = egi\n                g[idx] = g[sgi]+1\n                l = g.pop(sgi)\n                gc[ngl] -= 1\n                if ngl+1 not in gc:\n                    gc[ngl+1] = 0\n                gc[ngl+1] += 1\n                wr = True\n            if not wl and not wr:\n                sg[idx] = idx\n                eg[idx] = idx\n                g[idx] = 1\n                if 1 not in gc:\n                    gc[1] = 0\n                gc[1] += 1\n            elif wl and wr:\n                sgi = eg[idx]\n                ngl = g[sgi]\n                ngr = g[idx]\n                l = g.pop(idx)\n                gc[ngl] -= 1\n                gc[ngr] -= 1\n                if ngl+ngr-1 not in gc:\n                    gc[ngl+ngr-1] = 0\n                gc[ngl+ngr-1] += 1\n                g[sgi] = g[sgi] + l - 1\n                egi = sg[idx]\n                eg[egi] = sgi\n                sg[sgi] = egi\n            ta[idx] = v\n\n            if m in gc and gc[m] > 0:\n                ans = step\n\n            step += 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        d = dict() # max length of 1\u2018s at index i\n        counter = collections.Counter() # count of occurence of len\n        ans = -1\n        for i, num in enumerate(arr, 1):\n            left = d.get(num-1, 0)\n            right = d.get(num+1, 0)\n            total = left+right+1\n            d[num] = total\n            d[num-left] = total\n            d[num+right] = total\n            counter[total] += 1\n            counter[left] -= 1\n            counter[right] -= 1\n            if counter[m]:\n                ans = i\n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        comps = [0 for _ in range(len(arr) + 2)]\n        size = collections.Counter()\n        for i, a in enumerate(arr):\n            l, r = comps[a - 1], comps[a + 1]\n            comps[a] = comps[a - l] = comps[a + r] = l + r + 1\n            size[l] -= 1\n            size[r] -= 1\n            size[comps[a]] += 1\n            if size[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ta = [-1] * n\n        sg = [-1] * n\n        eg = [-1] * n\n        g = {}\n        ans = -1\n        gc = {}\n        for step, v in enumerate(arr):\n            idx = v - 1\n            wl = False\n            wr = False\n            if idx > 0 and eg[idx-1] > -1:\n                sgi = eg[idx-1]\n                ngl = g[sgi]\n                sg[sgi] = idx\n                eg[idx] = sgi\n                g[sgi] += 1\n                gc[ngl] -= 1\n                if ngl+1 not in gc:\n                    gc[ngl+1] = 0\n                gc[ngl+1] += 1\n                wl = True\n            if idx < n-1 and sg[idx+1] > -1:\n                sgi = idx+1\n                egi = sg[sgi]\n                ngl = g[sgi]\n                eg[egi] = idx\n                sg[idx] = egi\n                g[idx] = g[sgi]+1\n                l = g.pop(sgi)\n                gc[ngl] -= 1\n                if ngl+1 not in gc:\n                    gc[ngl+1] = 0\n                gc[ngl+1] += 1\n                wr = True\n            if not wl and not wr:\n                sg[idx] = idx\n                eg[idx] = idx\n                g[idx] = 1\n                if 1 not in gc:\n                    gc[1] = 0\n                gc[1] += 1\n            elif wl and wr:\n                sgi = eg[idx]\n                ngl = g[sgi]\n                ngr = g[idx]\n                l = g.pop(idx)\n                gc[ngl] -= 1\n                gc[ngr] -= 1\n                if ngl+ngr-1 not in gc:\n                    gc[ngl+ngr-1] = 0\n                gc[ngl+ngr-1] += 1\n                g[sgi] = g[sgi] + l - 1\n                egi = sg[idx]\n                eg[egi] = sgi\n                sg[sgi] = egi\n            ta[idx] = v\n\n            if m in gc and gc[m] > 0:\n                ans = step+1\n\n            step += 1\n        return ans", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        index2len = defaultdict(int)\n        cnt = Counter()\n        last = -1\n        for i, p in enumerate(a):    \n            left_len, right_len = index2len[p-1], index2len[p+1]\n            new_len = left_len + 1 + right_len\n            index2len[p-left_len] = index2len[p+right_len] = new_len\n            cnt[left_len] -= 1\n            cnt[right_len] -= 1                \n            cnt[new_len] += 1 \n            if cnt[m] > 0: last = i + 1            \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        start = {}\n        end = {}\n        groups = collections.defaultdict(set)\n        ans = -1\n        for idx,a in enumerate(arr):\n            new_start,new_end = a,a\n            if a + 1 in start:\n                new_end = start[a + 1]\n                del start[a + 1]\n                groups[new_end - (a + 1 )+ 1].remove((a+1,new_end))\n            if a - 1 in end:\n                new_start = end[a-1]\n                del end[a-1]\n                groups[a-1 - new_start + 1].remove((new_start,a-1))\n            start[new_start] = new_end\n            end[new_end] = new_start\n            groups[new_end - new_start + 1].add((new_start,new_end))\n            if len(groups[m])>0:ans = idx+1\n        return ans\n                \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m==n: return m\n        res = -1\n        length = [0 for _ in range(n+2)]\n        \n        for i,val in enumerate(arr):\n            left, right = length[val-1], length[val+1]\n            if left==m or right==m:\n                res = i\n            length[val-left] = length[val+right] = left+right+1\n        return res   ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dp = [0] * (len(arr) + 2)\n        g = collections.Counter()\n        ans = -1\n        for i in range(len(arr)):\n            l, r = dp[arr[i] - 1], dp[arr[i] + 1]\n            dp[arr[i]] = l + r + 1\n            dp[arr[i] - l] = dp[arr[i] + r] = l + r + 1\n            g[l] -= 1\n            g[r] -= 1\n            g[dp[arr[i]]] += 1\n            if g[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == 1 : return 1\n        dic, groups = {i:0 for i in range(1, n+1)}, {i:0 for i in range(1, n+1)}\n        right = {i:0 for i in range(1, n+1)}\n        laststep = -1\n        for idx, i in enumerate(arr):\n            # single 1\n            if (i == 1 or dic[i-1] == 0) and (i == n or dic[i+1] == 0):\n                groups[1] += 1\n                dic[i] = i\n                right[i] = i\n            # add 1 to right\n            elif (i == n or dic[i+1] == 0) and (i > 0 and dic[i-1] > 0):\n                leftmost = dic[i-1]\n                dic[i] = leftmost\n                right[leftmost] = i\n                right[i] = i\n                groups[i-leftmost] -= 1\n                groups[i-leftmost+1] += 1\n            # add 1 to left\n            elif (i == 1 or dic[i-1] == 0) and (i < n and dic[i+1] > 0):\n                rightmost = right[i+1]\n                dic[rightmost] = i\n                dic[i] = i\n                right[i] = rightmost\n                groups[rightmost - i] -= 1\n                groups[rightmost - i + 1] += 1\n            else:\n                leftmost = dic[i-1]\n                rightmost = right[i+1]\n                right[leftmost] = rightmost\n                dic[rightmost] = leftmost\n                groups[rightmost - i] -= 1\n                groups[i - leftmost] -= 1\n                groups[rightmost-leftmost+1] += 1\n\n            if groups[m] > 0:\n                laststep = idx+1\n            # print(\\\"step:\\\", idx+1, \\\":\\\",groups)\n        return laststep", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        '''\n        for arr[k:k+m], it forms m-group if max(time[x] for x in range(k,k+m) < min(time[k-1],time[k+m]),  )\n        cand(k)=\n        '''\n        turnedOnTime={}\n        for i,x in enumerate(arr):\n            turnedOnTime[x]=i+1\n        n=len(arr)\n        q=deque()\n        ans=-1\n        for i in range(1,n+1):\n            while q and q[0][0]<i-m+1: q.popleft()\n            while q and q[-1][1]<=turnedOnTime.get(i,n+1): q.pop()\n            q.append((i,turnedOnTime.get(i,n+1)))\n            if i>=m:\n                vanishTime=min(turnedOnTime.get(i+1,n+1),turnedOnTime.get(i-m,n+1))\n                cur=-1 if q[0][1]>=vanishTime else (vanishTime-1)\n                ans=max(ans,cur)\n        return ans\n", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        n = len(a)\n        l = [0] * (n + 2)\n        cnt = [0] * (n + 2)\n        ans = -1\n        for i, x in enumerate(a):\n            left, right = l[x - 1], l[x + 1]\n            l[x] = l[x - left] = l[x + right] = left + right + 1\n            cnt[left] -= 1\n            cnt[right] -= 1\n            cnt[l[x]] += 1\n            if cnt[m]:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr_len = len(arr)\n        d = {i: [i-1, 0, i+1] for i in range(arr_len + 1)}  # d[i] = (previous i, length ones start i)\n        last_round = -1  # last round where we had string of length m\n        count_m = 0  # count of current number of such strings\n\n        for cur_round, n in enumerate(arr):\n            prev_idx, this_len, next_idx = d[n]\n            if this_len == m:\n                count_m -= 1\n            if d[prev_idx][1] == m:\n                count_m -= 1\n            new_len = d[prev_idx][1] + this_len + 1\n            d[prev_idx][1] = new_len\n            d[prev_idx][2] = next_idx\n            \n            if next_idx <= arr_len:  # only set if still in rang\n                d[next_idx][0] = prev_idx\n                \n            d[n] = None   # so generate error if reuse\n            \n            if new_len == m:\n                count_m += 1\n            if count_m > 0:\n                last_round = cur_round + 1\n        return last_round", "\n\nclass Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        \n        n = len(a)\n        \n        sz = {}\n        cnt = Counter()\n        \n        ret = -1\n        \n        for i,x in zip(list(range(1, n+1)), a):\n            \n            # merge\n            left = sz[x-1] if x-1 in sz else 0\n            right = sz[x+1] if x+1 in sz else 0\n            tot = left + right + 1\n            \n            sz[x-left] = tot\n            sz[x+right] = tot\n            \n            cnt[left] -= 1\n            cnt[right] -= 1\n            cnt[tot] += 1\n            \n            if cnt[m]:\n                ret = i\n        \n        return ret\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        from collections import Counter\n        n = len(arr)\n        mem = [0] * n\n        counter = Counter()\n        res = -1\n        for j, v in enumerate(arr):\n            i = v - 1\n            mem[i] = 1\n            # 0 1 2 3 4 5\n            # 0 0 1 1 1 0\n            l = mem[i - 1] if i - 1 >= 0 else 0\n            r = mem[i + 1] if i + 1 <  n else 0\n            counter[l] -= 1\n            counter[r] -= 1\n            cur = l + r + 1\n            mem[i - l], mem[i + r] = cur, cur\n            counter[cur] += 1\n            # (j, v, cur, mem).p()\n            if counter[m] > 0:\n                res = j + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parent = [0] * (len(arr) + 2)\n        size = [1] * (len(arr) + 1)\n        \n        count = collections.defaultdict(int)\n        \n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                parent[px] = py\n                count[size[py]] -= 1\n                count[size[px]] -= 1\n                size[py] += size[px]\n                count[size[py]] += 1\n        \n        answer = -1\n        for i, value in enumerate(arr):\n            parent[value] = value\n            count[1] += 1\n            \n            if parent[value - 1]:\n                union(value - 1, value)\n            if parent[value + 1]:\n                union(value, value + 1)\n            \n            if count[m]:\n                answer = i + 1\n        \n        return answer", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        gLefts = dict()\n        gRights = dict()\n        gSizeCounter = collections.Counter()\n        result = -1\n        for step, x in enumerate(arr, 1):\n            try:\n                rGroup = gLefts[x + 1]\n            except KeyError:\n                rGroup = None\n            try:\n                lGroup = gRights[x - 1]\n            except KeyError:\n                lGroup = None\n                \n            if lGroup is not None and rGroup is not None:\n                lSize = lGroup[2]\n                rSize = rGroup[2]\n                del gLefts[rGroup[0]]\n                del gRights[lGroup[1]]\n                \n                gSizeCounter[lSize] -= 1\n                    \n                gSizeCounter[rSize] -= 1\n                    \n                lSize += 1 + rSize\n                gSizeCounter[lSize] += 1\n                lGroup[2] = lSize\n                lGroup[1] = rGroup[1]\n                gRights[lGroup[1]] = lGroup\n            elif lGroup is not None:\n                lSize = lGroup[2]\n                \n                gSizeCounter[lSize] -= 1\n                    \n                lSize += 1\n                gSizeCounter[lSize] += 1\n                lGroup[2] = lSize\n                del gRights[lGroup[1]]\n                lGroup[1] = x\n                gRights[x] = lGroup\n            elif rGroup is not None:\n                rSize = rGroup[2]\n                \n\n                gSizeCounter[rSize] -= 1\n                    \n                rSize += 1\n                gSizeCounter[rSize] += 1\n                rGroup[2] = rSize\n                del gLefts[rGroup[0]]\n                rGroup[0] = x\n                gLefts[x] = rGroup\n            else:\n                gSizeCounter[1] += 1\n                gLefts[x] = gRights[x] = [x, x, 1]\n\n            if gSizeCounter[m] > 0:\n                result = step\n                \n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        if m == n: return m\n        cnts = [0] * (n + 2)\n        for i, x in enumerate(arr):\n            cl, cr = cnts[x - 1], cnts[x + 1]\n            if cl == m or cr == m: ans = i\n            cnts[x - cl] = cnts[x + cr] = cl + cr + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        end = {}\n        n = len(arr)\n        count = collections.defaultdict(int)\n        string = [0]*(n+1)\n        ans = -1\n        for i in range(len(arr)):\n            start = arr[i]\n            string[start] = 1\n            left = start\n            right = start\n            flag1, flag2 = False, False\n            if arr[i]-1 > 0 and string[arr[i]-1] == 1:\n                l, r = end[arr[i]-1]\n                left = l\n                count[r-l+1] -= 1\n                flag1 = True\n            if arr[i]+1 <= n and string[arr[i]+1] == 1:\n                l2, r2 = end[arr[i]+1]\n                right = r2\n                count[r2-l2+1] -= 1\n                flag2 = True\n            end[arr[i]] = (left, right)\n            if flag1:\n                end[l] = (l, right)\n            if flag2:\n                end[r2] = (left, r2)\n\n            count[right - left + 1] += 1\n            # print(i, right, left, count, end)\n            if count[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        m_cnt = 0\n        parent = [i for i in range(N)]\n        cnt = [1]*N\n        mark = [0]*N\n        \n        def find(i):\n            if parent[i]==i:\n                return i\n            else:\n                parent[i] = find(parent[i])\n                return parent[i]\n            \n        def union(i,j,m_cnt):\n            x = find(i)\n            y = find(j)\n            if cnt[x] == m:\n                m_cnt -= 1\n            if cnt[y] == m:\n                m_cnt -= 1\n            if cnt[x]+cnt[y] == m:\n                m_cnt += 1\n            if x<y:\n                parent[y] = x\n                cnt[x] += cnt[y]\n            else:\n                parent[x] = y\n                cnt[y] += cnt[x]\n            \n            return m_cnt\n        \n        ans = -1\n        \n        \n        \n        for i,x in enumerate(arr):\n            mark[x-1]=1\n            l = False\n            r = False\n            \n            if m==1:\n                m_cnt+=1\n            \n            if x>1 and mark[x-2]==1:\n                m_cnt = union(x-1,x-2,m_cnt)\n            else:\n                l =True\n            if x<N and mark[x]==1:\n                m_cnt = union(x-1,x,m_cnt)\n            else:\n                r = True\n                \n            \n            \n            if m_cnt>0:\n                ans = i+1\n                \n            #print(m_cnt)\n        return ans\n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        lens = defaultdict(int) #len of union, count\n        \n        unions = {} #start:end, or vice versa\n        \n        latest = -1\n        \n        for step, i in enumerate(arr):\n            start = unions.pop(i-1, i)\n            end = unions.pop(i+1, i)\n            \n            unions[start] = end\n            unions[end] = start\n            \n            left_size = i - start\n            right_size = end - i\n            \n            lens[left_size] -= 1\n            lens[right_size] -= 1\n            lens[left_size + right_size + 1] += 1\n            \n            if lens[m]:\n                latest = step + 1\n        \n        return latest\n            \n        \n        # 1 0 1 0 1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res, n = -1, len(arr)\n        # length of group\n        length = [0] * (n + 2)\n        # count of length\n        count = [n] + [0] * n\n        \n        for i, v in enumerate(arr):\n            left, right = length[v - 1], length[v + 1]\n            length[v] = length[v - left] = length[v + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[v]] += 1\n            if count[m]:\n                res = i + 1        \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        length = [0] * (len(arr) + 2)\n        res = -1\n        \n        for i, pos in enumerate(arr):\n            left, right = length[pos - 1], length[pos + 1]\n            if left == m or right == m:\n                res = i\n            length[pos - left], length[pos + right] = left + right + 1, left + right + 1\n            \n        return res", "class Solution:\n    def findLatestStep(self, A, m):\n        if m == len(A): \n            return m\n        \n        length = [0] * (len(A) + 2)\n        res = -1\n        \n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) ==m:\n            return m\n        n = len(arr)\n        max_length = [0]*(n+2)\n        result = -1\n        for step, i in enumerate(arr):\n            left, right = max_length[i-1],  max_length[i+1]\n            if left == m or right == m:\n                result = step \n            \n            max_length[i-left] = max_length[i+right] = left + right + 1\n        \n        return result\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        def helper(start, end, curStep):\n            if curStep == 1: return curStep if m == 1 else -1\n            \n            if end - start + 1 < m: return -1\n            \n            elif end - start + 1 == m: return curStep\n            \n            else:    \n                idx = arr[curStep - 1]\n\n                if idx < start or idx > end: return helper(start, end, curStep - 1)\n\n                else: return max(helper(start, idx - 1, curStep - 1), helper(idx + 1, end, curStep - 1))\n                \n        return helper(1, len(arr), len(arr))", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        length = [0] * (len(arr) + 2)\n        cnt = [0] * (len(arr) + 1)\n        res = -1\n        for idx, i in enumerate(arr):\n            l = length[i - 1]\n            r = length[i + 1]\n            length[i] = length[i - l] = length[i + r] = l + r + 1\n            cnt[l] -= 1\n            cnt[r] -= 1\n            cnt[length[i]] += 1\n            if cnt[m]:\n                res = idx + 1\n        return res", "import collections\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:        \n        arr = [0] + arr + [0]\n        N = len(arr)\n        left  = [0]*N\n        right = [0]*N\n        sizes = collections.Counter()\n        ans = 0\n        for i in range(1, N-1):            \n            l = left[arr[i]-1]\n            r = right[arr[i]+1]\n           \n            sizes[l] -= 1\n           \n            sizes[r] -= 1\n            sizes[l + r + 1] += 1\n            left[arr[i] + 1 + r - 1]  = l + r + 1\n            right[arr[i] - 1 - l + 1] = l + r + 1\n            if sizes[m] >= 1:\n                ans = i   \n                \n        return  ans if ans >= 1 else -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        group_size = [0 for _ in range(len(arr)+1)] \n        parent_idx = [-1 for _ in range(len(arr)+1)] # same for self leading, 0 for not init\n        \n        res = -1\n        num_same = 0\n        for i in range(1, len(arr)+1):\n            num = arr[i-1]\n            this_group = 1\n            group_start = num\n            group_end = num\n            if num > 0 and group_size[num-1] > 0:\n                this_group += group_size[num-1]\n                group_start = parent_idx[num-1]\n                if (group_size[num-1] == m):\n                    num_same -= 1\n                \n            if num < len(arr) and group_size[num+1] > 0:\n                this_group += group_size[num+1]\n                group_end = num+group_size[num+1]\n                if (group_size[num+1] == m):\n                    num_same -= 1\n            \n            group_size[num] = this_group\n            group_size[group_start] = this_group\n            group_size[group_end] = this_group\n            \n            parent_idx[num] = group_start\n            parent_idx[group_end] = group_start\n            \n            if (this_group == m):\n                res = i\n                num_same += 1\n            elif (num_same > 0):\n                res = i\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        r = []\n        b = [0,]*len(arr)\n        i = 0\n        while i<len(arr):\n            v1 = arr[i] > 1 and b[arr[i]-2]\n            v2 = arr[i] < len(arr) and b[arr[i]]\n            if v1 and v2:\n                h = b[arr[i]]\n                t = b[arr[i]-2]\n                b[arr[i]] = 0\n                b[arr[i]-2] = 0\n            elif v1:\n                h = arr[i]\n                t = b[arr[i]-2]\n                b[arr[i]-2] = 0\n            elif v2:\n                h = b[arr[i]]\n                t = arr[i]\n                b[arr[i]] = 0\n            else:\n                h = arr[i]\n                t = h\n\n            b[t-1] = h\n            b[h-1] = t\n\n            i+=1\n\n            if h-t+1 == m:\n                ans = i\n                r.append((t,h))\n            elif r:\n                while r and not (b[r[-1][0]-1] == r[-1][1]):\n                    r.pop()\n\n                if r:\n                    ans = i\n\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ## \u5c31\u662f\u80fd\u591f\u5f97\u77e5\u5230\u5b58\u5728\u67d0\u4e2a\u4e8c\u8fdb\u5236str \u91cc\u9762111 \u957f\u5ea6\u7684\u72b6\u6001\n        ## \u6bcf\u4e00\u6b21\u66f4\u65b0\u90fd\u662f\u4f1a\u6539\u53d8 \u5de6\u8fb9\uff0c \u53f3\u8fb9\u7684\u72b6\u6001\n        if m == len(arr): return m\n        length = [0] * (len(arr) + 2)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if (m > len(arr)):\n            return -1\n        elif (m == len(arr)):\n            return len(arr)\n        else:\n            pass\n        \n        bit_information = [0] * (len(arr) + 1)\n        target_group_size_counter = 0\n        ret = -2\n        \n        \n        for i in range(len(arr)):\n            group_sizes = []\n            total_length = 1\n            neighbor_group_exists = [False, False]\n            \n            \n            if (arr[i] > 1 and bit_information[arr[i] - 1] != 0):\n                total_length += bit_information[arr[i] - 1]\n                neighbor_group_exists[0] = True\n                \n                \n            if (arr[i] < len(arr) and bit_information[arr[i] + 1] != 0):\n                total_length += bit_information[arr[i] + 1]\n                neighbor_group_exists[1] = True\n                  \n            bit_information[arr[i]] = total_length\n            \n            \n            if (neighbor_group_exists[0]):\n                target_group_size_counter -= 1 if bit_information[arr[i] - 1] == m else 0\n                bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n            \n            \n            if (neighbor_group_exists[1]):\n                target_group_size_counter -= 1 if bit_information[arr[i] + 1] == m else 0\n                bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n\n            target_group_size_counter += 1 if total_length == m else 0\n            ret = i if target_group_size_counter > 0 else ret\n            \n        return ret + 1       ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n#         dic = {}\n#         def count_cluster(y,x,cur_count):\n#             length = 0\n#             if y[x-1] == 0:\n#                 if x <n:\n#                     if y[x+1] ==0:\n#                         # ...0x0... \n#                         y[x] = 1\n#                         dic[x] = x\n#                         if m==1:\n#                             cur_count+=1\n#                     else:\n#                         # ...0x#... \n#                         oldr = y[x+1]\n#                         y[x] = 1 + y[x+1]\n#                         y[dic[x+1]] = y[x]\n#                         dic[x] = dic[x+1]\n#                         dic[dic[x+1]] = x\n#                         if oldr == m-1:\n#                             cur_count +=1\n#                         if oldr == m:\n#                             cur_count -=1\n#                 else:\n#                     # ...0x \n#                     y[x] = 1\n#                     dic[x] = x\n#                     if m==1:\n#                         cur_count+=1\n#             else:\n#                 if x <n:\n#                     if y[x+1] ==0:\n#                         # ...#x0... \n#                         oldl = y[x-1]\n#                         y[x] = y[x-1] +1\n#                         y[dic[x-1]] = y[x]\n#                         dic[x] = dic[x-1]\n#                         dic[dic[x-1]] = x\n#                         if oldl == m-1:\n#                             cur_count +=1\n#                         if oldl == m:\n#                             cur_count -=1\n#                     else:\n#                         # ...#x#... \n#                         oldr = y[x+1]\n#                         oldl = y[x-1]\n#                         y[x] = y[x-1] + 1 + y[x+1]\n#                         temp = dic[x-1]\n                        \n#                         y[dic[x-1]] = y[x]\n#                         dic[dic[x-1]] = dic[x+1]\n                        \n#                         y[dic[x+1]] = y[x]\n#                         dic[dic[x+1]] = temp\n                        \n#                         if oldr==m:\n#                             cur_count -= 1\n#                         if oldl ==m:\n#                             cur_count-=1\n#                         if oldr+oldl == m-1:\n#                             cur_count+=1\n#                 else:\n#                     # ...#x \n#                     oldl = y[x-1]\n#                     y[x] = y[x-1] +1\n#                     y[dic[x-1]] = y[x]\n#                     dic[x] = dic[x-1]\n#                     dic[dic[x-1]] = x\n#                     if oldl == m-1:\n#                         cur_count +=1\n#                     if oldl == m:\n#                         cur_count -=1\n                \n#             return cur_count     \n#         n = len(arr)\n#         s = [0] * (n+1)\n#         last = -1\n#         cur_count = 0\n#         for idx,x in enumerate(arr):\n#             cur_count=count_cluster(s,x,cur_count)\n#             if cur_count>0:\n#                 last = idx+1\n#         return last\n\n    #gonna try the union-find method\n        def find(parent, x):\n            if x == parent[x]:\n                return x\n            parent[x] = find(parent,parent[x])\n            return parent[x]\n        n = len(arr)\n        parent = [0 for x in range(n+1)]\n        size = [0] * (n+1)\n        count = [0] * (n+1)\n        ans = -1\n        for i,pos in enumerate(arr):\n            \n            size[pos] = 1\n            count[1] += 1\n            parent[pos] = pos\n            for j in [-1,1]:\n                if (pos+j <=n) and (pos+j>0) and (parent[pos+j]!=0):\n                    x = find(parent,pos+j)\n                    y = find(parent,pos)\n                    if x!=y:\n                        \n                        count[size[x]] -=1\n                        count[size[y]] -=1\n                        parent[x] = y\n                        size[y] += size[x]\n                        count[size[y]] +=1\n            if count[m]>0:\n                ans = i+1\n        return ans", "# class UF:\n#     def __init__(self, n, m):\n#         self.p = [i for i in range(n+1)]  # parent for each position\n#         self.c = [0 for _ in range(n+1)]  # length of group for each position\n#         self.m_cnt = 0                    # count of group with length m\n#         self.m = m                        # m\n        \n#     def union(self, i, j):\n#         pi, pj = self.find(i), self.find(j)\n#         if pi != pj:\n#             if self.c[pi] == self.m: self.m_cnt -= 1  # if previous length at pi is m, decrement m_cnt by 1\n#             if self.c[pj] == self.m: self.m_cnt -= 1  # if previous length at pj is m, decrement m_cnt by 1\n#             self.p[pj] = pi                           # union, use pi at parent for pj\n#             self.c[pi] += self.c[pj]                  # update new length at pi\n#             if self.c[pi] == self.m: self.m_cnt += 1  # if new length at pi == m, increment m_cnt by 1\n            \n#     def mark(self, i):                                \n#         self.c[i] = 1                                 # when first visit a point, mark length as 1\n#         if self.m == 1: self.m_cnt += 1               # if self.m == 1, increment m_cnt by 1\n        \n#     def find(self, i):                                # find parent of i\n#         if self.p[i] != i:\n#             self.p[i] = self.find(self.p[i])\n#         return self.p[i]\n    \n# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         n = len(arr)\n#         uf, ans = UF(n, m), -1                                   # create union find and answer\n#         for i, num in enumerate(arr, 1):\n#             uf.mark(num)\n#             if num-1 >= 1 and uf.c[num-1]: uf.union(num-1, num)  # if left neighbor is marked, union the two\n#             if num+1 < n+1 and uf.c[num+1]: uf.union(num+1, num) # if right neighbor is marked, union the two\n                \n#             if uf.m_cnt > 0: ans = i                             # if m_cnt > 0, meaning there exists some group with length m, update ans\n#         return ans\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def find(x):\n            while x!=par[x]:\n                par[x] = par[par[x]]\n                x = par[x]\n            return x\n        \n        def union(x,y):\n            nonlocal count\n            \n            px, py = find(x), find(y)\n            if px==py:  return\n            if size[px]==m: count-=1\n            if size[py]==m: count-=1\n                \n            if size[px] > size[py]:    \n                par[py] = par[px]\n                size[px] += size[py]\n                if size[px]==m: count+=1\n                \n            else:\n                par[px] = par[py]\n                size[py] += size[px]\n                if size[py]==m: count+=1\n                    \n        count = 0\n        n = len(arr)+1\n        par = list(range(n))\n        size = [0]*n\n        res = -1\n        for i, el in enumerate(arr, 1):\n            size[el] = 1\n            if m==1:    count+=1\n            if el-1>0 and size[el-1]:   union(el, el-1)\n            if el+1<n and size[el+1]:   union(el, el+1)\n            if count>0:    res = i\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        res = -1\n        if n==m:\n            return n\n        set_range = [0]*(n+2)\n        for i in range(n):\n            set_bit = arr[i]\n            left_range = set_range[set_bit-1]\n            right_range = set_range[set_bit+1]\n            set_range[set_bit] = left_range+right_range+1\n            set_range[set_bit-left_range] = set_range[set_bit+right_range] = set_range[set_bit]\n            if left_range==m or right_range==m:\n                res = i\n        \n        return res", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        left = {}\n        right = {}\n        tot = {}\n        cands = set()\n        N = len(A)\n        res = -1\n        for i, a in enumerate(A):\n            size = 1\n            newLeft = newRight = a\n            if a-1 in tot:  size += tot[a-1]\n            if a+1 in tot:  size += tot[a+1]\n            if a-1 in tot:\n                for c in [a-1, left[a-1]]:\n                    if c in cands: cands.remove(c)\n                newLeft = left[a-1]\n                right[left[a-1]] = right[a+1] if a+1 in tot else a\n                tot[left[a-1]] = size\n            if a+1 in tot:\n                for c in [a+1, right[a+1]]:\n                    if c in cands: cands.remove(c)\n                newRight = right[a+1]\n                left[right[a+1]] = left[a-1] if a-1 in tot else a\n                tot[right[a+1]] = size\n            tot[a] = size\n            left[a] = newLeft\n            right[a] = newRight\n            if size == m:\n                cands.add(newLeft)\n                cands.add(newRight)\n            if cands:\n                res = i+1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        uf = list(range(len(arr)))\n        sz = [0] * len(arr)\n        steps = set()\n        \n        def find(x):\n            while x != uf[x]:\n                # uf[x] = uf[uf[x]]\n                x = uf[x]\n            return x\n        \n        def union(p, q):\n            pid, qid = find(p), find(q)\n            if pid == qid:\n                return \n            if sz[pid] == m and pid in steps:\n                steps.remove(pid)\n            if sz[qid] == m and qid in steps:\n                steps.remove(qid)\n            if sz[pid] < sz[qid]:\n                uf[pid] = qid\n                sz[qid] += sz[pid]\n            else:\n                uf[qid] = pid\n                sz[pid] += sz[qid]\n        last_step = -1\n        for i in range(len(arr)):\n            idx = arr[i] - 1\n            sz[idx] = 1\n            if idx - 1 >= 0 and sz[idx-1]:\n                union(idx-1, idx)\n            if idx + 1 < len(arr) and sz[idx+1]:\n                union(idx+1, idx)\n            if sz[find(idx)] == m:\n                steps.add(find(idx))\n            if steps:\n                last_step = i + 1\n            # print(steps)\n        return last_step\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0]*(len(arr)+2)\n        count = [0]*(len(arr)+1)\n        latest = -1\n        for idx, pos in enumerate(arr):\n            left, right = length[pos-1], length[pos+1]\n            length[pos] = length[pos - left] = length[pos + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[pos]] += 1\n            if count[m]:\n                latest = idx + 1\n        return latest\n\n                \n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n      \n        n= len(arr)\n        return self.dfs_helper(arr, n, 1, n, m)\n    def dfs_helper(self, arr, step, left, right, target):\n        if left > right or right-left+1<target :\n            return -1 \n        if right - left + 1 == target:\n            return step\n        breakpoint = arr[step-1]\n        if left<=breakpoint<=right:\n            res = max(self.dfs_helper(arr, step-1, left, breakpoint-1, target), self.dfs_helper(arr,step-1,breakpoint+1, right, target))\n        else:\n            res = self.dfs_helper(arr, step-1, left, right,target)\n        return res ", "import collections\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:        \n        arr = [0] + arr + [0]\n        N = len(arr)\n        left  = [0]*N\n        right = [0]*N\n        sizes = collections.Counter()\n        ans = 0\n        for i in range(1, N-1):\n            # print()\n            # print(\\\"i: \\\", i)\n            l = left[arr[i]-1]\n            r = right[arr[i]+1]\n            if sizes[l] >= 1:\n                sizes[l] -= 1\n            if sizes[r] >= 1:\n                sizes[r] -= 1\n            sizes[l + r + 1] += 1\n            left[arr[i] + 1 + r - 1]  = l + r + 1\n            right[arr[i] - 1 - l + 1] = l + r + 1\n            if sizes[m] >= 1:\n                ans = i\n                \n            # print(left)\n            # print(right)\n            # print(\\\"sizes: \\\", sizes)\n                \n        return  ans if ans >= 1 else -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bit_information = [0] * (len(arr) + 1)\n        target_group_size_counter = 0\n        ret = -2\n        \n        \n        for i in range(len(arr)):\n            group_sizes = []\n            total_length = None\n            \n            \n            if (arr[i] > 1 and bit_information[arr[i] - 1] != 0 and arr[i] < len(arr) and bit_information[arr[i] + 1] != 0):\n                group_sizes = [bit_information[arr[i] - 1], bit_information[arr[i] + 1]]\n                total_length = 1 + bit_information[arr[i] - 1] + bit_information[arr[i] + 1]\n                bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n                bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n            elif (arr[i] > 1 and bit_information[arr[i] - 1] != 0):\n                group_sizes = [bit_information[arr[i] - 1]]\n                total_length = bit_information[arr[i] - 1] + 1\n                bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n                bit_information[arr[i]] = total_length\n            elif (arr[i] < len(arr) and bit_information[arr[i] + 1] != 0):\n                group_sizes = [bit_information[arr[i] + 1]]\n                total_length = bit_information[arr[i] + 1] + 1\n                bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n                bit_information[arr[i]] = total_length\n            else:\n                bit_information[arr[i]] = 1\n                total_length = 1\n                \n            target_group_size_counter -= group_sizes.count(m)\n            target_group_size_counter += 1 if total_length == m else 0\n            \n\n            if (target_group_size_counter > 0):\n                ret = i\n                \n        return ret + 1       ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, uf, cs, ones, cache, res = len(arr), list(range(len(arr))), set(), [0] * len(arr), [0] * len(arr), -1\n        def find(i):\n            while i != uf[i]:\n                i = uf[i]\n            return i\n        def union(nb, cur):\n            p = find(nb)\n            uf[p] = cur\n            cache[cur] += cache[p]\n            cache[p] = 0\n            if p in cs:\n                cs.remove(p)\n        for i, v in enumerate(arr):\n            l, cur, r = v - 2, v - 1, v\n            ones[cur] = 1\n            if l >= 0 and ones[l] == 1:\n                union(l, cur)\n            if r < n and ones[r] == 1:\n                union(r, cur)\n            cache[cur] += 1\n            if cache[cur] == m:\n                cs.add(cur)\n            if len(cs) > 0:\n                res = i + 1\n            # print(f'{ones} {cs} {cache} {uf}')\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        if m == len(arr): return m\n        d = {v: i + 1 for i, v in enumerate(arr)}\n        latest = -1\n        \n        i, j = 1, m\n        max_stack = collections.deque()\n        \n        for t in range(i, j + 1):\n            while max_stack and max_stack[-1] < d[t]:\n                max_stack.pop()\n            max_stack.append(d[t])\n        \n        while j <= len(arr):\n            in_max = max_stack[0]\n            \n            if in_max < d.get(i - 1, float('inf')) and in_max < d.get(j + 1, float('inf')):\n                latest = max(latest, min(d.get(i - 1, float('inf')), d.get(j + 1, float('inf'))) - 1)\n            \n            if d[i] == max_stack[0]:\n                max_stack.popleft()\n            \n            i += 1\n            j += 1\n            \n            if j <= len(arr):\n                while max_stack and max_stack[-1] < d[j]:\n                    max_stack.pop()\n                max_stack.append(d[j])\n\n        return latest", "from collections import deque \nclass Solution:\n    def findLatestStep(self, lis: List[int], m: int) -> int:\n        n = len(lis)\n        if m>n:\n            return 0\n        if m==n:\n            return n\n        if n==1:\n            return 1\n        lis = [[lis[i],i] for i in range(n)]\n        lis.sort()\n        #print(lis)\n        q = deque()\n        ans=0\n        for i in range(n):\n            while q and lis[i][1]>=q[-1][0]:\n                q.pop()\n            q.append([lis[i][1],i])\n            while q and q[0][1]<=i-m:\n                q.popleft()\n            if i>=m-1:\n                aa = q[0][0]\n          #      print(aa,i,m)\n                if i==m-1:\n                    if i+1<n and aa<lis[i+1][1]:\n                        ans = max(ans,lis[i+1][1])\n                if i==n-1:\n                    #print(lis[i-m][1],i,m)\n                    if aa<lis[i-m][1]:\n                        ans = max(ans,lis[i-m][1])\n                else:\n                    if i+1<n and aa<lis[i+1][1] and aa<lis[i-m][1]:\n                        ans = max(ans,min(lis[i+1][1],lis[i-m][1]))\n                #print(ans)\n        return -1 if ans==0 else ans\n            \n            \n            \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == 1:\n            if m == 0:\n                return 0\n            elif m == 1:\n                return 1\n            else:\n                return -1\n        \n        if len(arr) == m:\n            return m\n        \n        freq_indices = []\n        last_freq = -1\n        goal_freq = 0\n        arr = [el - 1 for el in arr]\n        left = [None] * len(arr)\n        right = [None] * len(arr)\n        \n        idx = 0\n        while idx < len(arr):\n            change = arr[idx]\n            if change == 0:\n                left_end = change\n                right_end = right[change + 1]\n                left_size = 0\n                if right_end is None:\n                    right_end = change\n                    right_size = 0\n                else:\n                    right_size = right_end - change\n                \n                right[change] = right_end\n                left[right_end] = left_end\n                \n                if right_size == m:\n                    goal_freq -= 1\n                \n                new_size = right_end - left_end + 1\n                if new_size == m:\n                    goal_freq += 1\n                \n                # print(new_size, goal_freq)\n                if goal_freq > 0:\n                    last_freq = idx\n                    \n            elif change == len(arr) - 1:\n                right_end = len(arr) - 1\n                left_end = left[change - 1]\n                right_size = 0\n                if left_end is None:\n                    left_end = change\n                    left_size = 0\n                else:\n                    left_size = change - left_end\n                \n                left[change] = left_end\n                right[left_end] = right_end\n                \n                if left_size == m:\n                    goal_freq -= 1\n                \n                new_size = right_end - left_end + 1\n                if new_size == m:\n                    goal_freq += 1\n                \n                if goal_freq:\n                    last_freq = idx\n                    \n            else:\n                left_end = left[change - 1]\n                right_end = right[change + 1]\n                if right_end is None:\n                    right_end = change\n                    right_size = 0\n                else:\n                    right_size = right_end - change\n                    \n                if left_end is None:\n                    left_end = change\n                    left_size = 0\n                else:\n                    left_size = change - left_end\n                \n                right[left_end] = right_end\n                left[right_end] = left_end\n                \n                if right_size == m:\n                    goal_freq -= 1\n                    \n                if left_size == m:\n                    goal_freq -= 1\n                \n                \n                new_size = right_end - left_end + 1\n                if new_size == m:\n                    goal_freq += 1\n                \n                if goal_freq:\n                    last_freq = idx\n            idx += 1\n        \n        if last_freq != -1:\n            return last_freq + 1\n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        status = [0]*len(arr)\n        cnt = collections.Counter()\n        \n        last = -1\n        for step, idx in enumerate(arr):\n            i = idx-1\n            status[i] = 1\n            \n            left = not (i == 0 or status[i-1] == 0)\n            right = not (i >= len(arr)-1 or status[i+1] == 0)\n            \n            if not left and not right:\n                cnt[1] += 1\n                status[i] = 1\n            \n            elif left and right:\n                j, k = status[i-1], status[i+1]\n                full = 1 + j + k\n                status[i-j] = full\n                status[i+k] = full\n                cnt[full] += 1\n                cnt[j] -= 1\n                cnt[k] -= 1\n            \n            elif left:\n                j = status[i-1]\n                full = 1+j\n                status[i-j] = full\n                status[i] = full\n                cnt[j] -= 1\n                cnt[full] += 1\n                \n            elif right:\n                k = status[i+1]\n                full = 1+k\n                status[i] = full\n                status[i+k] = full\n                cnt[k] -= 1\n                cnt[full] += 1\n                \n            # print(step, status, cnt)\n            if cnt[m] > 0:\n                last = step+1\n                \n        return last\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr) + 1\n        \n        starts = dict()\n        ends = dict()\n        \n        num_groups = 0\n        ans = -1\n        \n        for (step, i) in enumerate(arr):\n            \n            cur_range = [i, i]\n            if i + 1 in starts:\n                cur_range[1] = starts[i+1]\n                \n                if starts[i+1] - i == m:\n                    num_groups -= 1\n                \n                del starts[i+1]\n                \n            if i - 1 in ends:\n                cur_range[0] = ends[i-1]\n                \n                if i - ends[i-1] == m:\n                    num_groups -= 1\n                del ends[i-1]\n            \n            starts[cur_range[0]] = cur_range[1]\n            ends[cur_range[1]] = cur_range[0]\n            \n            if cur_range[1] - cur_range[0] + 1 == m:\n                num_groups += 1\n            \n            if num_groups > 0:\n                ans = step + 1\n        return ans\n            \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        aux = [[0, -1, -1] for _ in range(n)]\n        \n        #      Caso 1  \n        # arr = [3, 5, 1, 2, 4]\n        # [[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]]\n        # [Group size, startIdx, endIdx]\n\n        if n == 1:\n            return 1 if m == n else -1\n\n        mCounter = 0\n        result = -1\n        for i in range(n):\n            idx = arr[i] - 1\n            \n            if idx == 0: # Caso 1\n                if aux[idx+1][0] == m:\n                    mCounter -= 1\n                aux[idx][0] = aux[idx+1][0] + 1\n                if aux[idx][0] == m:\n                    mCounter += 1\n                endIdx = idx if aux[idx+1][2] == -1 else aux[idx+1][2]\n                aux[idx][2] = endIdx\n                aux[idx][1] = 0\n                \n                aux[endIdx][1] = 0\n                aux[endIdx][0] = aux[idx][0]\n                \n            elif idx == n-1: # Caso 2\n                if aux[idx-1][0] == m:\n                    mCounter -= 1\n                aux[idx][0] = aux[idx-1][0] + 1\n                if aux[idx][0] == m:\n                    mCounter += 1\n                startIdx = idx if aux[idx-1][1] == -1 else aux[idx-1][1]\n                aux[idx][1] = startIdx\n                aux[idx][2] = n-1\n                \n                aux[startIdx][2] = n-1\n                aux[startIdx][0] = aux[idx][0]\n                \n            else:\n                if aux[idx-1][0] == m:\n                    mCounter -= 1\n                if aux[idx+1][0] == m:\n                    mCounter -= 1\n                groupSize = aux[idx+1][0] + aux[idx-1][0] + 1\n                if groupSize == m: mCounter += 1\n\n                aux[idx][0] = groupSize\n                startIdx = idx if aux[idx-1][1] == -1 else aux[idx-1][1]\n                endIdx = idx if aux[idx+1][2] == -1 else aux[idx+1][2]\n\n                aux[idx][1] = startIdx\n                aux[idx][2] = endIdx\n                \n                # Updating first element of group\n                aux[startIdx][0] = groupSize\n                aux[startIdx][1] = startIdx\n                aux[startIdx][2] = endIdx\n                \n                # Updating last element of group\n                aux[endIdx][0] = groupSize\n                aux[endIdx][1] = startIdx\n                aux[endIdx][2] = endIdx\n            \n            if mCounter > 0:\n                result = i+1\n\n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if (m == len(arr)):\n            return len(arr)\n        \n        bit_information = [0] * (len(arr) + 2)\n        target_group_size_counter = 0\n        ret = -2\n        \n        \n        for i in range(len(arr)):\n            total_length = 1 + bit_information[arr[i] - 1] + bit_information[arr[i] + 1]   \n            bit_information[arr[i]] = total_length\n            \n            \n            if (total_length != 1):\n                target_group_size_counter -= 1 if bit_information[arr[i] - 1] == m else 0\n                bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n                target_group_size_counter -= 1 if bit_information[arr[i] + 1] == m else 0\n                bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n            \n            target_group_size_counter += 1 if total_length == m else 0\n            ret = i if target_group_size_counter > 0 else ret\n            \n        return ret + 1       ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        last_step = -1\n        n = len(arr)\n        left, right = [0] * n, [0] * n\n        tmp_arr = [0] * n\n        memo = collections.defaultdict(lambda: 0)\n        for i, num in enumerate(arr):\n            tmp_arr[num - 1] = 1\n            left[num - 1] = 1 + (left[num - 2] if num >= 2 else 0)\n            right[num - 1] = 1 + (right[num] if num < n else 0)\n            \n            if num >= 2 and tmp_arr[num - 2]:\n                memo[left[num - 2] + right[num - 2] - 1] -= 1\n                right[num - 2] += right[num - 1]\n                if (num - 1 - (left[num - 1] - 1)) != (num - 2): \n                    right[num - 1 - (left[num - 1] - 1)] += right[num - 1]\n                \n                \n            if num < n and tmp_arr[num]:\n                memo[left[num] + right[num] - 1] -= 1\n                left[num] += left[num - 1]\n                # print(\\\"haha\\\", tmp_arr, left, right)\n                if (num - 2 + right[num - 1]) != num: \n                    left[num - 2 + right[num - 1]] += left[num - 1]\n                \n            memo[left[num - 1] + right[num - 1] - 1] += 1\n                \n            if memo[m] > 0:\n                \n                last_step = i + 1\n            # print(memo, tmp_arr, left, right)\n        return last_step", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        groupCount = dict()\n        n = len(arr)\n        parents = [0] * n\n        \n        lastM = -1\n        mCnt = 0\n        for i,p in enumerate(arr):\n            leftParent = self.getParent(p - 1, parents)\n            rightParent = self.getParent(p + 1, parents)\n            parents[p-1] = p    # its own parent\n            if leftParent == 0 and rightParent == 0:\n                groupCount[p] = 1\n                newCnt = 1\n            elif leftParent != 0 and rightParent != 0:\n                newCnt = groupCount[leftParent] + groupCount[rightParent] + 1\n                self.mergeGroups(leftParent, p, parents)\n                self.mergeGroups(rightParent, p, parents)\n            elif leftParent != 0:\n                newCnt = groupCount[leftParent] + 1\n                self.mergeGroups(leftParent, p, parents)\n            else:\n                newCnt = groupCount[rightParent] + 1\n                self.mergeGroups(rightParent, p, parents)\n            \n            if leftParent != 0 and groupCount[leftParent] == m:\n                mCnt -= 1\n            \n            if rightParent != 0 and groupCount[rightParent] == m:\n                mCnt -= 1\n            \n            groupCount[p] = newCnt\n            \n            if newCnt == m:\n                mCnt += 1\n            \n            if mCnt > 0:\n                lastM = i + 1\n        \n        return lastM\n    \n    def getParent(self, p: int, parents: List[int]) -> int:\n        if p <= 0 or p > len(parents):\n            return 0\n        \n        if p == parents[p-1]:\n            return p\n        \n        return self.getParent(parents[p-1], parents)\n    \n    def mergeGroups(self, pp, p, parents):\n        parents[pp-1] = p\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        start_set = {}\n        end_set = {}\n        counter = 0\n        for idx, n in enumerate(arr):\n            if n - 1 in end_set and n + 1 in start_set:\n                st = end_set.pop(n-1)\n                ed = start_set.pop(n+1)\n                end_set[ed] = st\n                start_set[st] = ed\n                if n - st == m:\n                    counter -= 1\n                if ed - n == m:\n                    counter -= 1\n                if ed - st + 1 == m:\n                    counter += 1\n            elif n - 1 in end_set:\n                st = end_set.pop(n-1)\n                end_set[n] = st\n                start_set[st] = n\n                if n - st == m:\n                    counter -= 1\n                elif n-st+1 == m:\n                    counter += 1\n            elif n + 1 in start_set:\n                ed = start_set.pop(n+1)\n                start_set[n] = ed\n                end_set[ed] = n\n                if ed - n == m:\n                    counter -= 1\n                elif ed-n+1 == m:\n                    counter += 1\n            else:\n                start_set[n] = n\n                end_set[n] = n\n                if m == 1:\n                    counter += 1\n            if counter > 0:\n                ans = idx + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        if m == len(arr): return m\n        length = [0] * (len(arr) + 2)\n        res = -1\n        for i, v in enumerate(arr):\n            left, right = length[v - 1], length[v + 1]\n            if left == m or right == m:\n                res = i\n            length[v - left] = length[v + right] = left + right + 1\n        return res\n    \n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "from collections import Counter\nclass Solution:\n    def findLatestStep(self, arr1: List[int], m: int) -> int:\n        if m== len(arr1):\n          return len(arr1)\n        \n        def find(arr,i):\n          if i== arr[i]: return i\n          arr[i] = find(arr,arr[i])\n          return arr[i]\n        \n        def union(arr,i,j,c,mCount):\n          u= find(arr,i)\n          v= find(arr,j)\n          if u != v and v in c and c[v] == m: mCount -=1\n          if u != v and u in c and c[u] == m: mCount -=1\n          if u != v:\n            arr[v] = u\n          return u,mCount\n            \n        ret = -1\n        t = [0]*len(arr1)\n        par = [i for i in range(len(arr1))]\n        c = dict()\n        mCount = 0\n        for i in range(len(arr1)):\n          pri = arr1[i]-1\n          t[pri] = 1\n          p1, p2 = arr1[i]-2, arr1[i]\n          if( p1 < 0 or not t[p1] ) and (p2 >= len(arr1) or not t[p2]):\n              c[pri] = 1\n              if c[pri] == m: mCount+=1\n          if p1 >=0 and t[p1]:\n            u, mCount = union(par, p1, pri,c,mCount)\n            c[u] += 1\n            if  u in c and c[u] == m: mCount +=1 \n          if p2 <len(arr1) and p1>=0 and t[p1] and t[p2]:\n            u , mCount = union(par, p1, p2,c,mCount)\n            c[u] += c[p2]\n            if  u in c and c[u] == m: mCount +=1 \n            del c[p2]\n          elif p2<len(arr1) and t[p2]:\n            u,mCount = union (par,pri, p2,c,mCount)\n            c[u] = c[p2]+1\n            if  u in c and c[u] == m: mCount +=1 \n            del c[p2]\n          if mCount:\n            ret = i+1\n        return ret\n        \n                       \n", "from collections import Counter\nclass Solution:\n    def findLatestStep(self, arr1: List[int], m: int) -> int:\n        if m== len(arr1):\n          return len(arr1)\n        \n        def find(arr,i):\n          if i== arr[i]: return i\n          arr[i] = find(arr,arr[i])\n          return arr[i]\n        \n        def union(arr,i,j,c,mCount):\n          u= find(arr,i)\n          v= find(arr,j)\n          #print(mCount,u,v,c,\\\"9999999\\\")\n          if u != v and v in c and c[v] == m: mCount -=1\n          if u != v and u in c and c[u] == m: mCount -=1\n          if u != v:\n            arr[v] = u\n          #print(mCount,u,v,c,par)\n          return u,mCount\n            \n        ret = -1\n        t = [0]*len(arr1)\n        par = [i for i in range(len(arr1))]\n        c = dict()\n        mCount = 0\n        for i in range(len(arr1)):\n          pri = arr1[i]-1\n          t[pri] = 1\n          p1, p2 = arr1[i]-2, arr1[i]\n          if( p1 < 0 or not t[p1] ) and (p2 >= len(arr1) or not t[p2]):\n              c[pri] = 1\n              if c[pri] == m: mCount+=1\n          if p1 >=0 and t[p1]:\n            u, mCount = union(par, p1, pri,c,mCount)\n            c[u] += 1\n            if  u in c and c[u] == m: mCount +=1 \n          if p2 <len(arr1) and p1>=0 and t[p1] and t[p2]:\n            u , mCount = union(par, p1, p2,c,mCount)\n            c[u] += c[p2]\n            if  u in c and c[u] == m: mCount +=1 \n            del c[p2]\n          elif p2<len(arr1) and t[p2]:\n            u,mCount = union (par,pri, p2,c,mCount)\n            c[pri] = c[p2]+1\n            if  pri in c and c[pri] == m: mCount +=1 \n            del c[p2]\n          if mCount:\n            ret = i+1\n          #print(mCount,\\\";;;\\\",c)\n        return ret\n        \n                       \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        counts = [0] * (len(arr)+2)\n        # m_nums = 0\n        ans = -1\n        \n        for index,i in enumerate(arr):\n            left = counts[i-1]\n            right = counts[i+1]\n            total = 1+left+right\n            counts[i] = total\n            counts[i-left] = total\n            counts[i+right] = total\n            \n            if left==m or right ==m:\n                ans = index\n            # if left==m:\n            #     m_nums-=1\n            # if right == m:\n            #     m_nums-=1\n            # if total == m:\n            #     m_nums+=1\n            # if m_nums >0:\n            #     ans = index+1\n                \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        n = len(arr)\n        dp = [1]*(n+1)\n        res = -1\n        if n == m:\n            return n\n        \n        for i in range(len(arr)-1, -1, -1):\n            dp[arr[i]] = 0\n            \n            j = arr[i]+1\n            count = 0\n            while j < len(dp) and dp[j]==1:\n                count+=1\n                if count > m:\n                    break\n                j+=1\n            \n            if count == m:\n                return i\n            \n            j = arr[i]-1\n            count = 0\n            while j >= 1 and dp[j]==1:\n                count+=1\n                if count > m:\n                    break\n                j-=1\n                \n            if count == m:\n                return i\n        \n        \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        count = [0]*(n + 1)\n        length = [0]*(n + 1)\n        p = list(range(1 + n))\n        cur = [0]*(n + 2)\n        \n        def find(x):\n            if x != p[x]:\n                p[x] = find(p[x])\n            return p[x]\n        def union(x, y):\n            t1, t2 = find(x), find(y)\n            a, b = length[t1], length[t2]\n            p[t1] = t2\n            length[t2] = a + b\n            count[a] -= 1\n            count[b] -= 1\n            count[a + b] += 1\n        ans = -1\n        for i, x in enumerate(arr):\n            #print('in', i, x, cur, length, count)\n            cur[x] += 1\n            length[x] = 1\n            count[1] += 1\n            if cur[x - 1]:\n                union(x, x - 1)\n            if cur[x + 1]:\n                union(x, x + 1)\n            if count[m]:\n                ans = i + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        arr.append(n+1)\n        start = defaultdict(dict)\n        finish = defaultdict(dict)\n        last = -1\n        for level,i in enumerate(arr):\n            if i-1 not in finish: finish[i-1] = i \n            if i+1 not in start: start[i+1] = i\n\n            s, f = finish[i-1], start[i+1]\n            start[s] = f \n            finish[f] = s\n            \n            for os, of in [[i+1, start[i+1]], [finish[i-1], i-1]]:\n                if of-os+1 == m: last = level\n        \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m: return m\n        \n        fa = [i for i in range(n)]\n        sz = [0 for i in range(n)]\n        \n        def gf(i) -> int:\n            if fa[i] != i: fa[i] = gf(fa[i])\n            return fa[i]\n        \n        def merge(x, y):\n            fx, fy = gf(x), gf(y)\n            if fx != fy:\n                if sz[fx] < sz[fy]: \n                    fx, fy = fy, fx\n                fa[fy] = fx\n                sz[fx] += sz[fy]\n        ans = -1\n        for i in range(n):\n            a = arr[i] - 1\n            sz[a] = 1\n            for j in (a - 1, a + 1):\n                if 0 <= j < n and sz[j] > 0:\n                    if sz[gf(j)] == m: ans = i\n                    merge(j, a)\n        return ans\n                    \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bit_information = [0] * (len(arr) + 1)\n        target_group_size_counter = 0\n        ret = -2\n        \n        \n        for i in range(len(arr)):\n            group_sizes = []\n            total_length = 1\n            neighbor_group_exists = [False, False]\n            \n            \n            if (arr[i] > 1 and bit_information[arr[i] - 1] != 0):\n                total_length += bit_information[arr[i] - 1]\n                neighbor_group_exists[0] = True\n                \n                \n            if (arr[i] < len(arr) and bit_information[arr[i] + 1] != 0):\n                total_length += bit_information[arr[i] + 1]\n                neighbor_group_exists[1] = True\n                  \n            bit_information[arr[i]] = total_length\n            \n            \n            if (neighbor_group_exists[0]):\n                target_group_size_counter -= 1 if bit_information[arr[i] - 1] == m else 0\n                bit_information[arr[i] - bit_information[arr[i] - 1]] = total_length\n            \n            \n            if (neighbor_group_exists[1]):\n                target_group_size_counter -= 1 if bit_information[arr[i] + 1] == m else 0\n                bit_information[arr[i] + bit_information[arr[i] + 1]] = total_length\n\n            target_group_size_counter += 1 if total_length == m else 0\n            ret = i if target_group_size_counter > 0 else ret\n            \n        return ret + 1       ", "class Solution:\n    def isSorted(self, arr):\n        for i in range(1, len(arr)):\n            if arr[i] < arr[i-1]:\n                return False\n        return True\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        if m == length:\n            # Full string of 1s can only be found at last step\n            return m\n        \n        if self.isSorted(arr):\n            return m\n        \n        # Pad front and back to make boundary conditions easier\n        binary = [0] * (len(arr) + 2)\n        latest_step = -1\n        \n        for step in range(length):\n            pos = arr[step]\n            binary[pos] = 1\n            \n            # Examine positions directly to the left and right i.e., group boundaries\n            # Find/store the new group size at the new boundaries\n            left_len = binary[pos-1]\n            right_len = binary[pos+1]\n            new_len = left_len + right_len + 1\n            \n            if left_len == m or right_len == m:\n                # Target length persistent until prev step\n                latest_step = step\n                \n            binary[pos-left_len] = new_len\n            binary[pos+right_len] = new_len\n                \n        return latest_step", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        dic = collections.Counter()\n        cnt = collections.Counter()\n        res = -1\n        for i, a in enumerate(arr):\n            l = dic[a - 1]\n            r = dic[a + 1]\n            dic[a - l] = dic[a + r] = dic[a] = l + r + 1\n            cnt[l + r + 1] += 1\n            cnt[l] -= 1\n            cnt[r] -= 1\n            if cnt[m]:\n                res = i + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0] * (len(arr) + 2)\n        count = [0] * (len(arr) + 1)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "class Solution:\n        \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        self.mcnt = 0\n        par = {}\n        sz = {}\n        \n        def find(i):\n            while i != par[i]:\n                par[i] = par[par[i]]\n                i = par[i]\n            return i\n        \n        def union(i, j):\n            x = find(i)\n            y = find(j)\n            if x == y:\n                return\n            if sz[x] == m:\n                self.mcnt -= 1\n            if sz[y] == m:\n                self.mcnt -= 1\n                    \n            if sz[x] <= sz[y]:\n                sz[y] += sz[x]\n                par[x] = y\n                \n                if sz[y] == m:\n                    self.mcnt += 1\n            else:\n                sz[x] += sz[y]\n                par[y] = x\n                \n                if sz[x] == m:\n                    self.mcnt += 1\n        \n        count = 1\n        ans = -1\n        target = set()\n        for i in arr:\n            if i not in par:\n                par[i] = i\n                sz[i] = 1\n                if m == 1:\n                    self.mcnt += 1\n                \n            if i - 1 in par:\n                union(i-1, i)\n                \n            if i + 1 in par:\n                union(i, i+1)\n            \n            if self.mcnt > 0:\n                ans = count\n            count += 1\n                \n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, res = len(arr), -1\n        if m == n:\n            return n\n        if m == 1 and n == 1:\n            return 1\n        string, size, root = [0] * n, [1] * n, [-1] * n\n        \n        def find(a):\n            if root[a] != a:\n                root[a] = find(root[a])\n            return root[a]\n            \n        def union(a, b):\n            find_a, find_b = find(a), find(b)\n            root[find_a] = find_b\n            size[find_b] += size[find_a]\n            \n        for step in range(n):\n            idx = arr[step] - 1\n            string[idx] = 1\n            root[idx] = idx\n            \n            # we check the sizes of its two neigbor sets before we merge them with it\n            if idx - 1 >= 0 and string[idx - 1] == 1:\n                if m == size[find(idx - 1)]:\n                    res = step\n            if idx + 1 < n and string[idx + 1] == 1:\n                if m == size[find(idx + 1)]:\n                    res = step\n            if idx - 1 >= 0 and string[idx - 1] == 1:\n                union(idx - 1, idx)\n            if idx + 1 < n and string[idx + 1] == 1:\n                union(idx + 1, idx)\n        return res\n'''\n[3,5,1,2,4]\n1\n[3,1,5,4,2]\n2\n[1]\n1\n[2, 1]\n2\n[3,2,5,6,10,8,9,4,1,7]\n3\n[4,3,2,1]\n1\n'''\n", "class Solution:\n    def findLatestStep(self, arr, m) -> int:\n\n        n = length = len(arr)\n        if m == length:\n            return m\n        parent = [i for i in range(length)]\n        size = [0 for _ in range(length)]\n\n        cur = [0] * length\n        ans = -1\n\n        def root(p):\n            while p != parent[p]:\n                parent[p] = parent[parent[p]]\n                p = parent[p]\n            return p\n\n        def union(p, q):\n            root_p = root(p)\n            root_q = root(q)\n\n            if root_p != root_q:\n                if size[root_p] > size[root_q]:\n                    parent[root_q] = root_p\n                    size[root_p] += size[root_q]\n\n                else:\n                    parent[root_p] = root_q\n                    size[root_q] += size[root_p]\n\n        for idx, i in enumerate(arr):\n            i -= 1\n            size[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if size[root(j)] == m:\n                        ans = idx\n                    if size[j]:\n                        union(i, j)\n                    \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0]*(len(arr)+2)\n        count=[0]*(len(arr)+1)\n        res=-1\n        for i,a in enumerate(arr):\n            left,right = length[a-1],length[a+1]\n            length[a]=length[a-left]=length[a+right]=left+right+1\n            count[left]-=1\n            count[right]-=1\n            count[length[a]]+=1\n            if count[m]>0:\n                res=i+1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        #\u4e24\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u8bb0\u5f55\u957f\u5ea6\uff0c\u53e6\u4e00\u4e2a\u8bb0\u5f55\u957f\u5ea6\u7684\u4e2a\u6570\n        length = [0 for _ in range(len(arr)+2)]\n        count = [0 for _ in range(len(arr)+1)]\n        res = -1\n        for i, a in enumerate(arr):\n            #\u5148\u628a\u5de6\u8fb9\u7684\u957f\u5ea6\u548c\u53f3\u8fb9\u76841\u957f\u5ea6\u53d6\u51fa\u6765\n            left, right = length[a-1], length[a+1]\n            #\u73b0\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u957f\u5ea6\u5c31\u662f\u5de6\u8fb9\u7684\u957f\u5ea6\u52a0\u4e0a\u53f3\u8fb9\u7684\u957f\u5ea6\u52a0\u4e0a\u81ea\u5df1\n            #\u8ddd\u79bba\u4f4d\u7f6e\u7684\u5de6\u53f3\u4e24\u8fb9\u7684\u8fb9\u89d2\u5904\u7684\u7d22\u5f15\u4e5f\u4f1a\u88ab\u9644\u4e0a\u65b0\u7684\u503c\uff0c\u4e4b\u540e\u7684\u8ba1\u7b97\u53ef\u80fd\u7528\u5f97\u4e0a\n            length[a] = length[a-left] = length[a+right] = left + right + 1\n            \n            #\u7136\u540e\u5c31\u662f\u66f4\u65b0count\u4e86\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            \n            #\u5224\u65adm\u662f\u5426\u8fd8\u5b58\u5728\uff0c\u53ea\u8981m\u5b58\u5728\u90a3\u5c31\u662f\u6ee1\u8db3\u6761\u4ef6\u7684\u6700\u540e\u4e00\u6b65\n            if count[m]:\n                res = i+1\n        return res", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        length = [0] * (len(A) + 2)\n        count = [0] * (len(A) + 1)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "from bisect import bisect_left\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        if m == N: return m\n        bits = [(1, N)]\n        ans = 0\n        for i in range(N-1, -1, -1):\n            a = arr[i]\n            idx = bisect_left(bits, (a, a))\n            if idx < len(bits) and bits[idx][0] == a:\n                if bits[idx][1] == a:\n                    bits.pop(idx)\n                else:\n                    s, e = bits[idx]\n                    if (e - s) == m: return i\n                    bits[idx] = (s+1, e)\n                continue\n            idx -= 1\n            if bits[idx][1] == a:\n                bits[idx] = (bits[idx][0], a-1)\n                if bits[idx][1] - bits[idx][0] + 1 == m:\n                    return i\n            else:\n                before = (bits[idx][0], a-1)\n                after = (a+1, bits[idx][1])\n                if (before[1] - before[0] + 1) == m: return i\n                if (after[1] - after[0] + 1) == m: return i\n                bits[idx:idx+1] = [before, after]\n        return -1", "class Solution:\n    def findLatestStep2(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        spans = [(1, N)]\n        step = N\n        \n        if m == N:\n            return m\n        \n        while arr:\n            #print(step, spans)\n            d = arr.pop()\n            step -= 1\n            for span in spans:\n                if span[0] <= d <= span[1]:\n                    if d-span[0] == m or span[1] - d == m:\n                        return step\n                    \n                    spans.remove(span)\n                    if d - span[0] > m:\n                        spans.append((span[0], d-1))\n                    if span[1] - d > m:\n                        spans.append((d+1, span[1]))\n            \n        return -1\n    \n    def findLatestStep(self, A, m):\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        length_to_index = defaultdict(set)\n        state = [(0,0) for i in range(length+2)]\n        ans = -1\n        \n        for step,index in enumerate(arr):\n            if state[index-1] == (0,0) and state[index+1] == (0,0):\n                state[index] = (1,1)\n                length_to_index[1].add(index)\n            elif state[index+1] == (0,0):\n                L = state[index-1][0]+1\n                state[index] = (L,1)\n                state[index-L+1] = (1,L)\n                length_to_index[L-1].remove(index-L+1)\n                length_to_index[L].add(index-L+1)\n            elif state[index-1] == (0,0):\n                L = state[index+1][1]+1\n                state[index] = (1,L)\n                state[index+L-1] = (L,1)\n                length_to_index[L-1].remove(index+1)\n                length_to_index[L].add(index)\n            else:\n                l_left = state[index-1][0]\n                l_right = state[index+1][1]\n                L = l_left+ l_right + 1\n                state[index-l_left] = (1,L)\n                state[index+l_right]= (L,1)\n                length_to_index[l_right].remove(index+1)\n\n                length_to_index[l_left].remove(index-l_left)\n                length_to_index[L].add(index-l_left)\n            if length_to_index[m] :\n                ans = step + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        seen = dict()\n        \n        ans = -1\n        ct = 0\n        latestGood = dict()\n        for pos in arr:\n            ct+=1\n            mi, ma = pos, pos\n            \n            if pos-1 in seen:\n                mi = min(seen[pos-1][0], mi)\n            \n            if pos+1 in seen:\n                ma = max(seen[pos+1][1], ma)                                    \n            \n            seen[pos] = (mi, ma)\n            \n            if pos-1 in seen:\n                seen[pos-1] = (mi, ma)\n            \n            if pos+1 in seen:\n                seen[pos+1] = (mi, ma)\n                \n            if mi in seen:\n                seen[mi] = (mi, ma)\n            \n            if ma in seen:\n                seen[ma] = (mi, ma)\n            \n            if ma-mi+1==m:\n                ans=ct\n                \n                latestGood[mi] = ma\n                latestGood[ma] = mi\n            else:                                \n                if pos-1 in latestGood:\n                    if latestGood[pos-1] in latestGood:\n                        latestGood.pop(latestGood[pos-1])\n                        \n                    if pos-1 in latestGood:\n                        latestGood.pop(pos-1)\n                    \n                if pos+1 in latestGood:\n                    if latestGood[pos+1] in latestGood:\n                        latestGood.pop(latestGood[pos+1])\n                    \n                    if pos+1 in latestGood:\n                        latestGood.pop(pos+1)\n                \n                if len(latestGood)>0:\n                    ans=ct\n            \n                \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        par = {}\n        sz = {}\n        target = set()\n        \n        def find(i):\n            while i != par[i]:\n                par[i] = par[par[i]]\n                i = par[i]\n            return i\n        \n        def union(i, j):\n            x = find(i)\n            y = find(j)\n            if x == y:\n                return\n            if sz[x] <= sz[y]:\n                sz[y] += sz[x]\n                par[x] = y\n                \n                if sz[y] == m:\n                    target.add(y)\n                    \n                if sz[x] == m and x in target:\n                    target.remove(x)\n            else:\n                sz[x] += sz[y]\n                par[y] = x\n                \n                if sz[x] == m:\n                    target.add(x)\n                    \n                if sz[y] == m and y in target:\n                    target.remove(y)\n        \n        count = 1\n        ans = -1\n        target = set()\n        for i in arr:\n            if i not in par:\n                par[i] = i\n                sz[i] = 1\n                if m == 1:\n                    target.add(i)\n                \n            if i - 1 in par and i + 1 in par:\n                union(i-1, i+1)\n                union(i-1, i)\n            elif i - 1 in par:\n                union(i-1, i)\n            elif i + 1 in par:\n                union(i, i+1)\n            \n            t = set(target)\n            for x in t:\n                if sz[x] != m:\n                    target.remove(x)\n            if len(target):\n                ans = count\n            count += 1\n                \n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        lenArr = [0] * (len(arr) + 2)        \n        \n        count = 0\n        steps = 1\n        res = -1\n        for k in arr:            \n            left, right = lenArr[k-1], lenArr[k+1]\n            if lenArr[k-left] == m:\n                count -= 1 \n                \n            if lenArr[k+right] == m:\n                count -= 1 \n                \n            lenArr[k] = lenArr[k-left] = lenArr[k+right] = left + right + 1\n            if lenArr[k] == m:                \n                count += 1\n                \n            if count > 0:\n                res = steps\n            \n            steps += 1\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        def find(parents, u):\n            if u != parents[u]:\n                parents[u] = find(parents, parents[u])\n            \n            return parents[u]\n        \n        def union(parents, ranks, u, v):\n            pu = find(parents, u)\n            pv = find(parents, v)\n            if ranks[pu] >= ranks[pv]:\n                parents[pv] = pu\n                ranks[pu] += ranks[pv]\n            else:\n                parents[pu] = pv\n                ranks[pv] += ranks[pu]\n        \n        n = len(arr)\n        if n == m:\n            return n\n        \n        laststep = -1\n        parents = list(range(n))\n        ranks = [0] * (n)\n        for i in range(n):\n            num = arr[i] - 1\n            ranks[num] = 1\n            if num-1 >= 0:\n                pleft = find(parents, num-1)\n                #print('left', num, num-1, pleft)\n                if ranks[pleft] == m:\n                    laststep = i\n                if ranks[pleft] > 0:\n                    union(parents, ranks, num-1, num)\n            if num+1 < n:\n                pright = find(parents, num+1)\n                #print('right', num, num+1, pright)\n                if ranks[pright] == m:\n                    laststep = i\n                if ranks[pright] > 0:\n                    union(parents, ranks, num+1, num)\n            \n            #print('p:', parents)\n            #print('r:', ranks)\n        return laststep\n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        n = len(arr)\n        if m == n:\n            return m\n        parent = [-1]*n\n        size = [0]*n\n        def find(x):\n            if parent[x] == -1:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n        def union(x,y):\n            px = find(x)\n            py = find(y)\n            if px == py:\n                return False\n            if size[px] > size[py]:\n                size[px] += size[py]\n                parent[py] = px\n            else:\n                size[py] += size[px]\n                parent[px] = py\n            return True\n        \n\n        ans = -1\n        \n        for step, i in enumerate(arr):\n            i -=1\n            size[i] = 1\n            for j in (i-1, i+1):\n                if 0 <= j < n:\n                    if size[find(j)] == m:\n                        ans = step\n                    if size[j]:\n                        union(i,j)\n                        \n                    \n        return ans\n        \n        \n        \n                \n       \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        from collections import defaultdict\n        cnt = defaultdict(int)\n        \n        N = len(arr)\n        rank = [0] * N\n         \n        \n        res = -1\n        for i, n in enumerate(arr):\n            n -= 1\n            \n            if n!=0 and n!=N-1 and rank[n-1] and rank[n+1]:\n                cnt[rank[n-1]] -= 1\n                cnt[rank[n+1]] -= 1\n                r = 1+rank[n-1]+rank[n+1]\n                cnt[r] += 1\n                rank[n+1+rank[n+1]-1] = r\n                rank[n-1-rank[n-1]+1] = r\n            \n            elif n!=0 and rank[n-1]:\n                cnt[rank[n-1]] -= 1\n                cnt[rank[n-1]+1] += 1\n                rank[n] = rank[n-1] + 1\n                rank[n-1-rank[n-1]+1] = rank[n]\n                \n            elif n!=N-1 and rank[n+1]:\n                cnt[rank[n+1]] -= 1\n                cnt[rank[n+1]+1] += 1\n                rank[n] = rank[n+1] + 1\n                rank[n+1+rank[n+1]-1] = rank[n]\n            else:\n                cnt[1] += 1\n                rank[n] = 1\n            \n            \n            if cnt[m]:\n                res = i + 1\n                \n        return res\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        A=arr\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        length = [0]*(n+2)\n        ans = -1\n        for i, a in enumerate(arr):\n            left, right = length[a-1], length[a+1]\n            if left == m or right == m:\n                ans = i\n            length[a-left] = length[a+right] = left + right + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, A: List[int], T: int, last = -1) -> int:\n        seen, ok = set(), set()\n        A = [i - 1 for i in A]\n        N = len(A)\n        P = [i for i in range(N)]\n        L = [1] * N\n        def find(x):\n            if x != P[x]:\n                P[x] = find(P[x])\n            return P[x]\n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            P[b] = a\n            L[a] += L[b]\n            return L[a]\n        step = 1\n        for i in A:\n            seen.add(i)\n            if 0 < i     and find(P[i - 1]) in ok: ok.remove(find(P[i - 1]))\n            if i + 1 < N and find(P[i + 1]) in ok: ok.remove(find(P[i + 1]))\n            if i - 1 in seen: L[i] = union(i, i - 1)\n            if i + 1 in seen: L[i] = union(i, i + 1)\n            if L[i] == T:\n                ok.add(i)\n            if len(ok):\n                last = step\n            step += 1\n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # length[i]\u8868\u793a\u4f4d\u7f6ei\u7684\u8fde\u7eed1\u957f\u5ea6\u4e3a\u591a\u957f\uff0c\u56e0\u4e3a\u6bcf\u6b21\u90fd\u662f\u63d2\u5165\u4e00\u4e2a\u65b0\u7684\u5143\u7d20\u4f7f\u539f\u672c\u4e0d\u8fde\u901a\u7684\u5de6\u53f3\u8fde\u901a\n        # \u6240\u4ee5\u5bf9\u4e8e\u5de6\u8fb9\u7684length[i -1]\u8868\u793a\u4ee5i-1\u4e3a\u7ed3\u675f\u7684\u8fde\u7eed1\u957f\u5ea6\u6709\u591a\u957f\n        # \u5bf9\u4e8e\u53f3\u8fb9\u7684length[i + 1]\u8868\u793a\u4ee5i+1\u4e3a\u5f00\u59cb\u7684\u8fde\u7eed1\u957f\u5ea6\u6709\u591a\u957f\n        length = [0] * (len(arr) + 2)\n        # count[i]\u8868\u793a\u957f\u5ea6\u4e3ai\u7684\u5e8f\u5217\u6709\u51e0\u4e2a\n        count = [0] * (len(arr) + 1)\n        res = -1\n        for step, i in enumerate(arr):\n            left, right = length[i - 1], length[i + 1]\n            length[i] = length[i - left] = length[i + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[i]] += 1\n            if count[m]:\n                res = step + 1\n        return res\n            \n", "class UF:\n    def __init__(self, n, m):\n        self.p = [i for i in range(n+1)]  # parent for each position\n        self.c = [0 for _ in range(n+1)]  # length of group for each position\n        self.m_cnt = 0                    # count of group with length m\n        self.m = m                        # m\n        \n    def union(self, i, j):\n        pi, pj = self.find(i), self.find(j)\n        if pi != pj:\n            if self.c[pi] == self.m: self.m_cnt -= 1  # if previous length at pi is m, decrement m_cnt by 1\n            if self.c[pj] == self.m: self.m_cnt -= 1  # if previous length at pj is m, decrement m_cnt by 1\n            self.p[pj] = pi                           # union, use pi at parent for pj\n            self.c[pi] += self.c[pj]                  # update new length at pi\n            if self.c[pi] == self.m: self.m_cnt += 1  # if new length at pi == m, increment m_cnt by 1\n            \n    def mark(self, i):                                \n        self.c[i] = 1                                 # when first visit a point, mark length as 1\n        if self.m == 1: self.m_cnt += 1               # if self.m == 1, increment m_cnt by 1\n        \n    def find(self, i):                                # find parent of i\n        if self.p[i] != i:\n            self.p[i] = self.find(self.p[i])\n        return self.p[i]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf, ans = UF(n, m), -1                                   # create union find and answer\n        for i, num in enumerate(arr, 1):\n            uf.mark(num)\n            if num-1 >= 1 and uf.c[num-1]: uf.union(num-1, num)  # if left neighbor is marked, union the two\n            if num+1 < n+1 and uf.c[num+1]: uf.union(num+1, num) # if right neighbor is marked, union the two\n                \n            if uf.m_cnt > 0: ans = i                             # if m_cnt > 0, meaning there exists some group with length m, update ans\n        return ans\n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [1] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \n\nclass Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        length = [0] * (len(A) + 2)\n        count = [0] * (len(A) + 1)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parents = [i for i in range(N + 1)]\n        sizes = [1 for i in range(N + 1)]\n        \n        def ufind(a):\n            if parents[a] == a:\n                return a\n            parents[a] = ufind(parents[a])\n            return parents[a]\n        \n        def uunion(a, b):\n            ra = ufind(a)\n            rb = ufind(b)\n            if ra != rb:\n                parents[rb] = parents[ra]\n                sizes[ra] += sizes[rb]\n                \n        def usize(a):\n            return sizes[ufind(a)]\n        \n        ans = -1\n        seen = set()\n        counter = collections.defaultdict(int)\n        \n        for i, x in enumerate(arr):\n            lft = 0\n            if x - 1 > 0 and (x - 1) in seen:\n                lft = usize(x - 1)\n                counter[lft] -= 1\n                uunion(x, x - 1)\n                \n            rgt = 0\n            if x + 1 <= N and (x + 1) in seen:\n                rgt = usize(x + 1)\n                counter[rgt] -= 1\n                uunion(x, x + 1)\n                \n            grp = lft + 1 + rgt\n            counter[grp] += 1\n            \n            if counter[m] > 0:\n                ans = max(ans, i + 1)\n                \n            seen.add(x)\n                \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:           \n        d = set([0,len(arr) + 1])\n        if m == len(arr): return m\n        for i in range(len(arr)-1,-1,-1):\n            if arr[i] - m - 1 in d:\n                exit = True\n                for j in range(arr[i] - m , arr[i]):\n                    if j in d:\n                        exit = False\n                        break\n                if exit:\n                    return i\n            if arr[i] + m+1 in d:\n                exit = True\n                for j in range(arr[i]+1,arr[i]+m+1):\n                    if j in d:\n                        exit = False\n                        break\n                if exit:\n                    return i\n            d.add(arr[i])\n        \n        return -1\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count = [0] * (len(arr)+1)\n        length = [0] * (len(arr)+2)\n        res = -1\n        for i, n in enumerate(arr):\n            left, right = length[n-1], length[n+1]\n            length[n] = length[n-left] = length[n+right] = left+right+1\n            count[left] -= 1\n            count[right] -= 1\n            count[left+right+1] += 1\n            if count[m] > 0:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        group_members = {}\n        in_group = [-1 for i in range(len(arr))]\n        existing_ms = 0\n        lastm = -1\n        for i, pos in enumerate(arr):\n            pos -= 1\n            group_at_left = (pos > 0) and (in_group[pos - 1] != -1)\n            group_at_right = (pos < len(arr) - 1) and (in_group[pos + 1] != -1)\n            len_left = len(group_members[in_group[pos - 1]]) if group_at_left else 0\n            len_right = len(group_members[in_group[pos + 1]]) if group_at_right else 0\n            if len_left == m:\n                existing_ms -= 1\n            if len_right == m:\n                existing_ms -= 1\n            if (not group_at_left) and (not group_at_right):\n                in_group[pos] = pos\n                group_members[pos] = [pos]\n                if m == 1:\n                    existing_ms += 1\n            elif group_at_left and group_at_right:\n                if (len_left + len_right + 1) == m:\n                    existing_ms += 1\n                merge_group = in_group[pos - 1]\n                in_group[pos] = merge_group\n                group_members[merge_group].append(pos)\n                group_members[merge_group] += group_members[in_group[pos + 1]]\n                for pos_right in group_members[in_group[pos + 1]]:\n                    in_group[pos_right] = merge_group\n            elif group_at_left:\n                if (len_left + 1) == m:\n                    existing_ms += 1\n                merge_group = in_group[pos - 1]\n                in_group[pos] = merge_group\n                group_members[merge_group].append(pos)\n            else:\n                if (len_right + 1) == m:\n                    existing_ms += 1\n                merge_group = in_group[pos + 1]\n                in_group[pos] = merge_group\n                group_members[merge_group].append(pos)\n            if existing_ms > 0:\n                lastm = i + 1\n        return lastm", "class Solution:\n    def findLatestStep(self, A, m):\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res      ", "class UF:\n    def __init__(self, n, m):\n        self.p = [i for i in range(n+1)]  # parent for each position\n        self.c = [0 for _ in range(n+1)]  # length of group for each position\n        self.m_cnt = 0                    # count of group with length m\n        self.m = m                        # m\n        \n    def union(self, i, j):\n        pi, pj = self.find(i), self.find(j)\n        if pi != pj:\n            if self.c[pi] == self.m: self.m_cnt -= 1  # if previous length at pi is m, decrement m_cnt by 1\n            if self.c[pj] == self.m: self.m_cnt -= 1  # if previous length at pj is m, decrement m_cnt by 1\n            self.p[pj] = pi                           # union, use pi at parent for pj\n            self.c[pi] += self.c[pj]                  # update new length at pi\n            if self.c[pi] == self.m: self.m_cnt += 1  # if new length at pi == m, increment m_cnt by 1\n            \n    def mark(self, i):                                \n        self.c[i] = 1                                 # when first visit a point, mark length as 1\n        if self.m == 1: self.m_cnt += 1               # if self.m == 1, increment m_cnt by 1\n        \n    def find(self, i):                                # find parent of i\n        if self.p[i] != i:\n            self.p[i] = self.find(self.p[i])\n        return self.p[i]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf, ans = UF(n, m), -1                                   # create union find and answer\n        for i, num in enumerate(arr, 1):\n            uf.mark(num)\n            if num-1 >= 1 and uf.c[num-1]: uf.union(num-1, num)  # if left neighbor is marked, union the two\n            if num+1 < n+1 and uf.c[num+1]: uf.union(num+1, num) # if right neighbor is marked, union the two\n                \n            if uf.m_cnt > 0: ans = i                             # if m_cnt > 0, meaning there exists some group with length m, update ans\n        return ans", "# 22:00\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # 1 - n\n        ret = -1\n        cnt = [[] for _ in range(len(arr))]\n        counter = collections.Counter()\n        for (i, n) in enumerate(arr):\n            n -= 1\n            cnt[n].extend([n, n])\n            if n - 1 >= 0 and cnt[n - 1]:\n                cnt[n][0] = cnt[n - 1][0]\n                counter[cnt[n - 1][1] - cnt[n - 1][0] + 1] -= 1\n            if n + 1 < len(arr) and cnt[n + 1]:\n                cnt[n][1] = cnt[n + 1][1]\n                counter[cnt[n + 1][1] - cnt[n + 1][0] + 1] -= 1\n            \n            cnt[cnt[n][0]][1] = cnt[n][1]\n            cnt[cnt[n][1]][0] = cnt[n][0]\n            counter[cnt[n][1] - cnt[n][0] + 1] += 1\n            \n            if counter[m] > 0:\n                ret = i + 1\n        \n        return ret\n\n# 2, 4, 0, 1, 3\n# [0, 0] [] [2, 2] [] [4, 4]\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        arr.append(n+1)\n        start = {}\n        finish = {}\n        last = -1\n        for level,i in enumerate(arr):\n            if i-1 not in finish: finish[i-1] = i \n            if i+1 not in start: start[i+1] = i\n\n            s, f = finish[i-1], start[i+1]\n            start[s] = f \n            finish[f] = s\n            \n            for os, of in [[i+1, start[i+1]], [finish[i-1], i-1]]:\n                if of-os+1 == m: last = level\n                \n            del start[i+1]\n            del finish[i-1]\n            \n        return last", "class Solution:\n    def findLatestStep(self, arr, k):\n        n=len(arr)\n        par=[-1]*(n+2)\n        count=[0]*(n+1)\n        ind=[0]*(n+1)\n        ans=-1\n        def find(node):\n            if par[node]==node:\n                return node\n            node=par[node]\n            return find(node)\n        for i in range(n):\n            cur=arr[i]\n            left=cur-1\n            right=cur+1\n            par[cur]=cur\n            count[cur]+=1\n            if par[left]!=-1:\n                p=find(left)\n                ind[count[p]]-=1\n                par[p]=cur\n                count[cur]+=count[p]\n            if par[right]!=-1:\n                p=find(right)\n                ind[count[p]]-=1\n                par[p]=cur\n                count[cur]+=count[p]\n            \n            ind[count[cur]]+=1\n            if ind[k]:\n                ans=i+1\n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        A = [0] * n\n        B = [[i, i+1] for i in range(n)]\n        \n        def get_len(i) :\n            return B[i][1] - B[i][0]\n        def merge(i, j) :\n            left = min(B[i][0], B[j][0])\n            right = max(B[i][1], B[j][1])\n            \n            B[left][1] = right\n            B[right-1][0] = left\n            \n            B[i][0] = B[j][0] = left\n            B[i][1] = B[j][1] = right\n                        \n        ret = -1\n        for i in range(n) :\n            j = arr[i] - 1\n            A[j] = 1\n            if j and A[j-1] :\n                if get_len(j-1) == m :\n                    ret = i\n                merge(j, j-1)\n            if j + 1 < n and A[j+1] :\n                if get_len(j+1) == m :\n                    ret = i\n                merge(j, j+1)\n            if B[j][1] - B[j][0] == m :\n                ret = i+1\n        return ret\n        \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        def find(u):\n            if parent[u] == u:\n                return u\n            else:\n                parent[u] = find(parent[u])\n                return parent[u]\n            \n        def union(u,v):\n            pu = find(u)\n            pv = find(v)\n            \n            if pv!=pu:\n                store[size[pv]]-=1\n                store[size[pu]]-=1\n                size[pu] += size[pv]\n                size[pv] = 0\n                store[size[pu]]+=1\n                parent[pv] = pu\n                \n            return size[pu]\n                \n                \n        \n        n = len(arr)\n        \n        parent = [0]*n ;size = [0]*n;val = [0]*n\n        store = defaultdict(int)\n        \n        for i in range(n):\n            arr[i]-=1\n            parent[i] = i\n        \n        ans = -1\n        for i in range(n):\n            size[arr[i]] =1\n            val[arr[i]] = 1\n            store[1]+=1\n            curr = 0\n            \n            if arr[i] - 1 >= 0 and val[arr[i]-1] == 1:\n                curr = union(arr[i],arr[i]-1)\n                \n            if arr[i]+1 < n and val[arr[i]+1] == 1:\n                curr = union(arr[i],arr[i]+1)\n                \n            if store[m] > 0:\n                ans = i+1\n                \n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        vals = [0 for _ in range(len(arr)+2)]\n        numGroups = 0\n        res = -1\n        for p in range(len(arr)):\n            i = arr[p]\n            if vals[i-1] == 0 and vals[i+1] == 0:\n                vals[i] = 1\n                if m == 1:\n                    numGroups += 1\n            else:\n                if vals[i-1] == 0:\n                    groupStart = i\n                else:\n                    groupStart = i - vals[i-1]\n                    if vals[i-1] == m:\n                        numGroups -= 1\n                if vals[i+1] == 0:\n                    groupEnd = i\n                else:\n                    groupEnd = i + vals[i+1]\n                    if vals[i+1] == m:\n                        numGroups -= 1\n                groupLength = groupEnd - groupStart + 1\n                vals[groupStart] = vals[groupEnd] = groupLength\n                if groupLength == m:\n                    numGroups += 1\n            if numGroups > 0:\n                res = p + 1\n        return res", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parents = [-1] * n\n        ranks = [0]*n\n        if m == n:\n            return m\n        ans = -1\n        \n        def find(n):\n            if parents[n] >= 0:\n                parents[n] = find(parents[n])\n            else:\n                return n       \n            return parents[n]\n        \n        def union(m, n):\n            pm, pn = find(m), find(n)\n            #print(pm, pn)\n            if ranks[pm] > ranks[pn]:\n                parents[pn] = pm\n                ranks[pm] += ranks[pn]\n            else:\n                parents[pm] = pn\n                ranks[pn] += ranks[pm]\n            return True\n        visited = set([])\n        for i, a in enumerate(arr):\n            a -= 1\n            ranks[a] = 1\n            for j in [a-1, a+1]:\n                if 0 <= j < n:\n                    if ranks[find(j)] == m:\n                        ans = i\n                    if j in visited:\n                        union(a, j)\n                        #print(parents)\n                        #print(ranks)\n            visited.add(a)\n        #print(\\\"=\\\"*20)\n        return ans\n                    \n", "\n    \nclass Solution:\n    def findLatestStep(self, arr, m):\n        n = len(arr)\n        if n == m:\n            return m\n        size = [0] * (n + 2)\n        res = -1\n        for i, x in enumerate(arr):\n            if size[x - 1] == m or size[x + 1] == m:\n                res = i\n            size[x - size[x - 1]] = size[x + size[x + 1]] = size[x - 1] + size[x + 1] + 1\n\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = [-1 for i in range(n+1)]\n        size = [0 for i in range(n+1)]\n        counts = [0 for i in range(n+1)]\n        fliped = set()\n        \n        res = -1\n        for i in range(0, len(arr)):\n            val = arr[i]\n            uf[val] = val\n            size[val] =1\n            counts[1] +=1\n            fliped.add(val)\n            if val-1 in fliped:\n                self.union(uf, val-1, val, size, counts)\n            if val+1 in fliped:\n                self.union(uf, val, val+1, size, counts)\n            if counts[m] > 0:\n                res = max(res, i+1)\n        return res\n            \n    \n    def root(self, uf: List[int], a:int)-> int:\n        root = a\n        while uf[root] != root:\n            root = uf[root]\n\n        next = a\n        while next != root:\n            next = uf[a]\n            uf[a] = root\n        return root\n        \n    def union(self, uf: List[int], a: int, b: int, size: List[int], counts: List[int]):\n        roota = self.root(uf, a)\n        rootb = self.root(uf, b)\n    \n        \n        large = max(roota, rootb)\n        small = min(roota, rootb)\n        uf[large]=small\n        counts[size[large]] -=1\n        counts[size[small]] -=1\n        \n        size[small] = size[large] + size[small]\n        counts[size[small]] +=1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ids = [i for i in range(n + 1)]\n        weights = [0 for i in range(n + 1)]\n        size_set = collections.defaultdict(int)\n        ans = -1\n        \n        def find(i: int) -> int:\n            while ids[i] != i:\n                ids[i] = ids[ids[i]]\n                i = ids[i]\n            return i\n        \n        def union(i: int, j: int):\n            i_id, j_id = find(i), find(j)\n            i_weight, j_weight = weights[i_id], weights[j_id]\n            new_weight = weights[i_id] + weights[j_id]\n            if weights[i_id] > weights[j_id]:\n                weights[i_id] = new_weight\n                ids[j_id] = i_id\n            else:\n                weights[j_id] = new_weight\n                ids[i_id] = j_id\n            size_set[i_weight] -= 1\n            size_set[j_weight] -= 1\n            size_set[new_weight] += 1\n        \n        for i, index in enumerate(arr):\n            weights[index] = 1\n            size_set[1] += 1\n            if index > 1:\n                prev_id = find(index - 1)\n                if weights[prev_id] > 0:\n                    union(prev_id, index)\n            if index < n:\n                next_id = find(index + 1)\n                if weights[next_id] > 0:\n                    union(index, next_id)\n            if size_set[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if(len(arr)==1): return 1\n        res = [[0 for i in range(2)]]*len(arr)\n        mx = -1\n        for ind, i in enumerate(arr):\n            i-=1\n            #Current Element\n            current = res[i]\n            prev = nxt = 0\n            #Last element of previous sequence\n            if i-1>-1 and res[i-1][0]==1:\n                prev = res[i-1][1]\n            #first element and last element of next sequence\n            if i<len(res)-1 and res[i+1][0]==1:\n                nxt = res[i+1][1]\n            \n            res[i] = [1,prev + nxt + 1]\n            if i-1>-1 and res[i-1][0]==1:\n                if res[i-1][1]==m or res[i-res[i-1][1]][1]==m:\n                    mx = max(ind, mx)\n                res[i-res[i-1][1]][1] = res[i][1]\n                res[i-1][1] = res[i][1]\n            if i<len(res)-1 and res[i+1][0]==1:\n                if res[i+1][1]==m or res[i+res[i+1][1]][1]==m:\n                    mx = max(ind, mx)\n                res[i+res[i+1][1]][1] = res[i][1]\n                res[i+1][1] = res[i][1]\n            if res[i][1]==m:\n                mx = max(ind+1, mx)\n        return mx            ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parents = [i for i in range(len(arr) + 1)]\n        cnt = [1] * (len(arr) + 1)#initial 1\n        groupCnt = [0] * (len(arr) + 1)\n        rank = [0] * (len(arr) + 1)\n        def find(x):\n            if x != parents[x]:\n                parents[x] = find(parents[x])\n            return parents[x]\n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                groupCnt[cnt[px]] -= 1\n                groupCnt[cnt[py]] -= 1\n                cnt[px] = cnt[py] = cnt[px] + cnt[py]\n                groupCnt[cnt[px]] += 1\n                if rank[px] > rank[py]:\n                    parents[py] = px\n                elif rank[px] < rank[py]:\n                    parents[px] = py\n                else:\n                    parents[py] = px\n                    rank[px] += 1\n        visited = [False] * (len(arr) + 1)\n        res = -1\n        for i, num in enumerate(arr):\n            groupCnt[1] += 1\n            if num - 1 > 0 and visited[num - 1]:\n                union(num, num - 1)\n            if num + 1 < len(arr) + 1 and visited[num + 1]:\n                union(num, num + 1)\n            visited[num] = True\n            if groupCnt[m] > 0:\n                res = i + 1\n        return res", "from collections import defaultdict as d\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        #define a range as [l,r]\n        left=dict() #left[r]=l\n        right=dict() #right[l]=r\n        cntLengths=d(lambda :0) #cntLengths[length]=cnts\n        ans=-1\n        for i in range(len(arr)):\n            num=arr[i]\n            lower=num\n            upper=num\n            \n            if num+1 in right.keys():\n                upper=right[num+1]\n                right.pop(num+1)\n                cntLengths[upper-num]-=1\n            if num-1 in left.keys():\n                lower=left[num-1]\n                left.pop(num-1)\n                cntLengths[num-lower]-=1\n            left[upper]=lower\n            right[lower]=upper\n            cntLengths[upper-lower+1]+=1\n            \n            if cntLengths[m]>0:\n                ans=i+1\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        '''\n        n = len(arr)\n        parents = list(range(n))\n        ranks = [0] * n\n        groupCounts = [0] * (n+1)\n        counts = [1] * n\n        visited = [False] * n\n        \n        def find(x):\n            if parents[x] != x:\n                parents[x] = find(parents[x])\n            \n            return parents[x]\n    \n        def union(x, y):\n            r1 = find(x)\n            r2 = find(y)\n            \n            if r1 != r2:\n                groupCounts[counts[r1]] -= 1\n                groupCounts[counts[r2]] -= 1\n                counts[r1] = counts[r2] = counts[r1] + counts[r2]\n                groupCounts[counts[r1]] += 1\n                \n                if ranks[r1] >= ranks[r2]:\n                    parents[r2] = r1\n                    ranks[r1] += 1\n                else:\n                    parents[r1] = r2\n                    ranks[r2] += 1\n        \n        last = -1\n        \n        for step, index in enumerate(arr):\n            index -= 1\n            groupCounts[1] += 1\n            if index-1 >= 0 and visited[index-1]:\n                union(index, index-1)\n            \n            if index+1 < n and visited[index+1]:\n                union(index, index+1)\n            \n            visited[index] = True\n            \n            if groupCounts[m]:\n                last = step + 1\n\n        return last\n        '''\n        n = len(arr)\n        length = [0] * (n+2)\n        count = [0] * (n+1)\n        ans = -1\n        \n        for step, index in enumerate(arr):\n            left = length[index-1]\n            right = length[index+1]\n            length[index-left] = length[index+right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[index-left]] += 1\n            \n            if count[m]:\n                ans = step + 1\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        steps = [0] * (len(arr) + 2)\n        count = defaultdict(int)\n        ans = -1\n        for i in range(len(arr)):\n            c = arr[i]\n            l = c - 1\n            r = c + 1\n            count[steps[l]] -= 1\n            count[steps[r]] -= 1\n            steps[c] = steps[l - steps[l] + 1] = steps[r + steps[r] - 1] = steps[l] + steps[r] + 1\n            count[steps[c]] += 1\n            if count[m] > 0:\n                ans = i + 1\n        return ans", "\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        count = [0] * (n+1)\n        length = [0] * ( n + 2)\n        ans = -1\n        for i,v in enumerate(arr):\n            left = length[v - 1]\n            right = length[v + 1]\n            length[v] = length[v - left] = length[v + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[v]] += 1\n            if count[m] >0:\n                ans = i + 1\n            \n        return ans\n            \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        n = len(arr)\n        UF = list(range(n + 2))\n        SZ = [0] * (n + 2)\n        \n        def find(x):\n            if UF[x] != x:\n                UF[x] = find(UF[x])\n            return UF[x]\n        \n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            if a != b:\n                if SZ[a] < SZ[b]:\n                    a, b = b, a\n                UF[b] = a\n                SZ[a] += SZ[b]\n            \n        ans = -1\n        cnt = 0\n        \n        for step, x in enumerate(arr):\n            UF[x] = x\n            SZ[x] = 1\n            cnt -= (SZ[find(x - 1)] == m) + (SZ[find(x + 1)] == m)\n                \n            if SZ[x - 1]: union(x, x - 1)\n            if SZ[x + 1]: union(x, x + 1)\n\n            if SZ[find(x)] == m: cnt += 1\n\n            if cnt > 0: ans = step + 1\n                \n            # print(step, x, UF, SZ, cnt, ans)\n                \n        return ans", "class Solution:\n    \n\n\n    #def findLatestStep(self, arr: List[int], m: int) -> int:\n    def fstep(self, arr, start_idx, end_idx , step, m):\n        # u can't hit end idx\n        n = end_idx - start_idx\n        if n == m:\n            return step+1\n        turnoff = arr[step]-1\n        if turnoff < start_idx or turnoff >= end_idx:\n            return self.fstep(arr, start_idx, end_idx , step-1, m)\n        \n        left = turnoff - start_idx\n        right = n - left -1\n\n        \n\n        lr = -1\n        rr = -1\n        if left >= m:\n            lr = self.fstep(arr, start_idx, start_idx+left, step-1, m)\n        if right >= m:\n            rr = self.fstep(arr, start_idx +left+1, end_idx,step-1, m)\n        \n        return max(lr,rr) \n\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        return self.fstep(arr,0, len(arr), len(arr)-1, m)\n\n                \n            \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        groups = {}\n        cnt = 0\n        result = -1\n        for i, a in enumerate(arr):\n            b = a - 1\n            if b in groups:\n                l = groups.pop(b)\n                groups[a] = groups[b - l + 1] = l + 1\n            else:\n                groups[a] = 1\n            if groups[a] == m:\n                cnt += 1\n            elif groups[a] - 1 == m:\n                cnt -= 1\n            c = a + 1\n            if c in groups:\n                l = groups.pop(a)\n                r = groups.pop(c)\n                groups[c + r - 1] = groups[a - l + 1] = l + r\n                cnt += (l + r) == m\n                cnt -= (l == m) + (r == m)\n            if cnt != 0:\n                result = i + 1\n        return result", "# 1562. Find Latest Group of Size M\n\ndef find_latest_step (arr, group_size):\n    n = len (arr)\n    left_end = [-1] * (n + 2)\n    right_end = [-1] * (n + 2)\n    value = [0] * (n + 2)\n\n    def merge (a, b, removes, appends):\n        if value[a] == 0 or value[b] == 0:\n            return\n        lend, rend = left_end[a], right_end[b]\n        removes.append (a - lend + 1)\n        removes.append (rend - b + 1)\n        appends.append (rend - lend + 1)\n        left_end[rend] = lend\n        right_end[lend] = rend\n\n    right_size_group_count = 0\n\n    latest_step = -1\n\n    step = 1\n    for elem in arr:\n        removes = []\n        appends = [1]\n        value[elem] = 1\n        left_end[elem] = elem\n        right_end[elem] = elem\n        merge (elem - 1, elem, removes, appends)\n        merge (elem, elem + 1, removes, appends)\n        right_size_group_count += - sum (1 for x in removes if x == group_size) + sum (1 for x in appends if x == group_size)\n        if right_size_group_count > 0:\n            latest_step = max (latest_step, step)\n        step += 1\n\n    return latest_step\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        return find_latest_step(arr, m)", "class Solution:\n    \n    def find(self, d, x):\n        while x != d[x]:\n            x = d[x]\n        return x\n    \n    def union(self, d, x, y):\n        px, py = self.find(d, x), self.find(d, y)\n        if px != py:\n            d[px] = py\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, step = len(arr), -1\n        s, d, d_len, d_rec = [0]*n, {i:i for i in range(n)}, [1]*n, dict()\n        for i in range(n):\n            num = arr[i] - 1\n            s[num] = 1\n            if num-1 >= 0 and s[num-1] == 1:\n                temp = d_len[self.find(d, num-1)]\n                self.union(d, num-1, num)\n                d_rec[temp] -= 1\n                d_len[num] += temp\n            if num+1 < n and s[num+1] == 1:\n                temp = d_len[self.find(d, num+1)]\n                self.union(d, num+1, num)\n                d_rec[temp] -= 1\n                d_len[num] += temp\n            d_rec[d_len[num]] = d_rec[d_len[num]]+1 if d_len[num] in list(d_rec.keys()) else 1\n            if m in list(d_rec.keys()) and d_rec[m] > 0:\n                step = i+1\n        return step\n", "from collections import defaultdict\n\nclass Solution:\n    def merge(self, x, y, f):\n        f[y] = x\n        t = y\n        while f[t] != t:\n            t = f[t]\n        l = y\n        while f[l] != l:\n            f[l], l = t, f[l]\n        self.d[self.len[t]] -= 1\n        self.d[self.len[y]] -= 1\n        self.len[t] += self.len[y]\n        self.d[self.len[t]] += 1\n\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        self.d = defaultdict(int)\n        self.f = list(range(len(arr)))\n        self.len = [0] * len(arr)\n        state = [0] * len(arr)\n        ans = -1\n        for i, num in enumerate(arr):\n            num = num - 1\n            self.len[num] = 1\n            self.d[1] += 1\n            if num > 0 and state[num - 1] == 1:\n                self.merge(num - 1, num, self.f)\n            if num < len(arr) - 1 and state[num + 1]:\n                self.merge(num, num + 1, self.f)\n            state[num] = 1\n            if m in self.d and self.d[m] > 0:\n                ans = i + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        mc = 0\n        step = -1\n        tuples = {}\n        for i in range(len(arr)):\n            pos = arr[i]\n            minPos, maxPos = pos, pos\n            if pos - 1 in tuples:\n                minPos = tuples[pos - 1][0]\n                if tuples[pos - 1][1] - minPos + 1 == m:\n                    mc -= 1\n                    if mc == 0:\n                        step = i\n            if pos + 1 in tuples:\n                maxPos = tuples[pos + 1][1]\n                if maxPos - tuples[pos + 1][0] + 1 == m:\n                    mc -= 1\n                    if mc == 0:\n                        step = i\n            tuples[minPos] = (minPos, maxPos)\n            tuples[maxPos] = tuples[minPos]\n            if maxPos - minPos + 1 == m:\n                mc += 1\n        if mc > 0:\n            step = len(arr)\n        return step", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count = {}\n        for i in range(1,len(arr)+1):\n            count[i] = 0\n        segment = {}\n        res = -1\n        for step, a in enumerate(arr):\n            #print(count)\n            if a-1 in segment and a+1 in segment:\n                count[abs(a - 1 - segment[a - 1]) + 1] -= 1\n                count[abs(a + 1 - segment[a + 1]) + 1] -= 1\n                count[abs(segment[a+1] - segment[a-1]) + 1] += 1\n                left = segment[a-1]\n                right = segment[a+1]\n                del segment[a-1]\n                del segment[a+1]\n                segment[left] = right\n                segment[right] = left\n                \n            elif a-1 in segment:\n                count[abs(a - 1 - segment[a - 1]) + 1] -= 1\n                count[abs(a - 1 - segment[a - 1]) + 2] += 1\n                left = segment[a-1]\n                right = a\n                del segment[a-1]\n                segment[left] = right\n                segment[right] = left\n                \n            elif a+1 in segment:\n                count[abs(a + 1 - segment[a + 1]) + 1] -= 1\n                count[abs(a + 1 - segment[a + 1]) + 2] += 1\n                left = a\n                right = segment[a+1]\n                del segment[a+1]\n                segment[left] = right\n                segment[right] = left\n                \n            else:\n                count[1] += 1\n                segment[a] = a\n            \n            if count[m] > 0:\n                \n                res = step+1\n        #print(count)\n        return res\n            \n            \n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def helper(start, end, curStep):\n            if curStep == 1: return curStep if m == 1 else -1\n            \n            if end - start + 1 < m: return -1\n            \n            elif end - start + 1 == m: return curStep\n            \n            else:    \n                idx = arr[curStep - 1]\n\n                if idx < start or idx > end: return helper(start, end, curStep - 1)\n\n                else: return max(helper(start, idx - 1, curStep - 1), helper(idx + 1, end, curStep - 1))\n                \n        return helper(1, len(arr), len(arr))\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        size = len(arr)\n        if m == size:\n            return m\n\n        length, ans = [0] * (len(arr) + 2), -1\n        for i, n in enumerate(arr):\n            left, right = length[n - 1], length[n + 1]\n            if left == m or right == m:\n                ans = i\n            length[n - left] = length[n + right] = (left + right + 1)\n        return ans", "# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         arr = arr[::-1]\n#         s = \\\"1\\\"*len(arr)\n#         step = len(arr)\n#         for j in arr:\n#             group = s.split(\\\"0\\\")\n#             group = list(set(group))\n#             if \\\"1\\\"*m in group:\n#                 return step\n#             step -=1\n#             s = s[:j-1] + \\\"0\\\" + s[j:]\n#         return -1\n            \n            \nclass UF:\n    def __init__(self, n, m):\n        self.p = [i for i in range(n+1)]  # parent for each position\n        self.c = [0 for _ in range(n+1)]  # length of group for each position\n        self.m_cnt = 0                    # count of group with length m\n        self.m = m                        # m\n        \n    def union(self, i, j):\n        pi, pj = self.find(i), self.find(j)\n        if pi != pj:\n            if self.c[pi] == self.m: self.m_cnt -= 1  # if previous length at pi is m, decrement m_cnt by 1\n            if self.c[pj] == self.m: self.m_cnt -= 1  # if previous length at pj is m, decrement m_cnt by 1\n            self.p[pj] = pi                           # union, use pi at parent for pj\n            self.c[pi] += self.c[pj]                  # update new length at pi\n            if self.c[pi] == self.m: self.m_cnt += 1  # if new length at pi == m, increment m_cnt by 1\n            \n    def mark(self, i):                                \n        self.c[i] = 1                                 # when first visit a point, mark length as 1\n        if self.m == 1: self.m_cnt += 1               # if self.m == 1, increment m_cnt by 1\n        \n    def find(self, i):                                # find parent of i\n        if self.p[i] != i:\n            self.p[i] = self.find(self.p[i])\n        return self.p[i]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf, ans = UF(n, m), -1                                   # create union find and answer\n        for i, num in enumerate(arr, 1):\n            uf.mark(num)\n            if num-1 >= 1 and uf.c[num-1]: uf.union(num-1, num)  # if left neighbor is marked, union the two\n            if num+1 < n+1 and uf.c[num+1]: uf.union(num+1, num) # if right neighbor is marked, union the two\n                \n            if uf.m_cnt > 0: ans = i                             # if m_cnt > 0, meaning there exists some group with length m, update ans\n        return ans", "from collections import defaultdict\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        max_time = 0\n        n = len(arr)\n        \n        curr = [0 for _ in range(n)]\n        \n        parent = [i for i in range(n)]\n        size = [1 for i in range(n)]\n        \n        size_tracker = defaultdict(lambda: 0)\n        \n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y, time):\n            xs, ys = find(x), find(y)\n            if xs == ys: return False\n            if size[xs] < size[ys]:\n                xs, ys = ys, xs\n            size_tracker[size[xs]] -= 1\n            size_tracker[size[ys]] -= 1\n            size[xs] += size[ys]\n            size_tracker[size[xs]] += 1\n            if size_tracker[m] > 0: max_time = time + 1\n            parent[ys] = xs\n            return True\n        \n        for t in range(n):\n            x = arr[t] - 1\n            curr[x] = 1\n            size_tracker[1] += 1\n            if x > 0 and curr[x-1] == 1:\n                union(x, x-1, t)\n            if x < len(curr)-1 and curr[x+1] == 1:\n                union(x, x+1, t)\n            if size_tracker[m] > 0:\n                max_time = t + 1\n                \n        return max_time if max_time > 0 else -1\n        \n        \n        \n            \n            \n            \n            \n", "class Solution:\n    class UnionFind():\n        def __init__(self, n):\n            self.parents = list(range(n))\n            self.sizes = [0] * n\n        \n        def find(self, i):\n            #print(i, self.parents)\n            if i != self.parents[i]:\n                self.parents[i] = self.find(self.parents[i])\n            return self.parents[i]\n        \n        def union(self, i, j):\n            pi = self.find(i)\n            pj = self.find(j)\n            \n            if pi == pj:\n                return\n            \n            if self.sizes[pi] > self.sizes[pj]:\n                self.parents[pj] = pi\n                self.sizes[pi] += self.sizes[pj]\n            else:\n                self.parents[pi] = pj\n                self.sizes[pj] += self.sizes[pi]\n            \n            \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        last_seen = -1\n        if n == m:\n            return n\n        union_find = self.UnionFind(n)\n        \n        for step, num in enumerate(arr):\n            i = num - 1\n            #print(i)\n            #print(union_find.parents)\n            #print(union_find.sizes)\n            union_find.sizes[i] += 1\n            for j in [i - 1, i + 1]:\n                if 0 <= j < n:\n                    pj = union_find.find(j)\n                    if union_find.sizes[pj] == m:\n                        last_seen = step\n                    if union_find.sizes[pj] > 0:\n                        union_find.union(i, pj)\n        return last_seen\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        counter = collections.defaultdict(int)\n        count = collections.defaultdict(int)\n        ans = -1\n        term = 1\n        for i in arr:\n            if i - 1 in counter and i + 1 in counter:\n                left_most = counter[i - 1]\n                right_most = counter[i + 1]\n                counter[left_most] = right_most\n                counter[right_most] = left_most\n                count[right_most - left_most + 1] += 1\n                count[i - left_most] -= 1\n                count[right_most - i] -= 1\n                if i - 1 != left_most:\n                    del counter[i - 1]\n                if i + 1 != right_most:\n                    del counter[i + 1]\n                \n                \n            elif i - 1 in counter:\n                left_most = counter[i - 1]\n                counter[left_most] = i\n                counter[i] = left_most\n                count[i - left_most] -= 1\n                count[i - left_most + 1] += 1\n                if i - 1 != left_most:\n                    del counter[i - 1]\n            \n            elif i + 1 in counter:\n                right_most = counter[i + 1]\n                counter[right_most] = i\n                counter[i] = right_most\n                count[right_most - i] -= 1\n                count[right_most - i + 1] += 1\n                if i + 1 != right_most:\n                    del counter[i + 1]\n                \n            else:\n                counter[i] = i\n                count[1] += 1\n            \n            if m in count and count[m] > 0:\n                ans = term\n            \n            term += 1\n\n        return ans\n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n#         groups = [\\\"0\\\" for _ in range(len(arr))]\n#         dp = defaultdict(lambda:0)\n#         ctn = False\n#         pdx = -1\n        \n#         for i in range(len(arr)): groups[arr[i]-1] = \\\"1\\\"\n        \n#         for i in range(len(groups)):\n#             if groups[i] == \\\"0\\\":\n#                 ctn = False\n#             else:\n#                 if not ctn:\n#                     dp[i] += 1\n#                     ctn = True; pdx = i\n#                 else:\n#                     dp[pdx] += 1\n        \n#         for key in dp:\n#             if dp[key] == m: return len(arr)\n#         keys = list(sorted(dp.keys()))\n#         for i in range(len(arr))[::-1]:\n#             idx = bisect.bisect_left(keys, arr[i]-1)\n#             if ((0 < idx < len(keys) and keys[idx] != arr[i]-1)) or (idx == len(keys)): idx -= 1\n#             key = keys[idx]\n#             dif = arr[i]-1 - key\n#             if dp[key]-dif-1 != 0:\n#                 dp[arr[i]] = dp[key]-dif-1\n#                 bisect.insort(keys, arr[i])\n#                 if dp[arr[i]] == m: return i\n#             dp[key] = dif\n#             if dp[key] == m:\n#                 return i\n#             if dp[key] == 0: del dp[key]\n    \n#         return -1\n        \n        #\u53cc list\n        # length = [0] * (len(arr) + 2)\n        # count = [0] * (len(arr) + 1)\n        # res = -1\n        # for i, a in enumerate(arr):\n        #     left, right = length[a - 1], length[a + 1]\n        #     length[a] = length[a - left] = length[a + right] = left + right + 1\n        #     count[left] -= 1\n        #     count[right] -= 1\n        #     count[length[a]] += 1\n        #     if count[m]:\n        #         res = i + 1\n        # return res\n        \n        #\u7b80\u5355\u7248 \u901a\u8fc7\u8bb0\u5f55\u5de6\u53f3border\n        if m==len(arr): return m\n        \n        border=[-1]*(len(arr)+2)\n        ans=-1\n        \n        for i in range(len(arr)):\n            left=right=arr[i]\n            #left = arr[i]-1; right = arr[i]+1\n            if border[right+1]>=0: right=border[right+1]\n            if border[left-1]>=0: left=border[left-1]\n            border[left], border[right] = right, left\n            if (right-arr[i]==m) or (arr[i]-left==m):\n                ans=i\n        \n        return ans\n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        a = [(1, len(arr))]\n        if m == len(arr): return len(arr)\n        \n        def binSearch(ar, num) -> int:\n            if len(ar) == 1:\n                if ar[0][0] <= num <= ar[0][1]:\n                    return 0\n                \n            lo, hi = 0, len(ar)-1\n            while lo <= hi:\n                # print(ar, num, lo, hi)\n                mid = (lo+hi)//2\n                if ar[mid][1] < num:\n                    lo = mid+1\n                elif num < ar[mid][0]:\n                    hi = mid\n                elif ar[mid][0] <= num <= ar[mid][1]:\n                    return mid\n                else:\n                    return -1\n            return -1\n                    \n            \n        for i, n in enumerate(arr[::-1]):\n            idx = binSearch(a, n)\n            # print('binSearch', a, n, idx)\n            el = a[idx]\n            if el[0] == n: # left border\n                if el[1] == n: # (1,1)\n                    del a[idx]\n                else:\n                    a[idx] = (n+1, el[1])\n            elif el[1] == n: # right border\n                if el[0] == n: # (1,1)\n                    del a[idx]\n                else:\n                    a[idx] = (el[0], n-1)\n            else: # middle\n                a[idx] = (el[0], n-1)\n                a.insert(idx+1, (n+1, el[1]))\n            # print(a, n, el)\n            if n-el[0] == m or el[1]-n == m:\n                return len(arr)-i-1\n                    \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        da = {}\n        db = {}\n        n = len(arr)\n        s = [0 for i in range(len(arr))]\n        cnts = 0\n        step = 0\n        for e in arr:\n            step += 1\n            x = e-1\n            s[x] = 1\n            st = x\n            ed = x\n            da[x] = (x, x)\n            db[x] = (x, x)\n            if x > 0 and s[x-1] == 1:\n                p = db[x-1]\n                if (p[1]+1-p[0] == m):\n                    cnts -= 1\n                st = p[0]\n                da[st] = (st, ed)\n                del db[p[1]]\n                db[ed] = (st, ed)\n                del da[x]\n            if x < n-1 and s[x+1] == 1:\n                q = da[x+1]\n                if (q[1]+1-q[0] == m):\n                    cnts -= 1\n                ed = q[1]\n                da[st] = (st, ed)\n                del da[q[0]]\n                db[ed] = (st, ed)\n                del db[x]\n\n            if (ed+1-st) == m:\n                cnts += 1\n            if cnts > 0:\n                ans = step\n\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count = [0] * (len(arr) + 2)\n        length = [0] * (len(arr) + 2)\n        ans = -1\n        for i, a in enumerate(arr):\n            left, right = length[a-1], length[a+1]\n            length[a] = left + right + 1\n            length[a - left] = length[a]\n            length[a + right] = length[a]\n            count[left] -= 1\n            count[right] -= 1\n            count[left + right + 1] += 1\n            if count[m] > 0:\n                ans = i + 1\n        return ans        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m : return m\n        res = -1\n        ln = [0] * (len(arr) + 2)\n        \n        for i, a in enumerate(arr):\n            left, right = ln[a - 1], ln[a + 1]\n            if left == m or right == m : res = i\n            ln[a - left] = ln[a + right] = left + right + 1\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        def find(node):\n            if parent[node] < 0:\n                return node\n            else:\n                return find(parent[node])\n    \n        def union(n1,n2):\n            p1 = find(n1)\n            p2 = find(n2)\n            p1_size = abs(parent[p1])\n            p2_size = abs(parent[p2])\n            if p1_size == m or p2_size == m:\n                ans = count\n            if p1_size < p2_size:\n                tmp = parent[p1]\n                parent[p1] = p2\n                parent[p2] += tmp\n            else:\n                tmp = parent[p2]\n                parent[p2] = p1\n                parent[p1] += tmp\n        \n        n = len(arr)\n        ans = -1\n        \n        parent = [-1]*(n+1)\n        bitvalue = [0]*(n+1)\n        for count,i in enumerate(arr,1):\n            if i+1 <=n and bitvalue[i+1] == 1 and i-1 > 0 and bitvalue[i-1] == 1:\n                if abs(parent[find(i+1)]) == m or abs(parent[find(i-1)]) == m:\n                    ans = count-1\n                union(i,i+1)\n                union(i,i-1)\n            elif i+1 <= n and bitvalue[i+1] == 1:\n                if abs(parent[find(i+1)]) == m:\n                    ans = count-1\n                union(i,i+1)\n            elif i-1 > 0 and bitvalue[i-1] == 1:\n                if abs(parent[find(i-1)]) == m:\n                    ans = count-1\n                union(i,i-1)\n            bitvalue[i] = 1\n            if abs(parent[find(i)]) == m:\n                ans = count\n            # print(parent)\n        return ans\n                \n", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        index2len, len_cnt, last_index = defaultdict(int), Counter(), -1        \n        for i, p in enumerate(a):    \n            left_len, right_len = index2len[p-1], index2len[p+1]\n            new_len = left_len + 1 + right_len\n            index2len[p-left_len] = index2len[p+right_len] = new_len\n            len_cnt[left_len] -= 1\n            len_cnt[right_len] -= 1                \n            len_cnt[new_len] += 1 \n            if len_cnt[m] > 0: last_index = i + 1            \n        return last_index", "class Solution:\n    def findLatestStep(self, A, m):\n        length = [0] * (len(A) + 2)\n        count = [0] * (len(A) + 1)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        alls=[]\n        n=len(arr)\n        alls.append([1,n])\n        \n        count=n\n        \n        if m==n:\n            return n\n        \n        for j in range(len(arr)):\n            a=arr[n-j-1]\n            \n            count-=1\n            for i in range(len(alls)):\n                if a>=alls[i][0] and a<=alls[i][1]:\n                    left=[alls[i][0],a-1]\n                    right=[a+1,alls[i][1]]\n                    \n                    del alls[i]\n                    \n                    if left[1]-left[0]==m-1:\n                        return count\n                    \n                    if right[1]-right[0]==m-1:\n                        return count\n                    \n                    if left[1]>=left[0] and left[1]-left[0]>m-1:\n                        alls.append(left)\n                    if right[1]>=right[0] and right[1]-right[0]>m-1:\n                        alls.append(right)\n                        \n                    break\n            #print(alls)\n                        \n        \n        return -1\n                        \n                    \n                \n", "class UF:\n    def __init__(self, n, m):\n        self.p = [i for i in range(n+1)]\n        self.c = [0 for _ in range(n+1)]\n        self.m_cnt = 0\n        self.m = m\n        \n    def union(self, i, j):\n        pi, pj = self.find(i), self.find(j)\n        if pi != pj:\n            self.p[pj] = pi\n            if self.c[pj] == self.m: self.m_cnt -= 1\n            if self.c[pi] == self.m: self.m_cnt -= 1\n            #self.c[pj] += self.c[pi]\n            self.c[pi] += self.c[pj]\n            if self.c[pi] == self.m: self.m_cnt += 1 \n            \n    def mark(self, i):\n        self.c[i] = 1\n        if self.c[i] == self.m: self.m_cnt += 1\n        \n    def find(self, i):\n        if self.p[i] != i:\n            self.p[i] = self.find(self.p[i])\n        return self.p[i]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UF(n, m)\n        ans = -1\n        for i, num in enumerate(arr, 1):\n            uf.mark(num)\n            if num-1 >= 1 and uf.c[num-1]:\n                uf.union(num-1, num)\n            if num+1 < n+1 and uf.c[num+1]:\n                uf.union(num+1, num)\n            if uf.m_cnt > 0:    \n                ans = i\n        return ans                ", "class Solution:\n    def findLatestStep(self, A, m):\n        length = [0] * (len(A) + 2)\n        count = [0] * (len(A) + 1)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res        ", "from collections import defaultdict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        intervals = {}\n        lengths = defaultdict(int)\n        \n        found = -1\n        for i, val in enumerate(arr):\n            if (val-1) not in intervals and (val+1) not in intervals:\n                intervals[val] = val\n                lengths[1] += 1\n                \n            if (val-1) in intervals and (val+1) not in intervals:\n                prev_left = intervals[val-1]\n                prev_right = val-1\n                lengths[prev_right - prev_left + 1] -= 1\n                lengths[prev_right - prev_left + 2] += 1\n                \n                intervals[prev_left] = val\n                intervals[val] = prev_left\n                \n            if (val-1) not in intervals and (val+1) in intervals:\n                prev_right = intervals[val+1]\n                prev_left = val+1\n                lengths[prev_right - prev_left + 1] -= 1\n                lengths[prev_right - prev_left + 2] += 1\n                \n                intervals[prev_right] = val\n                intervals[val] = prev_right\n            \n            if (val-1) in intervals and (val+1) in intervals:\n                prev_right = intervals[val+1]\n                prev_left = intervals[val-1]\n                \n                lengths[prev_right-val] -= 1\n                lengths[val-prev_left] -= 1\n                lengths[prev_right-prev_left+1] += 1\n                \n                intervals[prev_left] = prev_right\n                intervals[prev_right] = prev_left\n                if val+1 != prev_right:\n                    del intervals[val+1]\n                if val-1 != prev_left:\n                    del intervals[val-1]\n                    \n            if lengths[m] != 0:\n                found = i+1\n        \n        return found", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N    = len(arr)\n        par  = [0] * N\n        rank = [0] * N\n        sz   = [0] * N\n        ops = {}\n        \n        for n in range(N):\n            par[n] = n\n        \n        def find(u):\n            if par[u] == u:\n                return u\n            par[u] = find(par[u])\n            return par[u]\n        \n        def merge(u, v):\n            up, vp = find(u), find(v)\n            \n            if rank[up] < rank[vp]:\n                par[up] = vp\n                sz[vp] += sz[up]\n                sz[up] = 0    \n            elif rank[vp] < rank[up]:\n                par[vp] = up\n                sz[up] += sz[vp]\n                sz[vp] = 0\n            else:\n                par[up] = vp\n                sz[vp] += sz[up]\n                rank[vp] += 1\n                sz[up] = 0\n                \n        \n        snap = [0] * (N)\n        last = -1\n        \n        for p, n in enumerate(arr):\n            n -= 1\n            snap[n] = 1\n            sz[n] = 1\n            mark = False\n            \n            if (n - 1) >= 0 and snap[n - 1] == 1:\n                p1 = find(n - 1)\n                if p1 in ops:\n                    del ops[p1]\n                mark = True\n                merge(n - 1, n)\n                \n            if n + 1 < N and snap[n + 1] == 1:\n                p1 = find(n + 1)\n                if p1 in ops:\n                    del ops[p1]\n                mark = True\n                merge(n, n + 1)\n            \n            para = find(n)\n            if sz[para] == m:\n                ops[para] = 1\n            \n            if ops:\n                last = p\n        \n        if last == -1:\n            return -1\n        return last + 1\n            \n            \n", "from collections import defaultdict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        s_d = defaultdict(list)\n        e_d = defaultdict(list)\n        lengths = defaultdict(int)\n        latest = -1\n        step = 1\n        for i in arr:\n            \n            end = i - 1\n            start = i + 1\n            \n            if end in e_d and start in s_d:\n                s_l = s_d[start]\n                e_l = e_d[end]\n                x = s_l[1] - s_l[0] + 1\n                y = e_l[1] - e_l[0] + 1\n                lengths[x] -= 1\n                lengths[y] -= 1\n                if lengths[x] == 0:\n                    del lengths[x]\n                if lengths[y] == 0:\n                    del lengths[y]\n                del s_d[start]\n                del e_d[end]\n                \n                l = [e_l[0],s_l[1]]\n                length = l[1] - l[0] + 1                \n                \n                lengths[length] += 1\n                s_d[l[0]] = l \n                e_d[l[1]] = l\n            elif end in e_d:\n                e_l = e_d[end]\n                x = e_l[1] - e_l[0] + 1 \n                lengths[x] -= 1\n                if lengths[x] == 0:\n                    del lengths[x]\n                    \n                del e_d[end]\n                \n                e_l[1] = i \n                e_d[e_l[1]] = e_l\n                length = e_l[1] - e_l[0] + 1\n                lengths[length] += 1\n                \n            elif start in s_d:\n                s_l = s_d[start]\n                x = s_l[1] - s_l[0] + 1 \n                lengths[x] -= 1 \n                if lengths[x] == 0:\n                    del lengths[x]\n                    \n                del s_d[start]\n                s_l[0] = i \n                s_d[i] = s_l\n                length = s_l[1] - s_l[0] + 1\n                lengths[length] += 1\n            else:\n                \n                l = [i,i]\n                s_d[i] = l \n                e_d[i] = l \n                \n                lengths[1] += 1\n            # print(i,s_d,lengths)\n            if m in lengths:\n                latest = step\n            step += 1\n        return latest\n                \n", "from collections import defaultdict\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        bits = [0] * n\n        \n        groups = defaultdict(int)\n        \n        \n        corner = defaultdict(int)\n        \n        result = -1\n        for step, i in enumerate(arr):\n            i = i -1\n            bits[i] = 1\n            group = 1\n            \n            j = i-1\n            group += corner[j]\n            groups[corner[j]] -= 1\n                \n            j = i+1\n            group += corner[j]\n            groups[corner[j]] -= 1\n            \n            # print(corner)\n            \n            groups[group] += 1\n            corner[i - corner[i-1]] = group\n            corner[i + corner[i+1]] = group\n            \n            # print(corner)\n            \n            # print(groups)\n            \n            if groups[m]:\n                result = step\n                \n        return result + 1 if result >= 0 else -1\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        n = len(arr)\n        \n        rank = [0 for i in range(n + 1)]\n        fa  =  [i for i in range(n + 1)]\n        def getfa(x):\n            if fa[x] == x: return x\n            fa[x] = getfa(fa[x])\n            return fa[x]\n        \n        def union(a, b):\n            p, q = getfa(a), getfa(b)\n            if p != q:\n                if rank[p] >= rank[q]:\n                    fa[q] = p\n                    rank[p] += rank[q]\n                    return p\n                else:\n                    fa[p] = q\n                    rank[q] += rank[p]\n                    return q\n                \n            return False\n        \n        cc = Counter()\n        last = -1\n        for i, num in enumerate(arr):\n            l, r = num - 1, num + 1\n            rank[num] = 1\n            cc[1] += 1\n            if rank[l]:\n                rl = getfa(l)\n                cc[1] -= 1\n                cc[rank[rl]] -= 1\n                newroot = union(num, rl)\n                cc[rank[newroot]] += 1\n            if r <= n and rank[r]:\n                rl = getfa(num)\n                cc[rank[rl]] -= 1\n                rr = getfa(r)\n                cc[rank[rr]] -= 1\n                newroot = union(rl, rr)\n                cc[rank[newroot]] += 1\n            if cc[m] > 0:\n                last = i + 1\n                \n        return last\n                \n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        self.parent = [i for i in range(n + 1)]\n        self.rank = [1 for _ in range(n + 1)]\n        self.result = 0\n        self.groups = set()\n        def find_parent(a):\n            if a != self.parent[a]:\n                self.parent[a] = find_parent(self.parent[a])\n            return self.parent[a]\n        \n        def union(a, b, check=False):\n            parent_a = find_parent(a)\n            parent_b = find_parent(b)\n            \n            if parent_a == parent_b:\n                if self.rank[parent_a] == m:\n                    self.groups.add(parent_a)\n                return\n            if self.rank[parent_a] < self.rank[parent_b]:\n                parent_a, parent_b = parent_b, parent_a\n            self.parent[parent_b] = parent_a\n            self.rank[parent_a] += self.rank[parent_b]\n            \n            if parent_a in self.groups:\n                self.groups.remove(parent_a)\n            if parent_b in self.groups:\n                self.groups.remove(parent_b)\n            \n            if check:\n                if self.rank[parent_a] == m:\n                    self.groups.add(parent_a)\n                \n        self.binary = [0 for _ in range(n + 2)]\n        result = -1\n        for idx in range(n):\n            num = arr[idx]\n            if self.binary[num-1] == 1 and self.binary[num + 1] == 1:\n                union(num-1, num)\n                union(num, num + 1, True)\n                #print(self.rank[num-1], self.rank[num], self.rank[num + 1])\n                \n                \n            elif self.binary[num - 1] == 1:\n                union(num, num - 1, True)\n            elif self.binary[num + 1] == 1:\n                union(num, num + 1, True)\n            else:\n                union(num, num, True)\n            if len(self.groups) > 0:\n                result = idx + 1\n            self.binary[num] = 1\n            #print(self.groups, self.binary, self.parent)\n            \n        return result ", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dp = [(-1, -1)] * (len(arr) + 1)\n        groups = collections.defaultdict(int)\n        if len(arr) == 1:\n            return 1\n        res = -1\n        for i, a in enumerate(arr):\n            leftPos, rightPos = a, a\n            if a == 1:\n                rightPos = a if dp[a+1][1] == -1 else dp[a+1][1]\n            elif a == len(arr):\n                leftPos = a if  dp[a-1][0] == -1 else dp[a-1][0]\n            else:\n                leftPos = a if  dp[a-1][0] == -1 else dp[a-1][0]\n                rightPos = a if dp[a+1][1] == -1 else dp[a+1][1]\n            \n            dp[a] = (leftPos, rightPos)\n            dp[leftPos] = (leftPos, rightPos)\n            dp[rightPos] = (leftPos, rightPos)\n\n            groups[rightPos - leftPos + 1] += 1\n            groups[a - leftPos] -= 1\n            groups[rightPos - a] -= 1\n            if groups[m] >= 1:\n                res = i + 1\n        return res\n\n        # length = [0] * (len(arr) + 2)\n        # groups = [0] * (len(arr) + 1)\n        # res = -1\n        # for i, a in enumerate(arr):\n        #     left, right = length[a - 1], length[a + 1]\n        #     total = left + right + 1\n        #     length[a] = length[a - left] = length[a + right] = total\n        #     groups[left] -= 1\n        #     groups[right] -= 1\n        #     groups[total] += 1\n        #     if groups[m] > 0:\n        #         res = i + 1\n        # return res\n", "class Solution:\n    \n    def find_root(self, arr, idx):\n        assert arr[idx][0] != -1\n        while(arr[idx][0] != idx):\n            idx = arr[idx][0]\n        return idx\n        \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        tree_root = [[-1,-1] for i in range(len(arr))]\n        \n        if m == len(arr):\n            return m\n        \n        last_t = -1\n        for i in range(len(arr)):\n            bit_idx = arr[i] - 1\n            for j in range(bit_idx-1, bit_idx+2):\n                if 0 <= j < len(arr):\n                    if tree_root[j][0] != -1 and tree_root[self.find_root(tree_root, j)][1] == m:\n                        last_t = i\n                        \n            tree_root[bit_idx][0] = bit_idx\n            tree_root[bit_idx][1] = 1\n            if bit_idx > 0 and tree_root[bit_idx-1][0] != -1:\n                left_node_root = self.find_root(tree_root, bit_idx-1)\n                tree_root[left_node_root][0] = bit_idx\n                tree_root[bit_idx][1] += tree_root[left_node_root][1]\n            if bit_idx < len(arr)-1 and tree_root[bit_idx+1][0] != -1:\n                right_node_root = self.find_root(tree_root, bit_idx+1)\n                tree_root[right_node_root][0] = bit_idx\n                tree_root[bit_idx][1] += tree_root[right_node_root][1]\n            \n            # for j in range(len(arr)):\n            #     if (tree_root[j][0] == j and tree_root[j][1] == m):\n            #         last_t = i + 1\n            \n            # if (tree_root[bit_idx][1] == m):\n            #     last_t = i + 1\n        \n        return last_t", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n#         n = len(arr)\n#         groups = defaultdict(set)\n#         parents = [i for i in range(n)]\n#         size = [0] * n\n        \n#         def find(node):\n#             if parents[node] == node:\n#                 return node\n#             parent = find(parents[node])\n#             return parent\n        \n#         def union(a, b):\n#             para = find(a)\n#             parb = find(b)\n#             if para != parb:\n#                 groups[parb].update(groups[para])\n#                 groups.pop(para)\n#                 parents[para] = parb\n                \n#         def get_size(a):\n#             parent = find(parents[a])\n#             return len(groups[parent])\n        \n#         def update(i):\n#             check = get_size(i)\n#             sizes[check] -= 1\n#             if sizes[check] == 0:\n#                 sizes.pop(check)\n        \n#         arr = [i-1 for i in arr]\n#         step = 0\n#         ans = -1\n#         sizes = Counter()\n#         for i in arr:\n#             step += 1\n#             size[i] += 1\n#             groups[i].add(i)\n#             sizes[1] += 1\n#             if i-1 >= 0 and i+1 < n and size[i-1] and size[i+1]:\n#                 update(i-1)\n#                 update(i+1)\n#                 update(i)\n#                 union(i, i-1)\n#                 union(i+1, i-1)\n#                 new_size = get_size(i-1)\n#                 sizes[new_size] += 1\n#             elif i-1 >= 0 and size[i-1]:\n#                 update(i-1)\n#                 update(i)\n#                 union(i, i-1)\n#                 new_size = get_size(i-1)\n#                 sizes[new_size] += 1\n#             elif i+1 < n and size[i+1]:\n#                 update(i+1)\n#                 update(i)\n#                 union(i, i+1)\n#                 new_size = get_size(i+1)\n#                 sizes[new_size] += 1\n#             if m in sizes:\n#                 ans = step\n#         return ans\n        N = len(arr)\n        arr = [x - 1 for x in arr]\n        parent = [x for x in range(N)]\n        size = [1 for _ in range(N)]\n        used = [False for _ in range(N)]\n        \n        def ufind(a):\n            if a == parent[a]:\n                return a\n            parent[a] = ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a, b):\n            sa = ufind(a)\n            sb = ufind(b)\n            \n            if sa != sb:\n                parent[sa] = parent[sb]\n                size[sb] += size[sa]\n        \n        def usize(a):\n            return size[ufind(a)]\n            \n        counts = [0] * (N+1)\n        \n        latest = -1\n        for index, x in enumerate(arr):\n            left = 0\n            if x - 1 >= 0 and used[x - 1]:\n                left = usize(x - 1)\n                \n            right = 0\n            if x + 1 < N and used[x + 1]:\n                right = usize(x + 1)\n                \n            current = 1\n            counts[1] += 1\n            if left > 0:\n                counts[left] -= 1\n            if right > 0:\n                counts[right] -= 1\n            counts[1] -= 1\n            used[x] = True\n            \n            new_size = left + right + current\n            #print(x, left, right)\n            counts[new_size] += 1\n            if left > 0:\n                uunion(x, x - 1)\n            if right > 0:\n                uunion(x, x + 1)\n            \n            #print(counts)\n            if counts[m] > 0:\n                latest = max(latest, index + 1)\n        return latest", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # [3,1,5,4,2]\n        uf = UF(len(arr) + 1)\n        res, step = -1, 1\n        ok = set()\n        for i in arr:\n            uf.isOne[i] = True\n            if i - 1 > 0 and uf.isOne[i - 1]:\n                uf.union(i - 1, i)\n            if i + 1 <= len(arr) and uf.isOne[i + 1]:\n                uf.union(i, i + 1)\n            curok = set()\n            curf = uf.find(i)\n            curones = uf.rank[curf]\n            if curones == m:\n                curok.add(curf)\n                \n            for f in ok:\n                newf = uf.find(f)\n                if uf.rank[newf] == m:\n                    curok.add(newf)\n            ok = curok\n            if len(ok) > 0:\n                res = step\n            step += 1\n        return res\n        \n        \n        \n        \nclass UF:\n    def __init__(self, n):\n        self.n = n\n        self.fathers = [i for i in range(n)]\n        self.rank = [1 for _ in range(n)]\n        self.isOne = [False for _ in range(n)]\n        \n    def find(self, x):\n        if x != self.fathers[x]:\n            self.fathers[x] = self.find(self.fathers[x])\n        return self.fathers[x]\n    \n    def union(self, x, y):\n        fx, fy = self.find(x), self.find(y)\n        if fx != fy:\n            count = self.rank[fx] + self.rank[fy]\n            if self.rank[fx] > self.rank[fy]:\n                self.fathers[fx] = fy\n                self.rank[fy] = count\n            else:\n                self.fathers[fy] = fx\n                self.rank[fx] = count\n    \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], target: int) -> int:\n        b = [0] * len(arr)\n        m = {}\n        c = {}\n        res = -1\n        step = 1\n        for i in arr:\n            i -= 1\n            newl = i\n            newr = i\n            if i >= 1 and b[i-1] == 1:\n                l = i - m[i-1]\n                newl = m[i-1]\n                del m[m[i-1]]\n                if i-1 in m:\n                    del m[i-1]\n                c[l] -= 1\n            if i < len(arr) - 1 and b[i+1] == 1:\n                l = m[i+1] - i\n                newr = m[i+1]\n                del m[m[i+1]]\n                if i+1 in m:\n                    del m[i+1]\n                c[l] -= 1\n            m[newl] = newr\n            m[newr] = newl\n            l = newr - newl + 1\n            c[l] = c.get(l, 0) + 1\n            b[i] = 1\n            if c.get(target, 0):\n                res = step\n            step += 1\n        return res\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parent = [x for x in range(N)]\n        size = [1 for _ in range(N)]\n        used = [False for _ in range(N)]\n        \n        def ufind(a):\n            if a == parent[a]:\n                return a\n            parent[a] = ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a, b):\n            sa = ufind(a)\n            sb = ufind(b)\n            \n            if sa != sb:\n                parent[sa] = parent[sb]\n                size[sb] += size[sa]\n        \n        def usize(a):\n            return size[ufind(a)]\n            \n        counts = [0] * (N+1)\n        \n        latest = -1\n        for index, X in enumerate(arr):\n            x = X - 1\n            left = 0\n            if x - 1 >= 0 and used[x - 1]:\n                left = usize(x - 1)\n                \n            right = 0\n            if x + 1 < N and used[x + 1]:\n                right = usize(x + 1)\n                \n            current = 1\n            counts[1] += 1\n            if left > 0:\n                counts[left] -= 1\n            if right > 0:\n                counts[right] -= 1\n            counts[1] -= 1\n            used[x] = True\n            \n            new_size = left + right + current\n            counts[new_size] += 1\n            if left > 0:\n                uunion(x, x - 1)\n            if right > 0:\n                uunion(x, x + 1)\n            \n            if counts[m] > 0:\n                latest = max(latest, index + 1)\n        return latest", "class Solution:\n    # https://leetcode.com/problems/find-latest-group-of-size-m/discuss/806786/JavaC%2B%2BPython-Count-the-Length-of-Groups-O(N)\n    # https://www.youtube.com/watch?v=2NCfiCpv1OA\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        # number [0, n + 1]\n        length = [0 for _ in range(len(arr) + 2)]\n        res = -1\n        # n starts from 1.\n        for i, n in enumerate(arr):\n            left, right = length[n - 1], length[n + 1]\n            if left == m or right == m:\n                #update res for each time satisfying conditiong. so return the latest one.\n                res = i\n            # update edge. [0111010], change middle 0 t0 1. left = 3, right = 1.total length = 3 + 1 + 1 = 5. edge, length[1] = 5, length[6] = 5\n            length[n - left] = length[n + right] = left + right + 1\n        return res\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        result = len(arr) - self.helper(arr,1,len(arr),len(arr)-1,m)\n        \n        if result < 0: \n            return -1\n        return result\n    \n    \n    \n    def helper(self,arr,left,right,index,m):\n        val=arr[index]\n        steps= 1\n        \n        while val > right or val < left:\n            steps+=1\n            if index -1 >= 0:\n                index -=1 \n                val=arr[index]\n            else:\n                return float('inf')\n        \n        if val-left  == m or  right-val == m:\n            return steps \n        \n        # print(left,val,right,index,m,steps)\n        \n        left_bound =  self.helper(arr,left,val -1,index-1,m) if (val-left > m)  else float('inf')\n        right_bound = self.helper(arr,val +1,right,index-1,m) if (right-val > m) else float('inf')\n        \n        # print(left_bound,right_bound,left,right)\n        return steps + min(left_bound,right_bound)\n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        L, R, C, res = {}, {}, 0, -1\n        for i, x in enumerate(A):\n            l = r = x\n            if x-1 in L:\n                l = L[x-1]\n                if x-l == m:\n                    C -= 1\n                del L[x-1]\n            if x+1 in R:\n                r = R[x+1]\n                if r-x == m:\n                    C -= 1\n                del R[x+1]\n            R[l], L[r] = r, l\n            if r-l+1 == m:\n                C += 1\n            if C:\n                res = i+1\n        return res\n", "class Solution:\n    def find(self,node1: int, group:List[int]) -> int:\n        head  =  node1\n        while head != group[head]:\n            head = group[head]\n        \n        # path compression\n        # while node1 != group[node1]:\n        #     next_node = group[node1]\n        #     group[node1] = head \n        #     node1 = next_node\n        return head\n        \n    def union(self,node1: int, node2:int, group:List[int], size:dict) -> int:\n        # find head for both node 1 and node 2\n        head1 , head2 = self.find(node1,group) , self.find(node2,group)\n        \n        if head1 == head2:\n            return head1\n        \n        if size[head1] < size[head2]:\n            # merge head 1 into head2\n            group[head1] = head2\n            size[head2] += size[head1]\n            size.pop(head1)\n            return head2\n\n        # merge 2 into one\n        group[head2] = head1\n        size[head1] += size[head2]\n        size.pop(head2)\n        return head1\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        group = [-1 for _ in range(len(arr))]\n        sizes = {}\n        ans = -1\n        arr_size= len(arr)\n        for ix, val in enumerate(arr):\n            if group[val-1] != -1:\n                # already visited\n                continue\n            \n            # first time visiting\n            group[val-1] = val-1\n            sizes[val-1] = 1\n            for neighbor in (val-2,val):\n                if 0<=neighbor<arr_size:\n                    head = self.find(neighbor,group)\n                    if head in sizes and sizes[head] == m:\n                        ans = ix\n                    if group[neighbor] != -1:\n                        self.union(val-1,neighbor,group,sizes)\n            # if head and sizes[head] == m:\n            #     ans = max(ix+1,ans)\n        return ans\n", "from sortedcontainers import SortedList\nclass Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        length = [0] * (len(A) + 2)\n        count = [0] * (len(A) + 1)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "from collections import defaultdict\n\nclass DSU:\n    def __init__(self, n):\n        self.n = n\n        self.fa = list(range(n))\n        self.sz = [1 for _ in range(n)]\n        self.cnt = defaultdict(int)\n\n    def find(self, x):\n        r = x\n        while self.fa[r] != r:\n            r = self.fa[r]\n        i = x\n        while i != r:\n            i, self.fa[i] = self.fa[i], r\n        return r\n    \n    def join(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        if x != y:\n            if self.sz[x] > self.sz[y]:\n                x, y = y, x\n            sx = self.sz[x]\n            sy = self.sz[y]\n            self.cnt[sx] -= 1\n            self.cnt[sy] -= 1\n            self.cnt[sx + sy] += 1\n            \n            self.fa[x] = y\n            self.sz[y] += self.sz[x]\n\nclass Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        n = len(a)\n        b = [0 for _ in range(n + 2)]\n        dsu = DSU(n + 1)\n        \n        ans = -1\n        valid = set()\n        for step, j in enumerate(a, 1):\n            b[j] = 1\n            dsu.cnt[1] += 1\n\n            if b[j - 1]:\n                dsu.join(j, j - 1)\n            if b[j + 1]:\n                dsu.join(j, j + 1)\n            if dsu.cnt.get(m, 0):\n                ans = step\n\n        return ans", "class UF:\n  def __init__(self, e):\n    self.parents = list(range(e))\n    self.ranks = [0]*e\n\n  def findP(self, r):\n    if r==self.parents[r]:\n      return r\n    self.parents[r] = self.findP(self.parents[r])\n    return self.parents[r]\n\n  def union(self, u, v):\n    up = self.findP(u)\n    vp = self.findP(v)\n\n    if up!=vp:\n      if self.ranks[up]>=self.ranks[vp]:\n        self.parents[vp] = up\n\n        self.ranks[up] += self.ranks[vp]\n      else:\n        self.parents[up] = vp\n        self.ranks[vp] += self.ranks[up]\n      return False\n    return True\n  \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n      \n      if m==len(arr): return m\n      \n      n = len(arr)\n      u = UF(n)\n      \n      res = -1\n  \n      for step, v in enumerate(arr):\n        \n        v = v - 1\n        u.ranks[v] = 1\n        \n        for i in (v-1, v+1):\n          if 0<=i<n:\n            if u.ranks[u.findP(i)]==m:\n              res = step\n              \n            if u.ranks[i]:\n              u.union(v, i)\n            \n        # print (step, u.ranks, u.parents)\n        \n        # if u.ranks[u.findP(v)]==m:\n        #   res = step\n        \n      return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ids = [0]*(len(arr)+2)\n        d = []\n        lst = -1\n        def parent(a):\n            # print(a)\n            if(ids[a]<0):\n                return a\n            ids[a] = parent(ids[a])\n            return ids[a]\n        \n        def SF(a, b):\n            return parent(a)==parent(b)\n        \n        def SU(a,b):\n            a = parent(a)\n            b = parent(b)\n            # print(a,\\\" \\\",b)\n            if(a==b):\n                return\n            if(ids[a]<=ids[b]):\n                ids[a] += ids[b]\n                ids[b] = a\n            else:\n                ids[b] += ids[a]\n                ids[a] = b\n        \n        def size(a):\n            return -ids[parent(a)]\n        \n        for j,i in enumerate(arr):\n            # print(\\\"toto \\\",j, \\\"  \\\",i)\n            ids[i]=-1\n            if(ids[i-1]!=0):\n                SU(i-1,i)\n            if(ids[i+1]!=0):\n                SU(i, i+1)\n            # print(i,\\\" \\\",size(i))\n            if(size(i)==m):\n                d.append(i)\n            for t in range(len(d)-1,-1, -1):\n                x = d.pop(t)\n                if(size(x)==m):\n                    d.append(x)\n                    lst = j+1\n            # print(d)\n        \n        return lst", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        F = [0] * n\n        d = collections.defaultdict(int)\n        \n        def find(x):\n            if F[x] < 0:\n                return x\n            else:\n                F[x] = find(F[x])\n                return F[x]\n        \n        t = [0] * n\n        ans = -1\n        \n        for i in range(n):\n            ind = arr[i] - 1\n            d[1] += 1\n            t[ind] = 1\n            F[ind] = -1\n            if ind > 0 and t[ind-1] == 1:\n                new = find(ind-1)\n                d[-F[ind]] -= 1\n                d[-F[new]] -= 1\n                d[-F[ind]-F[new]] += 1\n                F[ind] += F[new]\n                F[new] = ind\n            if ind < n-1 and t[ind+1] == 1:\n                new = find(ind+1)\n                d[-F[ind]] -= 1\n                d[-F[new]] -= 1\n                d[-F[ind]-F[new]] += 1\n                F[ind] += F[new]\n                F[new] = ind\n            if d[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return len(arr)\n        \n        visited = set([0, len(arr)+1]) \n        for i in range(len(arr)-1, -1, -1):\n            index = arr[i]\n            if index + m +1 in visited:\n                for n in range(index, index+m+1):\n                    if n in visited:\n                        break \n                else:\n                    return i\n            \n            if index - m - 1 in visited:\n                for n in range(index-1, index-m-1, -1):\n                    if n in visited:\n                        break \n                else:\n                    return i\n            visited.add(index)\n            \n        return -1 \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        self.groups_start = {} # start pos: length\n        self.groups_end = {} # end pos: start pos\n        \n        last_pos = -1\n        m_start_pos = set()\n        n = len(arr)\n        for k, i in enumerate(arr):\n            start_pos = i\n            if i + 1 <= n:\n                if i + 1 in self.groups_start:\n                    # merge\n                    length = self.groups_start[i+1]\n                    del self.groups_start[i+1]\n                    self.groups_start[i] = length + 1\n                    self.groups_end[i+length] = i\n                    if i + 1 in m_start_pos:\n                        m_start_pos.remove(i+1)\n                else:\n                    self.groups_start[i] = 1\n                    self.groups_end[i] = i\n            else:\n                self.groups_start[i] = 1\n                self.groups_end[i] = i\n            if i - 1 >= 1:\n                if i - 1 in self.groups_end:\n                    # merge\n                    start_pos = self.groups_end[i-1]\n                    if start_pos in m_start_pos:\n                        m_start_pos.remove(start_pos)\n                    new_length = self.groups_start[start_pos] + self.groups_start[i]\n                    self.del_group(i)\n                    self.del_group(start_pos)\n                    self.groups_start[start_pos] = new_length\n                    self.groups_end[start_pos+new_length-1] = start_pos\n            if self.groups_start[start_pos] == m:\n                m_start_pos.add(start_pos)\n            if len(m_start_pos) > 0:\n                last_pos = k + 1\n                    \n        return last_pos\n        \n    def del_group(self, start_pos):\n        del self.groups_end[start_pos+self.groups_start[start_pos]-1]\n        del self.groups_start[start_pos]", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        \n        def helper(rec, k):\n            temp_rec = []\n            for i, j in rec:\n                if k < i or k > j:\n                    if j-i+1 > m:\n                        temp_rec.append([i, j])\n                    continue\n                if k-i == m or j-k == m:\n                    return True\n                else:\n                    if k-i > m:\n                        temp_rec.append([i, k-1])\n                    if j-k > m:\n                        temp_rec.append([k+1, j])\n#            print(temp_rec)\n            return temp_rec\n        \n        rec = [(1, n)]\n        for ind in range(n, 0, -1):\n            rec = helper(rec, arr[ind-1])\n#            print(rec)\n            if rec == True:\n                return ind-1\n            elif not rec:\n                return -1\n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def func(i):\n            if d[i]!=i: d[i]=func(d[i])\n            return d[i]\n        d,dd,a,s={},{},{},-1\n        for p,i in enumerate(arr,1):\n            if i-1 in d:\n                if i+1 in d:\n                    j,k=func(i-1),func(i+1)\n                    d[k],d[i]=j,j\n                    a[dd[j]]-=1\n                    a[dd[k]]-=1\n                    dd[j]+=dd[k]+1\n                    a[dd[j]]=a.get(dd[j],0)+1\n                else:\n                    j=func(i-1)\n                    d[i]=j\n                    a[dd[j]]-=1\n                    dd[j]+=1\n                    a[dd[j]]=a.get(dd[j],0)+1\n            elif i+1 in d:\n                j=func(i+1)\n                d[i]=j\n                a[dd[j]]-=1\n                dd[j]+=1\n                a[dd[j]]=a.get(dd[j],0)+1\n            else:\n                d[i]=i\n                dd[i]=1\n                a[1]=a.get(1,0)+1\n            if a.get(m,0): s=p\n        return s", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        result = dict()\n        total = len(arr)\n        buffer = [-1] * total\n\n        return self.do_find(arr, m, total, 0, buffer, result)\n\n    def do_find(self, arr, m, total, index, buffer, result):\n        if index == total:\n            return -1\n\n        arr_idx = arr[index] - 1\n\n\n        if arr_idx > 0 and buffer[arr_idx-1] != -1:\n            start_idx = buffer[arr_idx-1]\n            result[arr_idx - start_idx] -= 1\n        else:\n            start_idx = arr_idx\n\n        if arr_idx < total - 1 and buffer[arr_idx + 1] != -1:\n            end_idx = buffer[arr_idx+1]\n            result[end_idx - arr_idx] -= 1\n        else:\n            end_idx = arr_idx\n\n        new_len = end_idx - start_idx + 1\n\n        if new_len in result:\n            result[new_len] += 1\n        else:\n            result[new_len] = 1\n\n        buffer[end_idx] = start_idx\n        buffer[start_idx] = end_idx\n\n        current_result = index+1 if result.get(m, 0) > 0 else -1\n        next_result = self.do_find(arr, m, total, index + 1, buffer, result)\n        if next_result > 0:\n            return next_result\n        return current_result\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        a = len(arr)\n        if a == m:\n            return m\n        arr_set = set(arr)\n        arr.reverse()\n        for i in range(a):\n            arr_set.remove(arr[i])\n            back_i = arr[i]+1\n            if back_i in arr_set:\n                cur_streak = 1\n                while back_i+1 in arr_set:\n                    back_i += 1\n                    cur_streak += 1\n                    if cur_streak > m:\n                        break\n                if cur_streak == m:\n                    return a-1-i\n            front_i = arr[i]-1\n            if front_i in arr_set:\n                cur_streak = 1\n                while front_i-1 in arr_set:\n                    front_i -= 1\n                    cur_streak += 1\n                    if cur_streak > m:\n                        break\n                if cur_streak == m:\n                    return a-1-i\n        return -1", "from collections import Counter\nclass Union:\n    def __init__(self, n):\n        self.groups = list(range(n))\n        self.sizes = [1] * n\n    def find(self, node):\n        while node != self.groups[node]:\n            node = self.groups[node]\n        return node\n    \n    def union(self, node1, node2):\n        root1, root2 = self.find(node1), self.find(node2)\n        if self.sizes[root1] < self.sizes[root2]:\n            root1, root2 = root2, root1\n        self.sizes[root1] += self.sizes[root2]\n        self.groups[root2] = root1\n        return self.sizes[root1]\n    \n    def getSize(self, node):\n        node = self.find(node)\n        return self.sizes[node]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        union = Union(n)\n        bits = [0] * n\n        counter = Counter()\n        res = -1\n        for i, x in enumerate(arr):\n            curr_size = 1\n            x -= 1\n            bits[x] = 1\n            if x and bits[x-1] == 1:\n                l_size = union.getSize(x - 1)\n                counter[l_size] -= 1\n                curr_size = union.union(x-1, x)\n            \n            if x < n - 1 and bits[x+1] == 1:\n                r_size = union.getSize(x + 1)\n                counter[r_size] -= 1\n                curr_size = union.union(x, x+1)\n            \n            counter[curr_size] += 1\n            #print(counter)\n            if counter[m] > 0:\n                res = i + 1\n        return res\n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        a = [0]*n\n        c = [0]*n\n        for i in range(n):\n            a[i] = -1\n            c[i] = -1\n        res = -1\n        have_m = 0\n        def find_root(i):\n            while a[i] != i:\n                i = a[i]\n            return i\n        step = 0\n        for pos in arr:\n            step+=1\n            pos -= 1\n            if pos<n-1 and a[pos+1]!=-1:\n                a[pos+1] = pos\n                a[pos] = pos\n                c[pos] = c[pos+1]+1\n                if c[pos+1] == m:\n                    have_m-=1\n                if c[pos] == m:\n                    have_m+=1\n            else:\n                a[pos] = pos\n                c[pos] = 1\n                if c[pos] == m:\n                    have_m+=1\n            if pos>0 and a[pos-1]!=-1:\n                a[pos] = find_root(pos-1)\n                if c[pos] == m:\n                    have_m -= 1\n                if c[a[pos]] == m:\n                    have_m -= 1\n                c[a[pos]] += c[pos]\n                if c[a[pos]] == m:\n                    have_m+=1\n            if have_m:\n                res = step\n        return res\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        pos = [None] * (len(arr) + 3)\n        num = 0\n        ans = -1\n        for idx in range(1, len(arr) + 1):\n            l, r, p = [arr[idx - 1]] * 3\n            if pos[p-1]:\n                if pos[p-1][1] - pos[p-1][0] + 1 == m:\n                    num -= 1\n                l = pos[p-1][0]\n            if pos[p + 1]:\n                if pos[p + 1][1] - pos[p+1][0] + 1 == m:\n                    num -= 1\n                r = pos[p+1][1]\n            pos[l] = pos[r] = (l, r)\n            if r - l + 1 == m:\n                num += 1\n            if num != 0:\n                ans = idx\n        return ans", "class UnionFind:\n\n    def __init__(self, values: int):\n        self.values = list(range(values))\n        self.connectedComponents = [1] * values\n\n    def root(self, key):\n        root = self.values[key]\n\n        while root != self.values[root]:\n            root = self.values[root]\n\n        return root\n\n    def union(self, keyA, keyB):\n        rootA = self.root(keyA)\n        rootB = self.root(keyB)\n\n        self.values[rootB] = rootA\n        self.connectedComponents[rootA] += self.connectedComponents[rootB]\n        self.connectedComponents[rootB] = 0\n\n    def find(self, keyA, keyB):\n        return self.root(keyA) == self.root(keyB)\n\n\nclass Solution:\n    def findLatestStep(self, arr: list, m: int) -> int:\n\n        uf = UnionFind(len(arr))\n\n        step = -1\n        groupM = set()\n        binaryString = [0] * len(arr)\n\n        for i, val in enumerate(arr):\n\n            if i == 9:\n                print('')\n\n            val = val - 1\n\n            binaryString[val] = 1\n\n            if val != 0 and binaryString[val - 1] == 1:\n                if not uf.find(val, val - 1):\n                    root = uf.root(val - 1)\n                    uf.union(val, val - 1)\n\n                    if root in groupM:\n                        groupM.remove(root)\n\n            if val != (len(arr) - 1) and binaryString[val + 1] == 1:\n                if not uf.find(val, val + 1):\n                    root = uf.root(val + 1)\n                    uf.union(val, val + 1)\n\n                    if root in groupM:\n                        groupM.remove(root)\n\n            if uf.connectedComponents[val] == m:\n                groupM.add(val)\n            elif uf.connectedComponents[val] != m and val in groupM:\n                groupM.remove(val)\n\n            if len(groupM):\n                step = i + 1\n\n        return step", "# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         n = len(arr)\n#         if n == m:\n#             return n\n#         temp = [1]*n\n#         j = n\n#         while j > 0:\n#             temp[arr[j-1]-1] = 0\n#             count = 0\n#             for i, y in enumerate(temp):\n#                 if y == 1:\n#                     count += 1\n#                 else:\n#                     count = 0\n#                 if count == m and (i+1 >= n or (i+1 < n and temp[i+1] == 0)):\n#                     return j - 1\n#             j -= 1\n#         return -1\n\n# class Solution:\n#     def findLatestStep(self, A, m):\n#         if m == len(A): return m\n#         length = [0] * (len(A) + 2)\n#         res = -1\n#         for i, a in enumerate(A):\n#             left, right = length[a - 1], length[a + 1]\n#             if left == m or right == m:\n#                 res = i\n#             length[a - left] = length[a + right] = left + right + 1\n#         return res\n\nclass UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n: return n \n        arr.append(n+1)\n        start = {}\n        finish = {}\n        last = -1\n        for level,i in enumerate(arr):\n            if i-1 not in finish: finish[i-1] = i \n            if i+1 not in start: start[i+1] = i\n\n            s, f = finish[i-1], start[i+1]\n            start[s] = f \n            finish[f] = s\n            \n            os, of = i+1, start[i+1]\n            if of-os+1 == m: last = level\n                \n            os, of = finish[i-1], i-1\n            if of-os+1 == m: last = level\n            \n            del start[i+1]\n            del finish[i-1]\n            \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        lengths = [0] * (len(arr) + 2)\n        result = -1\n        for i, a in enumerate(arr):\n            left, right = lengths[a - 1], lengths[a + 1]\n            if left == m or right == m:\n                result = i\n            lengths[a - left] = lengths[a + right] = left + right + 1\n        return result\n            \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        while u != self.parents[u]:\n            self.parents[u] = self.parents[self.parents[u]]\n            u = self.parents[u]\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n         \n        if self.ranks[pu] > self.ranks[pv]:\n            a, b = pu, pv\n        else:\n            a, b = pv, pu\n            \n        self.parents[b] = a\n        self.ranks[a] += self.ranks[b]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n                \n                    \n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        #elif self.ranks[pv] > self.ranks[pu]:\n        #    self.parents[pu] = pv\n        #    self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        if m == n:\n            return n\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        left = [0]*(n+2)\n        right = [0]*(n+2)\n        def getlength(x):\n            return right[x]-x+1\n        count = 0\n        res = -1\n        for i in range(n):\n            x = arr[i]\n            if left[x-1] and right[x+1]:\n                if getlength(left[x-1]) == m:\n                    count -= 1\n                if getlength(x+1) == m:\n                    count -= 1\n                right[left[x-1]] = right[x+1]\n                left[right[x+1]] = left[x-1]\n                if getlength(left[x-1]) == m:\n                    count += 1\n            elif left[x-1]:\n                if getlength(left[x-1]) == m:\n                    count -= 1\n                right[left[x-1]] = x\n                left[x] = left[x-1]\n                if getlength(left[x-1]) == m:\n                    count += 1\n            elif right[x+1]:\n                if getlength(x+1) == m:\n                    count -= 1\n                left[right[x+1]] = x\n                right[x] = right[x+1]\n                if getlength(x) == m:\n                    count += 1\n            else:\n                left[x] = x\n                right[x] = x\n                if m == 1:\n                    count += 1\n            if count > 0:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        d = {}\n        res = set()\n        ans = -1\n        for (s,j) in enumerate(arr):\n            i = j-1\n            #print(i,d)\n            if i+1 not in d and i-1 not in d:\n                #print(i,d)\n                d[i] = 1\n                if d[i] == m: res.add(i)\n            elif i+1 in d and i-1 not in d:\n                if i+1 in res:res.remove(i+1)\n                if i+d[i+1] in res:res.remove(i+d[i+1])\n                if d[i+1] != 1:\n                    temp = d.pop(i+1)\n                    d[i] = 1+temp\n                    d[i+temp] += 1\n                else:\n                    d[i] = 2\n                    d[i+1] = 2\n                if d[i] == m: \n                    res.add(i)\n\n                #print(i,d)\n            elif i-1 in d and i+1 not in d:\n                #print(i,d)\n                if i-1 in res: res.remove(i-1)\n                if i-d[i-1] in res:res.remove(i-d[i-1])\n                if d[i-1] != 1:\n                    temp = d.pop(i-1)\n                    d[i] = 1+temp\n                    d[i-temp] += 1\n                else:\n                    d[i] = 2\n                    d[i-1] = 2\n                if d[i] == m: \n                    res.add(i)\n\n                         \n            else:\n                a,b = i-d[i-1],i+d[i+1]\n                if d[i-1] != 1: d.pop(i-1)\n                if d[i+1] != 1: d.pop(i+1)\n                if i-1 in res: res.remove(i-1)\n                if i+1 in res: res.remove(i+1)\n                if a in res: res.remove(a)\n                if b in res: res.remove(b)\n                d[a] = b-a+1\n                d[b] = b-a+1\n                #print(i,a,b,d[i-1],d[i+1])\n                if b-a+1 == m: \n                    res.add(a)\n                    res.add(b)        \n\n            #print(d,res)\n            if res: ans = s+1\n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        mcount = 0\n        lastindex = -1\n        ends = {}\n        starts = {}\n        for i in range(n):\n            index = arr[i]\n            if index-1 in ends and index+1 in starts:\n                start = ends[index-1]\n                end = starts[index+1]\n                old1 = index-start\n                old2 = end-index\n                if old1==m:\n                    mcount-=1\n                if old2==m:\n                    mcount-=1\n                if end-start+1==m:\n                    mcount+=1\n                starts[start], ends[end] = end, start\n                starts.pop(index+1)\n                ends.pop(index-1)\n            elif index-1 in ends:\n                start = ends[index-1]\n                old1 = index-start\n                if old1==m:\n                    mcount-=1\n                elif old1==m-1:\n                    mcount+=1\n                starts[start] = index\n                ends[index] = start\n                ends.pop(index-1)\n            elif index+1 in starts:\n                end = starts[index+1]\n                old1 = end-index\n                if old1==m:\n                    mcount-=1\n                elif old1==m-1:\n                    mcount+=1\n                starts[index] = end\n                ends[end] = index\n                starts.pop(index+1)\n            else:\n                starts[index] = index\n                ends[index] = index\n                if m==1:\n                    mcount+=1\n            if mcount != 0:\n                lastindex = i+1\n        return lastindex\n                \n                \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        spans = [(1, N)]\n        step = N\n        \n        if m == N:\n            return m\n        \n        while arr:\n            #print(step, spans)\n            d = arr.pop()\n            step -= 1\n            for span in spans:\n                if span[0] <= d <= span[1]:\n                    if d-span[0] == m or span[1] - d == m:\n                        return step\n                    \n                    spans.remove(span)\n                    if d - span[0] > m:\n                        spans.append((span[0], d-1))\n                    if span[1] - d > m:\n                        spans.append((d+1, span[1]))\n            \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start_mp, end_mp = {}, {}\n        max_step = -1\n        m_cnt = 0\n        # use the merge's mind\n        for idx, num in enumerate(arr): \n            l = 1\n            if num-1 not in end_mp and num+1 not in start_mp: \n                start_mp[num] = end_mp[num] = 1\n                start_index = end_index = num\n            elif num-1 in end_mp and num +1 in start_mp:\n                # merge\n                old_l = end_mp[num-1]\n                old_r = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                if old_r == m: \n                    m_cnt -= 1\n                start_index = num-1 - end_mp[num-1] + 1\n                end_index = num+1 + start_mp[num+1] -1\n                l = end_mp[num-1] + start_mp[num+1] + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1], start_mp[num+1], end_mp[num+1+old_r-1]\n                start_mp[start_index] = l\n                end_mp[end_index] = l\n            elif num-1 in end_mp: \n                # extend to the left\n                old_l = end_mp[num-1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1]\n                start_index = num-l+1 \n                end_index = m\n                end_mp[num] = start_mp[num-l+1] = l\n            elif num+1 in start_mp: \n                old_l = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num+1+old_l-1], start_mp[num+1]\n                start_mp[num] = end_mp[num+l-1] = l\n                start_index = num\n                end_index = num+l-1\n            \n            if l == m: \n                m_cnt += 1\n            if m_cnt > 0: \n                max_step = max(max_step, idx + 1)\n        return max_step\n                \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # actually the above code could be much simpler \n        # keyed by length, cnt is the value\n        lcnt = collections.Counter()\n        l = [0 for _ in range(len(arr)+2)]\n        max_step = -1\n        for idx, num in enumerate(arr): \n            left, right = l[num-1], l[num+1]\n            new_l = left + right + 1\n            l[num-left] = l[num] = l[num+right] = new_l # this step is the key\n            lcnt[left] -=1\n            lcnt[right] -= 1\n            lcnt[new_l] += 1\n            if lcnt[m]: \n                max_step = idx + 1\n        return max_step\n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        segment = [0]*len(arr)\n        count = {}\n        res = -1\n        for i in range(len(arr)):\n            left,right = 0,0\n            index = arr[i]-1\n            if index-1 >= 0:\n                left = segment[index-1]\n            if index+1 < len(arr):\n                right = segment[index+1]\n            segment[index-left] = left+right+1\n            segment[index+right] = left+right+1\n            \n            if left in count and count[left] != 0 :\n                count[left] -= 1\n            if right in count and count[right] != 0 :\n                count[right] -= 1\n            \n            if left+right+1 in count:\n                count[left+right+1] += 1\n            else:\n                count[left+right+1] = 1\n                \n            if m in count and count[m] != 0 :\n                res = i+1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return len(arr)    \n        \n        u = list(range(len(arr)+1))\n        size = [0] * (len(arr)+1)\n        \n        def find(a):\n            if u[a] != a:\n                u[a] = find(u[a])\n            return u[a]\n        \n        def union(a, b):\n            u1 = find(a)\n            u2 = find(b)\n            if u1 != u2:\n                if size[u1] < size[u2]:\n                    u[u1] = u2\n                    size[u2] += size[u1]\n                else:\n                    u[u2] = u1\n                    size[u1] += size[u2]\n        ans = -1\n        for a_idx, a in enumerate(arr):\n            # print(a)\n            # print(\\\"u\\\", u)\n            # print(\\\"s\\\", size)\n            size[a] = 1\n            for i in [a-1, a+1]:\n                if 1 <= i <= len(arr):\n                    if size[find(i)] == m:\n                        ans = a_idx\n                    if size[i] > 0:\n                        union(a, i)\n                    # if size[find(a)] == m:\n                    #     ans = a_idx+1\n                        \n        # print(\\\"u\\\", u)\n        # print(\\\"s\\\", size)\n                        \n        for i in range(1, len(arr)+1):\n            # print(i, find(i))\n            if size[find(i)] == m:\n                return len(arr)\n        # print(\\\"not last\\\")\n        return ans\n        \n#         sections = [\n#             [1, len(arr)]\n#         ]\n#         arr = arr[::-1]\n#         for a_idx, a in enumerate(arr):\n#             # print(a, sections)\n#             l = 0\n#             r = len(sections)\n#             while l < r:\n#                 c = l + (r-l)//2\n#                 if sections[c][0] <= a <= sections[c][1]:\n#                     # a at left\n#                     if a == sections[c][0]:\n#                         sections[c][0] = a+1\n#                         if sections[c][0] > sections[c][1]:\n#                             sections = sections[:c] + sections[c+1:]\n#                         else:\n#                             if sections[c][1] - sections[c][0] + 1 == m:\n#                                 return len(arr) - a_idx - 1 \n#                     elif a == sections[c][1]:\n#                         sections[c][1] = a-1\n#                         if sections[c][0] > sections[c][1]:\n#                             sections = sections[:c] + sections[c+1:]\n#                         else:\n#                             if sections[c][1] - sections[c][0] + 1 == m:\n#                                 return len(arr) - a_idx - 1 \n#                     else:\n#                         tmp = sections[c][1]\n#                         sections[c][1] = a-1\n#                         sections = sections[:c+1] + [[a+1, tmp]] + sections[c+1:]\n#                         # heapq.heappush(sections, [a+1, tmp])\n#                         if sections[c][1] - sections[c][0] + 1 == m:\n#                             return len(arr) - a_idx - 1 \n#                         if sections[c+1][1] - sections[c+1][0] + 1 == m:\n#                             return len(arr) - a_idx - 1\n#                     break   \n#                 elif a < sections[c][0]:\n#                     r = c\n#                 elif a > sections[c][1]:\n#                     l = c+1\n#             # print(sections)\n        \n#         return -1\n        \n#         ans = -1\n#         dp = [0] * (len(arr)+1)\n#         for idx, a in enumerate(arr):\n#             if a > 1:\n#                 dp[a] += dp[a-1]\n#             if a < len(arr):\n#                 dp[a] += dp[a+1]\n#             dp[a] += 1\n#             if dp[a] == m:\n#                 ans = idx+1\n#             print(dp)\n                \n#         return ans\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        n = len(arr)\n        uf = UnionFind(n)\n        ans = -1\n        for step, i in enumerate(arr):\n            index = i - 1\n            uf.ranks[index] = 1\n            for j in [index - 1, index + 1]:\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(index, j)\n        return ans\n        \n\nclass UnionFind():\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n    \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, n1, n2):\n        p1, p2 = self.find(n1), self.find(n2)\n        if p1 == p2:\n            return\n        if self.ranks[p1] > self.ranks[p2]:\n            self.parents[p2] = p1\n            self.ranks[p1] += self.ranks[p2]\n            return\n        else:\n            self.parents[p1] = p2\n            self.ranks[p2] += self.ranks[p1]\n            return\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        par = {}\n        sz = {}\n        target = set()\n        \n        def find(i):\n            while i != par[i]:\n                par[i] = par[par[i]]\n                i = par[i]\n            return i\n        \n        def union(i, j):\n            x = find(i)\n            y = find(j)\n            if x == y:\n                return\n            if sz[x] <= sz[y]:\n                sz[y] += sz[x]\n                par[x] = y\n                \n                if sz[y] == m:\n                    target.add(y)\n                    \n                if sz[x] == m and x in target:\n                    target.remove(x)\n            else:\n                sz[x] += sz[y]\n                par[y] = x\n                \n                if sz[x] == m:\n                    target.add(x)\n                    \n                if sz[y] == m and y in target:\n                    target.remove(y)\n        \n        count = 1\n        ans = -1\n        for i in arr:\n            if i not in par:\n                par[i] = i\n                sz[i] = 1\n                if m == 1:\n                    target.add(i)\n                \n            if i - 1 in par and i + 1 in par:\n                union(i-1, i+1)\n                union(i-1, i)\n            elif i - 1 in par:\n                union(i-1, i)\n            elif i + 1 in par:\n                union(i, i+1)\n                \n            t = set()\n            for i in target:\n                if sz[i] == m:\n                    ans = count\n                    t.add(i)\n            target = t\n            count += 1\n                \n        return ans\n            \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr)==m:\n            return m\n        n,  ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        #for i in range(n):\n         #   if uf.ranks[uf.find(i)] == m:\n          #      return n\n            \n        return ans\n", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        g = [0] * (len(a)+1)\n        cnt = Counter()\n        last = -1\n        for i, p in enumerate(a):    \n            l = g[p-1] if p > 1 else 0\n            r = g[p+1] if p < len(g)-1 else 0\n            new_l = l+1+r\n            g[p-l] = g[p+r] = new_l\n            if l > 0: \n                cnt[l] -= 1\n                if cnt[l] == 0: del cnt[l]\n            if r > 0: \n                cnt[r] -= 1\n                if cnt[r] == 0: del cnt[r]\n            cnt[new_l] += 1 \n            if m in cnt:\n                last = i + 1\n            # print(i, l, r, g)\n        return last", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n                \n                    \n        \n", "class UF:\n    def __init__(self, n):\n        self.parents = [i for i in range(n)]\n        self.ranks = [0] * n\n    \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n            \n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        if m == len(arr):\n            return m\n        \n        n = len(arr)\n        uf = UF(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1 # because of 1-index\n            uf.ranks[i] = 1\n            \n            for j in (i-1, i+1):\n                if 0<=j<n:\n                    # if j's parent to j constintutes a m-length array\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j] > 0:\n                        uf.union(i, j)\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n: \n            return m\n        \n        border = [0]*(n+2)\n        ans = -1\n        for i in range(n):\n            left = right = arr[i]\n            if border[right+1] > 0: \n                right = border[right+1]\n            if border[left-1] > 0:\n                left = border[left-1]\n            border[left], border[right] = right, left\n            if right-arr[i] == m or arr[i]-left == m:\n                ans=i\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        \n        # pos: length\n        lenMap = dict()\n        # length: cnt\n        cntMap = collections.defaultdict(lambda: 0)\n        \n        for i,x in enumerate(arr):\n            left = 0\n            right = 0\n            \n            if x - 1 in lenMap: \n                left = lenMap[x - 1]\n                cntMap[left] -= 1\n            if x + 1 in lenMap: \n                right = lenMap[x + 1]\n                cntMap[right] -= 1\n                \n            newLen = 1 + left + right\n            lenMap[x] = lenMap[x - left] = lenMap[x + right] = newLen\n            cntMap[newLen] += 1\n            \n            if cntMap[m] != 0:\n                res = i + 1\n                \n        return res\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(n)\n        res = [0]*n\n        ans = -1\n        for i in range(n):\n            step = i+1\n            index = arr[i]-1\n            res[index] = 1\n            uf.size[index] = 1\n            uf.count[1] += 1\n            \n            if index-1 >= 0 and res[index-1] == 1:\n                uf.union(index-1, index)\n            \n            if index+1 < n and res[index+1] == 1:\n                uf.union(index, index+1)\n            \n            if uf.count[m] > 0:\n                ans = step\n        \n        return ans\n            \n        \n\nclass UnionFind:\n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.size = [0]*n\n        self.count = Counter()\n        \n    def union(self, x, y):\n        rootx = self.find(x)\n        rooty = self.find(y)\n        \n        if rootx == rooty:\n            return False\n        \n        size_x = self.size[rootx]\n        size_y = self.size[rooty]\n        \n        self.count[size_x] -= 1\n        self.count[size_y] -= 1\n        \n        new_size = size_x + size_y\n        \n        self.parent[rooty] = rootx\n        self.size[rootx] = new_size\n        self.count[new_size] += 1\n        \n        return True\n    \n    def find(self, x):\n        while x != self.parent[x]:\n            # self.parent[x] = self.parent[self.parent[x]]\n            x = self.parent[x]\n        return x", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start_mp, end_mp = {}, {}\n        max_step = -1\n        m_cnt = 0\n        # use the merge's mind\n        for idx, num in enumerate(arr): \n            l = 1\n            if num-1 not in end_mp and num+1 not in start_mp: \n                start_mp[num] = end_mp[num] = 1\n                start_index = end_index = num\n            elif num-1 in end_mp and num +1 in start_mp:\n                # merge\n                old_l = end_mp[num-1]\n                old_r = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                if old_r == m: \n                    m_cnt -= 1\n                start_index = num-1 - end_mp[num-1] + 1\n                end_index = num+1 + start_mp[num+1] -1\n                l = end_mp[num-1] + start_mp[num+1] + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1], start_mp[num+1], end_mp[num+1+old_r-1]\n                start_mp[start_index] = l\n                end_mp[end_index] = l\n            elif num-1 in end_mp: \n                # extend to the left\n                old_l = end_mp[num-1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1]\n                start_index = num-l+1 \n                end_index = m\n                end_mp[num] = start_mp[num-l+1] = l\n            elif num+1 in start_mp: \n                old_l = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num+1+old_l-1], start_mp[num+1]\n                start_mp[num] = end_mp[num+l-1] = l\n                start_index = num\n                end_index = num+l-1\n            \n            if l == m: \n                m_cnt += 1\n            if m_cnt > 0: \n                max_step = max(max_step, idx + 1)\n        return max_step\n                \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # actually the above code could be much simpler \n        # keyed by length, cnt is the value\n        lcnt = collections.Counter()\n        l = collections.Counter()\n        max_step = -1\n        for idx, num in enumerate(arr): \n            left, right = l[num-1], l[num+1]\n            new_l = left + right + 1\n            l[num-left] = l[num] = l[num+right] = new_l # this step is the key\n            lcnt[left] -=1\n            lcnt[right] -= 1\n            lcnt[new_l] += 1\n            if lcnt[m]: \n                max_step = idx + 1\n        return max_step\n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parent = [i for i in range(n)]\n        cnt = [0]*n\n        self.m_cnt = 0\n        def find(node):\n            if parent[node] != node:\n                parent[node] = find(parent[node])\n            return parent[node]\n        \n        def union(n1, n2):\n            old = (cnt[find(n1)] == m) + (cnt[find(n2)] == m)\n            cnt[find(n2)] += cnt[find(n1)]\n            parent[find(n1)] = find(n2)\n            new = (cnt[find(n2)] == m)\n            self.m_cnt += new-old\n            \n        string = [0]*n\n        ans = -1\n        for i in range(n):\n            j = arr[i]-1\n            string[j] = 1\n            cnt[j] = 1\n            if m == 1:\n                self.m_cnt += 1\n            if j>0 and string[j-1] == 1:\n                union(j-1, j)\n            if j<n-1 and string[j+1] == 1:\n                union(j, j+1)\n            if self.m_cnt > 0:\n                ans = i+1\n        return ans\n        \n", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        n = len(a)\n        left, right = [0] * (n + 2), [0] * (n + 2)\n        count = [0] * (n + 2)\n        ans = -1\n        for i, x in enumerate(a):\n            left[x], right[x] = x, x\n            count[1] += 1\n            if left[x - 1] != 0:\n                count[1] -= 1\n                right[left[x - 1]] = x\n                left[x] = left[x - 1]\n                count[x - left[x - 1]] -= 1\n                count[x - left[x - 1] + 1] += 1\n            if right[x + 1] != 0:\n                right[x] = right[x + 1]\n                right[left[x]] = right[x + 1]\n                left[right[x + 1]] = left[x]\n                count[right[x + 1] - x] -= 1\n                count[x - left[x] + 1] -= 1\n                count[right[x] - left[x] + 1] += 1\n            if count[m] > 0:\n                ans = i + 1\n        return ans ", "class Solution:\n    \n    def find(self, a):\n        if self.parent[a] != a:\n            self.parent[a] = self.find(self.parent[a])\n        return self.parent[a]\n    \n    def union(self, a, b):\n        r1 = self.find(a)\n        r2 = self.find(b)\n        if r1 == r2:\n            return\n        if self.size[r1] == self.m:\n            self.num_m -= 1\n        if self.size[r2] == self.m:\n            self.num_m -= 1\n        ns = self.size[r1] + self.size[r2]\n        if ns == self.m:\n            self.num_m += 1\n            \n        if self.rank[r1] > self.rank[r2]:\n            self.parent[r2] = r1\n            self.size[r1] = ns\n        else:\n            if self.rank[r2] > self.rank[r1]:\n                self.parent[r1] = r2\n                self.size[r2] = ns\n            else:\n                self.parent[r1] = r2\n                self.rank[r2] += 1\n                self.size[r2] = ns\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        self.parent = {}\n        self.rank = {}\n        self.size = {}\n        self.m = m\n        self.num_m = 0\n        ans = -1\n        for i, v in enumerate(arr):\n            self.parent[v] = v\n            self.rank[v] = 1\n            self.size[v] = 1\n            if self.size[v] == m:\n                self.num_m += 1\n            if v-1 in self.parent:\n                self.union(v-1, v)\n            if v+1 in self.parent:\n                self.union(v+1, v)\n            if self.num_m > 0:\n                ans = i+1\n            # print(i,self.num_m,ans)\n        return ans\n", "from collections import Counter\nfrom typing import List\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:        \n        n = len(arr)\n        last = -2        \n        sizes = Counter()        \n        starts, ends = {}, {}\n            \n        def dec_sizes(size):\n            sizes[size] -= 1\n            if sizes[size] <= 0:\n                sizes.pop(size)\n    \n        for i, x in enumerate(arr):\n            x -=1                        \n            count = 1            \n            start = x\n            end = x\n            \n            left = x - 1\n            if left >= 0 and left in ends:\n                len_ = ends.pop(left)\n                j = left - len_ + 1                \n                starts.pop(j)\n                start = j\n                count += len_                \n                dec_sizes(len_)\n                            \n            right = x + 1\n            if right < n and right in starts:\n                len_ = starts.pop(right)\n                j = right + len_ - 1\n                ends.pop(j)\n                end = j\n                count += len_\n                dec_sizes(len_)\n                \n            starts[start] = count\n            ends[end] = count                                             \n            sizes[count] += 1\n            \n            if m in sizes:\n                last = i\n        \n        return last + 1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        if m==len(arr): return m\n        \n        border=[0]*(len(arr)+2)\n        ans=-1\n        \n        for i in range(len(arr)):\n            left=right=arr[i]\n            if border[right+1]>0: right=border[right+1]\n            if border[left-1]>0: left=border[left-1]\n            border[left], border[right] = right, left\n            if (right-arr[i]==m) or (arr[i]-left ==m): ans=i\n        \n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = [i for i in range(n)]\n        self.ranks = [0]*n\n    \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n\n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \nclass Solution:    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        print((uf.ranks))\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parents = list(range(N))\n        sizes = [0] * N\n        \n        islands = set()\n        \n        def union(one, two):\n            r1 = findroot(one)\n            r2 = findroot(two)\n            \n            if r1 == r2: return sizes[r1]\n            if sizes[r1] == m and r1 in islands:\n                islands.remove(r1)\n            if sizes[r2] == m and r2 in islands:\n                islands.remove(r2)\n            big, small = (r1, r2) if sizes[r1] > sizes[r2] else (r2, r1)\n            parents[small] = big\n            sizes[big] += sizes[small]\n            return sizes[big]\n        \n        def findroot(pos):\n            if parents[pos] != pos:\n                parents[pos] = findroot(parents[pos])\n            return parents[pos]\n        \n        last_round = -1\n        for i, pos in enumerate(arr, 1):\n            pos -= 1\n            sizes[pos] += 1\n            sz = sizes[pos]\n            if pos < N - 1 and sizes[pos + 1]:\n                sz = union(pos, pos+1)\n            if pos > 0 and sizes[pos - 1]:\n                sz = union(pos-1, pos)\n            if sz == m:\n                islands.add(findroot(pos))\n            if islands:\n                last_round = i\n        \n        return last_round\n            \n", "class UnionFind:\n    \n    def __init__(self, n):\n        # every node's parent is itself\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        \n        if pu == pv:\n            return \n        \n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        \n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n            \n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFind(n)\n        \n        if m == n:\n            return m\n        \n        for step, i in enumerate(arr):    \n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step    \n                    if uf.ranks[j]:\n                        uf.union(i, j)\n            \n        return ans", "# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         bits = [0]*len(arr)\n        \n#         #2 choice for key: step value or index locations\n        \n#         for i in reversed(range(len(arr))):\n            \nfrom collections import Counter\nclass DSU:\n    def __init__(self,n):\n        self.par = [x for x in range(n)]\n        self.sz = [1]*n\n    \n    def find(self,x):\n        if self.par[x]!=x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self,x,y):\n        xp,yp = self.find(x),self.find(y)\n        if xp == yp:\n            return False\n        if self.sz[xp] < self.sz[yp]:\n            xp,yp = yp,xp\n            \n        self.par[yp] = xp\n        self.sz[xp] += self.sz[yp]\n        self.sz[yp] = self.sz[xp]\n        return True\n        \n    def size(self,x):\n        xp = self.find(x)\n        return self.sz[xp]\n    \nclass Solution:\n    def findLatestStep(self, arr,m):\n        res = -1\n        n = len(arr)\n        dsu = DSU(n)\n        \n        A = [0]*n\n        count = Counter()\n        for i,x in enumerate(arr,start=1):\n            x -= 1\n            A[x] = 1\n            this = 1\n            if x-1>=0 and A[x-1]:\n                left = dsu.size(x-1)\n                dsu.union(x,x-1)\n                this += left\n                count[left] -= 1\n            if x+1<n and A[x+1]:\n                right = dsu.size(x+1)\n                dsu.union(x,x+1)\n                this += right\n                count[right] -=1\n                \n            count[this] += 1\n            if count[m] >0:\n                res = i\n        return res", "class Solution:\n    \n    def find(self, d, x):\n        while x != d[x]:\n            x = d[x]\n        return x\n    \n    def union(self, d, x, y):\n        px, py = self.find(d, x), self.find(d, y)\n        if px != py:\n            d[px] = py\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, step, rec = len(arr), -1, 0\n        s, d, d_len = [0]*n, {i:i for i in range(n)}, [1]*n\n        for i in range(n):\n            num = arr[i] - 1\n            s[num] = 1\n            for j in (num-1, num+1):\n                if j >= 0 and j < n and s[j] == 1:\n                    temp = d_len[self.find(d, j)]\n                    if temp == m:\n                        rec -= 1\n                    self.union(d, j, num)\n                    d_len[num] += temp\n            if d_len[num] == m:\n                rec += 1\n            if rec > 0:\n                step = i+1\n        return step\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        class DSU:\n            def __init__(self, n, m):\n                self.parent = [i for i in range(n)]\n                self.size = [0] * n\n                self.m = m\n                self.cntm = 0\n                \n            def add(self, x):\n                self.size[x] = 1\n                if self.m == 1:\n                    self.cntm += 1\n                self.unite(x - 1, x)\n                self.unite(x, x + 1)\n\n            def find(self, x):\n                if self.parent[x] != x:\n                    self.parent[x] = self.find(self.parent[x])\n                return self.parent[x]\n            \n            def unite(self, x, y):\n                if x < 0 or self.size[x] == 0 or y == len(self.size) or self.size[y] == 0:\n                    return \n                px, py = self.find(x), self.find(y)\n                self.cntm -= self.size[px] == self.m\n                self.cntm -= self.size[py] == self.m\n\n                if self.size[px] < self.size[py]:\n                    px, py = py, px\n                self.size[px] += self.size[py]\n                self.parent[py] = px\n                self.cntm += self.size[px] == self.m\n                \n            \n        n = len(arr)\n        dsu = DSU(n, m)\n        latest = -1\n        \n        for i in range(n):\n            dsu.add(arr[i] - 1)\n            if dsu.cntm:\n                latest = i + 1\n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        \n        def dfs(start: int, end: int, step: int, target: int):\n            if end > len(arr) or end < 1:\n                return -1\n            if start > len(arr) or start < 1:\n                return -1\n            if end < start:\n                return -1\n            if end - start + 1 < target:\n                return -1\n\n            if end - start + 1 == target:\n                return step\n            bp = arr[step - 1]\n            res = -1\n            if start <= bp <= end:\n                res = max(dfs(start, bp - 1, step - 1, target), dfs(bp + 1, end, step - 1, target))\n            else:\n                res = max(res, dfs(start, end, step - 1, target)) \n            return res\n        \n        return dfs(1, n, n, m)\n        \n        \n", "from collections import Counter\nclass DSU:\n    def __init__(self,n):\n        self.par = [x for x in range(n)]\n        self.sz = [1]*n\n    \n    def find(self,x):\n        if self.par[x]!=x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self,x,y):\n        xp,yp = self.find(x),self.find(y)\n        if xp == yp:\n            return False\n        if self.sz[xp] < self.sz[yp]:\n            xp,yp = yp,xp\n            \n        self.par[yp] = xp\n        self.sz[xp] += self.sz[yp]\n        self.sz[yp] = self.sz[xp]\n        return True\n        \n    def size(self,x):\n        xp = self.find(x)\n        return self.sz[xp]\n    \nclass Solution:\n    def findLatestStep(self, arr,m):\n        res = -1\n        n = len(arr)\n        dsu = DSU(n)\n        \n        A = [0]*n\n        count = Counter()\n        for i,x in enumerate(arr,start=1):\n            x -= 1\n            A[x] = 1\n            this = 1\n            if x-1>=0 and A[x-1]:\n                left = dsu.size(x-1)\n                dsu.union(x,x-1)\n                this += left\n                count[left] -= 1\n            if x+1<n and A[x+1]:\n                right = dsu.size(x+1)\n                dsu.union(x,x+1)\n                this += right\n                count[right] -=1\n                \n            count[this] += 1\n            if count[m] >0:\n                res = i\n        return res", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        n = len(a)\n        ans = -1\n        d = {}\n        ls = [0]*(n+3)\n        for ind, i in enumerate(a):\n            j,k = i-1, i+1\n            ls[i] = 1\n            l,r = ls[j], ls[k]\n            # while j<n+2 and ls[j] == 1:\n            #     l += 1\n            #     j += 1\n            # while k>0 and ls[k] == 1:\n            #     r += 1\n            #     k -= 1\n            d[l] = d.get(l, 0) - 1\n            d[r] = d.get(r, 0) - 1\n            d[l+r+1] = d.get(l+r+1, 0) + 1\n            ls[i-l] = l+r+1\n            ls[i+r] = l+r+1\n            # print(l, r, d, ls)\n            if m in d and d[m]>0:\n                # print(d, a, m, ls)\n                ans = ind+1\n            \n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m \n        groups = [0] * (len(arr) + 2)\n        res = -1\n        for i, num in enumerate(arr):\n            left, right = groups[num - 1], groups[num + 1]\n            groups[num-groups[num-1]] = left + right + 1\n            groups[num+groups[num+1]] = left + right + 1\n            if left == m or right == m :\n                res = i\n        return res\n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        self.size = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.size[pu] += self.size[pv]\n        elif self.ranks[pu] < self.ranks[pv]:\n            self.parents[pu] = pv\n            self.size[pv] += self.size[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += 1\n            self.size[pv] += self.size[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            uf.size[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    # if uf.ranks[uf.find(j)] == m:\n                    if uf.size[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n: return n \n        arr.append(n+1)\n        start = defaultdict(dict)\n        finish = defaultdict(dict)\n        last = -1\n        for level,i in enumerate(arr):\n            if i-1 not in finish: finish[i-1] = i \n            if i+1 not in start: start[i+1] = i\n\n            s, f = finish[i-1], start[i+1]\n            start[s] = f \n            finish[f] = s\n            \n            for os, of in [[i+1, start[i+1]], [finish[i-1], i-1]]:\n                if of-os+1 == m: last = level\n        \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start_mp, end_mp = {}, {}\n        max_step = -1\n        m_cnt = 0\n        for idx, num in enumerate(arr): \n            l = 1\n            if num-1 not in end_mp and num+1 not in start_mp: \n                start_mp[num] = end_mp[num] = 1\n                start_index = end_index = num\n            elif num-1 in end_mp and num +1 in start_mp:\n                # merge\n                old_l = end_mp[num-1]\n                old_r = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                if old_r == m: \n                    m_cnt -= 1\n                start_index = num-1 - end_mp[num-1] + 1\n                end_index = num+1 + start_mp[num+1] -1\n                l = end_mp[num-1] + start_mp[num+1] + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1], start_mp[num+1], end_mp[num+1+old_r-1]\n                start_mp[start_index] = l\n                end_mp[end_index] = l\n            elif num-1 in end_mp: \n                # extend to the left\n                old_l = end_mp[num-1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num-1], start_mp[num-1-old_l+1]\n                start_index = num-l+1 \n                end_index = m\n                end_mp[num] = start_mp[num-l+1] = l\n            elif num+1 in start_mp: \n                old_l = start_mp[num+1]\n                if old_l == m: \n                    m_cnt -= 1\n                l = old_l + 1\n                del end_mp[num+1+old_l-1], start_mp[num+1]\n                start_mp[num] = end_mp[num+l-1] = l\n                start_index = num\n                end_index = num+l-1\n            \n            if l == m: \n                m_cnt += 1\n            if m_cnt > 0: \n                max_step = max(max_step, idx + 1)\n        return max_step\n                \n                \n            \n            \n            \n                \n            \n            \n            \n            \n            \n", "def getGroup(groupsByNum, n):\n    path = []\n    while groupsByNum[n] != n:\n        path.append(n)\n        n = groupsByNum[n]\n    for x in path:\n        groupsByNum[x] = n\n    return n\n\ndef joinGroups(a, b, groupsByNum, sizeByGroup, groupBySize):\n    try:\n        b = getGroup(groupsByNum, b)\n        a = getGroup(groupsByNum, a)\n        if a != b:\n            aSize = sizeByGroup[a]\n            bSize = sizeByGroup[b]\n            if aSize > bSize:\n                a, b = b, a\n                aSize, bSize = bSize, aSize\n            \n            groupsByNum[a] = b\n            del sizeByGroup[a]\n            sizeByGroup[b] += aSize\n            groupBySize[aSize].remove(a)\n            groupBySize[bSize].remove(b)\n            try:\n                groupBySize[sizeByGroup[b]].add(b)\n            except KeyError:\n                groupBySize[sizeByGroup[b]] = {b}\n            \n            \n            return True\n        else:\n            return False\n    except KeyError:\n        return False\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sizeByGroup = dict()\n        groupBySize = {1: set()}\n        groupsByNum = dict()\n        \n\n        result = -1\n        for step, x in enumerate(arr, 1):\n            groupsByNum[x] = x\n            groupBySize[1].add(x)\n            sizeByGroup[x] = 1\n            joinGroups(x, x + 1, groupsByNum, sizeByGroup, groupBySize)\n            joinGroups(x, x - 1, groupsByNum, sizeByGroup, groupBySize)\n            try:\n                if len(groupBySize[m]) > 0:\n                    result = step\n            except KeyError:\n                pass\n                \n            \n        return result\n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        \n        # pos: length\n        lenMap = dict()\n        # length: cnt\n        cntMap = collections.defaultdict(lambda: 0)\n        \n        for i,x in enumerate(arr):\n            left = 0\n            right = 0\n            \n            if x - 1 in lenMap: \n                left = lenMap[x - 1]\n                cntMap[left] -= 1\n            if x + 1 in lenMap: \n                right = lenMap[x + 1]\n                cntMap[right] -= 1\n                \n            newLen = 1 + left + right\n            lenMap[x] = newLen\n            lenMap[x - left] = newLen\n            lenMap[x + right] = newLen\n            cntMap[newLen] += 1\n            \n            if cntMap[m] != 0:\n                res = i + 1\n                \n        return res\n                \n", "class UnionFind:\n\n    def __init__(self):\n        self.parents = {}\n        self.size = {}\n        self.counts = defaultdict(int)\n\n    def add(self,val):\n        self.parents[val] = val\n        self.size[val] = 1\n        self.counts[1] += 1\n\n    def find(self,u):\n        if self.parents[u] != u:\n            self.parents[u] = self.find(self.parents[u])\n\n        return self.parents[u]\n\n    def union(self,u,v):\n\n        if not u in self.parents or not v in self.parents:\n            return\n\n        pU = self.find(u)\n        pV = self.find(v)\n\n        if pU == pV:\n            return\n\n        self.counts[self.size[pU]]-=1\n        self.counts[self.size[pV]]-=1\n\n        if self.size[pU] < self.size[pV]:\n            self.parents[pU] = self.parents[pV]\n            self.size[pV] += self.size[pU]\n            self.counts[self.size[pV]] += 1\n        else:\n            self.parents[pV] = self.parents[pU]\n            self.size[pU] += self.size[pV]\n            self.counts[self.size[pU]] += 1\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UnionFind()\n        iter = 1\n        res = -1\n\n        for num in arr:\n            uf.add(num)\n\n            uf.union(num,num-1)\n            uf.union(num,num+1)\n\n            if uf.counts[m] > 0:\n                res = iter\n\n            iter += 1\n\n        return res", "from collections import defaultdict\n\nclass Solution:\n    def findLatestStep(self, arr_: List[int], m: int) -> int:\n        arr = [a - 1 for a in arr_]\n        n = len(arr)\n        last_round = -1\n\n        length = defaultdict(int)\n        count = defaultdict(int)\n\n        for i, a in enumerate(arr):\n            left, right = length[a-1], length[a+1]\n            new_length = left + right + 1\n\n            length[a-left] = new_length\n            length[a+right] = new_length\n\n            count[new_length] += 1\n            count[left] -= 1\n            count[right] -= 1\n\n            if count[m] > 0:\n                last_round = i + 1\n        \n        return last_round\n        \n", "# class UnionFind:\n#     def __init__(self, n):\n#         self.parent = {}\n#         self.rank = [0] * (n+1)\n#         self.group_size = defaultdict(list)\n    \n#     def find(self, x):\n#         if x not in self.parent:\n#             self.parent[x] = x\n#             self.rank[x] = 1\n#             self.group_size[1].append(x)\n\nclass UnionFind:\n        def __init__(self, m, n):\n            self.m = m\n            self.parents = [i for i in range(n+1)]\n            # self.ranks = [1 for _ in range(n)]\n            self.group_size = defaultdict(set)\n            # self.group_size[1] = set([i+1 for i in range(n)])\n            self.sizes = defaultdict(int)\n            # for i in range(n):\n            #     self.sizes[i+1] = 1\n\n        def find(self, x):\n            if self.parents[x]!=x:\n                self.parents[x] = self.find(self.parents[x])\n            return self.parents[x]\n\n        def union(self, x, y):\n            root_x, root_y = self.find(x), self.find(y)\n            # print(\\\"x\\\", x ,\\\"y\\\", y)\n            # print(\\\"root_x\\\", root_x ,\\\"root_y\\\", root_y)\n            self.parents[root_x] = root_y\n            size_root_x = self.sizes[root_x]\n            self.sizes[root_x] = 0\n            self.group_size[size_root_x].remove(root_x)\n\n            size_root_y = self.sizes[root_y]\n            self.group_size[size_root_y].remove(root_y)\n            self.sizes[root_y] = size_root_y + size_root_x\n            self.group_size[self.sizes[root_y]].add(root_y)\n            \n            \n            # print(\\\"len(self.group_size[self.m])\\\", len(self.group_size[self.m]))\n            if len(self.group_size[self.m])>0:\n                return True\n            else:\n                return False\n            \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(m, n)\n        # print(uf.group_size)\n        # print(uf.sizes)\n        seen = set()\n        res = -1\n        for idx, x in enumerate(arr):\n            seen.add(x)\n            uf.sizes[x] = 1\n            uf.group_size[1].add(x)\n            if x-1 in seen:\n                uf.union(x, x-1)\n                # if len(uf.group_size[m])>0:\n                #     res = idx+1\n            if x+1 in seen:        \n                uf.union(x+1, x)\n                \n            if len(uf.group_size[m])>0:\n                res = idx+1\n            # print(\\\"uf.group_size\\\", uf.group_size)\n            # print(\\\"uf.sizes\\\", uf.sizes)\n        return res\n            \n", "#https://leetcode.com/problems/find-latest-group-of-size-m/discuss/836441/Very-Easy\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        # if n==m:\n        #     return n\n        \n        memo = collections.defaultdict(lambda : 0)\n        res = -1\n        for idx, i in enumerate(arr):\n            left = memo[i-1]\n            right = memo[i+1]\n            if left==m or right==m:\n                res = idx\n            memo[i-left] = left+right+1\n            memo[i+right] = left+right+1\n            \n        # print (dict(memo))\n        if m==memo[1]:\n            res = n\n        \n        return res\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        '''\n        maintain a DS to record all segments (start, end).\n        For each arr[i], test if i-1 or i+1 are in the DS.\n        If so, merge the interval and insert to the DS again.\n        \n        DS:\n        - Insert interval\n        - Delete interval\n        '''\n        \n        starts = {}\n        ends = {}\n        intervals = {}\n        interval_count = 0\n        \n        ans = -1\n        \n        for i, x in enumerate(arr):\n            s, e = x, x\n            if x - 1 in ends:\n                iid = ends[x - 1]\n                s = intervals[iid][0]\n                if intervals[iid][1] - intervals[iid][0] + 1 == m:\n                    ans = max(ans, i)\n                del starts[intervals[iid][0]]\n                del ends[intervals[iid][1]]\n            if x + 1 in starts:\n                iid = starts[x + 1]\n                e = intervals[iid][1]\n                if intervals[iid][1] - intervals[iid][0] + 1 == m:\n                    ans = max(ans, i)\n                del starts[intervals[iid][0]]\n                del ends[intervals[iid][1]]\n            iid = interval_count\n            interval_count += 1\n            intervals[iid] = (s, e)\n            starts[s] = iid\n            ends[e] = iid\n            # print(iid, s, e)\n            # print(starts, ends, intervals)\n            if e - s + 1 == m:\n                ans = max(ans, i + 1)\n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        parent = {}\n        size = {}\n        sizes = collections.defaultdict(int)\n        \n        def union(a, b):\n            fa, fb = find(a), find(b)\n            parent[fa] = fb\n            sizes[size[fa]] -= 1\n            sizes[size[fb]] -= 1\n            size[fb] += size[fa]\n            sizes[size[fb]] += 1\n            \n        def get_size(a):\n            return size[find(a)]\n            \n        def find(a):\n            if a not in parent:\n                parent[a] = a\n                size[a] = 1\n                sizes[1] += 1\n                return parent[a]\n            if parent[a] != a:\n                parent[a] = find(parent[a])\n            return parent[a]\n        \n        bits = [0] * len(arr)\n        res = -1\n        for i, n in enumerate(arr):\n            idx = n-1\n            bits[idx] = 1\n            if idx - 1 >= 0 and bits[idx-1] == 1:\n                union(idx, idx-1)\n            if idx + 1 < len(bits) and bits[idx + 1] == 1:\n                union(idx, idx+1)\n            sz = get_size(idx)\n            if sizes[m] > 0:\n                res = i + 1\n        return res\n            \n    \n    \n    \n    def findLatestStep1(self, arr: List[int], m: int) -> int:\n        res, n = -1, len(arr)\n        length, cnts = [0] * (n+2), [0] * (n+1)\n        for i in range(n):\n            a = arr[i]\n            left, right = length[a-1], length[a+1]\n            newlen = left + right + 1\n            length[a] = newlen\n            length[a - left] = newlen\n            length[a + right] = newlen\n            cnts[left] -= 1\n            cnts[right] -= 1\n            cnts[length[a]] += 1\n            if cnts[m] > 0:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        size = [0] * (n + 1)\n        parents = list(range(n + 1))\n        def find(x):\n            if parents[x] != x:\n                parents[x] = find(parents[x])\n            return parents[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if size[px] < size[py]:\n                px, py = py, px\n            parents[py] = px\n            size[px] += size[py]\n        \n        result = -1\n        for j, i in enumerate(arr):\n            size[i] = 1\n            if i > 1 and size[find(i - 1)] == m:\n                result = j\n            if i < n and size[find(i + 1)] == m:\n                result = j\n            if i > 1 and size[i - 1]: \n                union(i, i - 1)\n            if i < n and size[i + 1]:\n                union(i, i + 1)\n        return result\n        \n        \n        \n#         n = len(arr)\n#         if m == n:\n#             return n\n#         segments = set([(1, n)])\n#         not_relevant = set()\n#         for i in range(n - 1, -1, -1):\n#             if arr[i] in not_relevant:\n#                 continue\n#             to_add = []\n#             to_remove = None\n#             for left, right in segments:\n#                 if left <= arr[i] <= right:\n#                     to_remove = (left, right)\n#                     left_len = arr[i] - left\n#                     right_len = right - arr[i]\n#                     if left_len == m or right_len == m:\n#                         return i\n#                     if left_len > m:\n#                         to_add.append((left, arr[i] - 1))\n#                     else:\n#                         for j in range(left, arr[i]):\n#                             not_relevant.add(j)\n#                     if right_len > m:\n#                         to_add.append((arr[i] + 1, right))\n#                     else:\n#                         for j in range(arr[i] + 1, right + 1):\n#                             not_relevant.add(j)\n#                     break\n#             for segment in to_add:\n#                 segments.add(segment)\n#             if to_remove:\n#                 segments.discard(to_remove)\n#             if not segments:\n#                 return -1\n#         return -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        #Union find\n        records = []\n        self.num_m = 0\n        for i in range(len(arr)):\n            records.append([-1,0])\n        def find(i):\n            if records[i][0] == -1:\n                return -1\n            elif records[i][0] == i:\n                return i\n            else:\n                ii = find(records[i][0])\n                records[i][0] = ii\n                return ii\n        def union(i,j):\n            ans_i = find(i)\n            ans_j = find(j)\n            if records[ans_i][1] > records[ans_j][1]:\n                records[ans_j][0] = ans_i\n                if m == records[ans_i][1]:\n                    self.num_m -= 1\n                if m == records[ans_j][1]:\n                    self.num_m -= 1\n                records[ans_i][1] += records[ans_j][1]\n                if m == records[ans_i][1]:\n                    self.num_m += 1\n            else:\n                records[ans_i][0] = ans_j\n                if m == records[ans_i][1]:\n                    self.num_m -= 1\n                if m == records[ans_j][1]:\n                    self.num_m -= 1\n                records[ans_j][1] += records[ans_i][1]\n                if m == records[ans_j][1]:\n                    self.num_m += 1\n\n        last = -1\n        for i, n in enumerate(arr):\n            num = n - 1\n            records[num] = [num,1]\n            if m == 1:\n                self.num_m += 1\n            if num >= 1 and records[num - 1][0] != -1:\n                if records[num-1][1] == 1:\n                    union(num - 1, num)\n                else:\n                    union(num - 1, num)\n            if num < len(arr) - 1 and records[num + 1][0] != -1:\n                if records[num+1][1] == 1:\n                    union(num + 1, num)\n                else:\n                    union(num + 1, num)\n            if self.num_m > 0:\n                last = i+1\n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        from collections import defaultdict \n        parents = [i for i in range(n)]\n        ranks = [0] * n\n        size = [1] * n \n        group_size = [0] * (n+1)\n        visited = [False] * n\n        \n        def find(x):\n            if x != parents[x]:\n                parents[x] = find(parents[x])\n            return parents[x]\n        \n        def union(x, y):\n            r1 = find(x)\n            r2 = find(y)\n         \n            if r1 != r2:\n                group_size[size[r1]] -= 1 \n                group_size[size[r2]] -= 1 \n                size[r1] = size[r2] = size[r1] + size[r2]\n                group_size[size[r1]] += 1 \n            \n                if ranks[r2] > ranks[r1]:\n                    r1, r2 = r2, r1 \n                \n                parents[r2] = r1 \n                if ranks[r1] == ranks[r2]:\n                    ranks[r1] += 1\n        \n        ans = -1\n        for step, idx in enumerate(arr):\n            idx -= 1 \n            left, right = idx - 1, idx + 1\n            group_size[1] += 1 \n            if left >= 0 and visited[left]:\n                union(idx, left)\n            if right < n  and visited[right]:\n                union(idx, right)\n            \n            visited[idx] = True\n            if group_size[m] > 0:\n                ans = step + 1 \n        \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        g_right = {}\n        g_left = {}\n        lengths = [0] * n # number of cells with length 1, 2, ... , n\n        res = -1\n        for itr,i in enumerate(arr):\n            pos = i-1\n            rb = i-1\n            lb = i-1\n            \n            if pos + 1 in g_right:\n                rb = g_right[pos + 1]\n                end = g_right.pop(pos + 1)\n                lengths[end - (pos + 1)] -= 1\n            \n            if pos - 1 in g_left:\n                lb = g_left[pos - 1]\n                end = g_left.pop(pos - 1)\n                lengths[(pos - 1) - end] -= 1\n            \n            g_left.update({rb:lb})\n            g_right.update({lb:rb})\n            lengths[rb - lb] += 1\n            # print(lengths)\n            if lengths[m-1] > 0:\n                res = itr + 1\n\n        return res\n        #     for i in g_\n        #     if m in s:\n        #         res = itr + 1\n        # return res\n            \n            \n", "class Solution:\n    def find(self, n):\n        if self.par[n] == n:\n            return n\n        else:\n            self.par[n] = self.find(self.par[n])\n            return self.par[n]\n        \n    def union(self, n1, n2):\n        p1 = self.find(n1)\n        p2 = self.find(n2)\n        if self.rank[p1] < self.rank[p2]:\n            self.par[p1] = p2\n            self.rank[p2] += self.rank[p1]\n        elif self.rank[p1] > self.rank[p2]:\n            self.par[p2] = p1\n            self.rank[p1] += self.rank[p2]    \n        else:\n            self.par[p2] = p1\n            self.rank[p1] += self.rank[p2]\n            \n        \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        self.N = N\n        if m == N:\n            return N\n        \n        self.par = list(range(N+1))\n        self.rank = [0]*(N+1)\n        \n        result = -1\n        for i, v in enumerate(arr, 1):\n            self.rank[v] = 1\n            for j in [v-1, v+1]:\n                if 1<=j<=N and self.rank[j]:\n                    if self.rank[self.find(j)] == m:\n                        result = i-1\n                    self.union(j, v)\n\n            \n        for i in range(1, N+1):\n            if self.rank[self.find(i)] == m:\n                return N\n            \n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        start = {}\n        end = {}\n        groups = collections.defaultdict(set)\n        ans = -1\n        for idx,a in enumerate(arr):\n            new_start,new_end = a,a\n            if a + 1 in start:\n                new_end = start[a + 1]\n                del start[a + 1]\n                groups[new_end - (a + 1 )+ 1].remove((a+1,new_end))\n            if a - 1 in end:\n                new_start = end[a-1]\n                del end[a-1]\n                groups[a-1 - new_start + 1].remove((new_start,a-1))\n            start[new_start] = new_end\n            end[new_end] = new_start\n            groups[new_end - new_start + 1].add((new_start,new_end))\n            #print(groups)\n            if len(groups[m])>0:ans = idx+1\n            #print(groups)\n        return ans\n                \n            \n", "# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         #\u4e24\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u8bb0\u5f55\u957f\u5ea6\uff0c\u53e6\u4e00\u4e2a\u8bb0\u5f55\u957f\u5ea6\u7684\u4e2a\u6570\n#         length = [0 for _ in range(len(arr)+2)]\n#         count = [0 for _ in range(len(arr)+1)]\n#         res = -1\n#         for i, a in enumerate(arr):\n#             #\u5148\u628a\u5de6\u8fb9\u7684\u957f\u5ea6\u548c\u53f3\u8fb9\u76841\u957f\u5ea6\u53d6\u51fa\u6765\n#             left, right = length[a-1], length[a+1]\n#             #\u73b0\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u7684\u957f\u5ea6\u5c31\u662f\u5de6\u8fb9\u7684\u957f\u5ea6\u52a0\u4e0a\u53f3\u8fb9\u7684\u957f\u5ea6\u52a0\u4e0a\u81ea\u5df1\n#             #\u8ddd\u79bba\u4f4d\u7f6e\u7684\u5de6\u53f3\u4e24\u8fb9\u7684\u8fb9\u89d2\u5904\u7684\u7d22\u5f15\u4e5f\u4f1a\u88ab\u9644\u4e0a\u65b0\u7684\u503c\uff0c\u4e4b\u540e\u7684\u8ba1\u7b97\u53ef\u80fd\u7528\u5f97\u4e0a\n#             length[a] = length[a-left] = length[a+right] = left + right + 1\n            \n#             #\u7136\u540e\u5c31\u662f\u66f4\u65b0count\u4e86\n#             count[left] -= 1\n#             count[right] -= 1\n#             count[length[a]] += 1\n            \n#             #\u5224\u65adm\u662f\u5426\u8fd8\u5b58\u5728\uff0c\u53ea\u8981m\u5b58\u5728\u90a3\u5c31\u662f\u6ee1\u8db3\u6761\u4ef6\u7684\u6700\u540e\u4e00\u6b65\n#             if count[m]:\n#                 res = i+1\n#         return res\n\nclass UnionFindSet:\n    def __init__(self, n):\n        self.parents = [i for i in range(n)]\n        self.ranks = [0 for _ in range(n)] #\u8868\u793aindex\u4f4d\u7f6e\u76841\u7684\u957f\u5ea6\n\n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        \n        #\u4f5c\u4e3a\u7236\u4eb2\u8282\u70b9\u7684\u6761\u4ef6\uff0c\u8c01\u7684\u957f\u5ea6\u6bd4\u8f83\u5927\u3002\u5c31\u8ddf\u7740\u8c01\u3002 \u5982\u679c\u957f\u5ea6\u76f8\u540c\u65f6\u4f1a\u4e0d\u4f1a\u6709\u95ee\u9898? \u611f\u89c9\u8fd9\u91cc\u5199\u5f97\u4e0d\u5bf9\uff0c\u957f\u5ea6\u76f8\u540c\u65f6\u5e94\u8be5\u770bpu\u548cpv\u54ea\u4e2a\u6bd4\u8f83\u5927(\u5c0f). \u4e5f\u8bb8\u6309\u957f\u5ea6\u6765\u4f5c\u4e3a\u7236\u4eb2\u8282\u70b9\u5e76\u6ca1\u6709\u5f71\u54cd\uff0c\u4e5f\u53ef\u4ee5\u5c1d\u8bd5\u627e\u7d22\u5f15\u503c\u8f83\u5c0f\u7684\u5143\u7d20\u4f5c\u4e3a\u7236\u4eb2\u8282\u70b9\n        # if self.ranks[pu] > self.ranks[pv]:\n        #     self.parents[pv] = self.parents[pu]\n        #     self.ranks[pu] += self.ranks[pv] #\u8fd9\u91cc\u53ea\u4fee\u6539pu\u76841\u957f\u5ea6\u539f\u56e0\u662f\uff0c\u4ee5\u540e\u67e5\u8be2pv\u7684\u957f\u5ea6\u90fd\u4f1a\u6307\u5411pu\u7684\u957f\u5ea6\n        # else:\n        #     self.parents[pu] = self.parents[pv]\n        #     self.ranks[pv] += self.ranks[pu]\n        self.parents[max(pu,pv)] = min(pu, pv)\n        self.ranks[min(pu,pv)] += self.ranks[max(pu,pv)]\n             \n        return True\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m: #\u6700\u540e\u4e00\u6b65\n            return m\n        \n        uf = UnionFindSet(len(arr))\n        n, ans = len(arr), -1\n        \n        for step, a in enumerate(arr):\n            a -= 1 #\u5b57\u7b26\u4e32\u7d22\u5f15\u4ece0\u5f00\u59cb\n            \n            uf.ranks[a] = 1\n            #\u627e\u5de6\u53f3\u8282\u70b9\u8fdb\u884c\u8054\u7ed3\n            for j in (a-1, a+1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        #\u4e0a\u4e00\u6b65\u8fd8\u5b58\u5728m\u957f\u5ea6\u76841\u7fa4. \u4e5f\u8bb8\u5728\u5176\u4ed6\u5730\u65b9\u8fd8\u6709\u5b58\u5728m\u957f\u5ea6\u7684\uff0c\u4f46\u662f\u540e\u9762\u4f1a\u904d\u5386\u5230. \u6ce8\u610f\u8fd9\u91cc\u904d\u5386\u4e0d\u5230\u6700\u540e\u4e00\u6b65\n                        ans = step\n                    #\u5982\u679cj\u4f4d\u7f6e\u4e0a\u662f1,\u53731\u7684\u7fa4\u957f\u5ea6\u5927\u4e8e0\u3002 \u5219\u53ef\u4ee5\u8fdb\u884c\u8fde\u63a5\n                    if uf.ranks[j] > 0:\n                        uf.union(a , j)\n                        \n        return ans", "#https://leetcode.com/problems/find-latest-group-of-size-m/discuss/836441/Very-Easy\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n==m:\n            return n\n        \n        memo = collections.defaultdict(lambda : 0)\n        res = -1\n        for idx, i in enumerate(arr):\n            left = memo[i-1]\n            right = memo[i+1]\n            if left==m or right==m:\n                res = idx\n            memo[i-left] = left+right+1\n            memo[i+right] = left+right+1\n        # if m in memo.values():\n        #     res = n\n        return res\n            \n", "class UnionFind:\n    \n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.rank = [0]*n\n        self.size = [0]*n\n        self.groupCount = [0]*(n+1)\n    \n    def find(self, x):\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def add(self, x):\n        self.size[x] = 1\n        self.groupCount[1] += 1\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return False\n        if self.groupCount[self.size[px]] > 0: \n            self.groupCount[self.size[px]] -= 1\n        if self.groupCount[self.size[py]] > 0:\n            self.groupCount[self.size[py]] -= 1\n        if self.rank[px] > self.rank[py]:\n            self.parent[py] = px\n            self.size[px] += self.size[py]\n            self.size[py] = 0\n        elif self.rank[py] > self.rank[px]:\n            self.parent[px] = py\n            self.size[py] += self.size[px]\n            self.size[px] = 0\n        else:\n            self.parent[px] = py\n            self.size[py] += self.size[px]\n            self.size[px] = 0\n            self.rank[py] += 1\n        self.groupCount[self.size[px]] += 1\n        self.groupCount[self.size[py]] += 1\n        return True\n    \n    def getSize(self, i):\n        px = self.find(i)\n        return self.size[px]\n    \nclass Solution:\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        disjoint = UnionFind(len(arr))\n        ans = - 1\n        val = [0]*len(arr)\n        for k in range(len(arr)):\n            index = arr[k] - 1\n            val[index] += 1\n            disjoint.add(index)\n            if index > 0 and val[index] == val[index-1]:\n                disjoint.union(index, index - 1)\n            if index + 1 < len(val) and val[index] == val[index+1]:\n                disjoint.union(index, index + 1)\n            #print(k, disjoint.groupCount)\n            if disjoint.groupCount[m] > 0:\n                ans = k + 1\n            '''\n            i = 0\n            while i < len(arr):\n                if val[i] == 1 and disjoint.getSize(i) == m:\n                    i += disjoint.getSize(i)\n                    ans = k + 1\n                    continue\n                i += 1\n            '''\n            #print(k, disjoint.size, val)\n        return ans \n    \n    '''\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def check(i):\n            val = [0]*len(arr)\n            for k in range(i+1):\n                val[arr[k]-1] = 1\n            count = 0\n            success = False\n            for k in range(len(val)):\n                if val[k] > 0:\n                    count += 1\n                else:\n                    if count == m:\n                        success = True\n                        break\n                    count = 0\n            if count == m:\n                success = True\n            return success                \n            \n        left = 0\n        right = len(arr)\n        while left < right:\n            mid = left + (right - left) //2\n            if not check(mid):\n                right = mid\n            else:\n                left = mid + 1\n        print(left)\n        if left == 0 and not check(left):\n            return -1\n        else:\n            return left\n    '''\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        temp = [0]*len(arr)\n        rn = [[None, None] for i in range(len(arr))]\n        fans = None\n        ans = set()\n        st = 0\n        for ind in arr:\n            st += 1\n            i = ind - 1\n            temp[i] = 1\n            \n            if i == len(arr)-1:\n                rn[i] = [i, i]\n                if temp[i-1] == 1:\n                    if tuple(rn[i-1]) in ans:\n                        ans.remove(tuple(rn[i-1]))\n                    mn, mx = rn[i-1]\n                    rn[i] = [min(mn, rn[i][0]), max(mx, rn[i][1])]\n                    rn[rn[i][0]] = rn[rn[i][1]] = rn[i]\n                    \n            elif i == 0:\n                rn[i] = [i, i]\n                if temp[i+1] == 1:\n                    if tuple(rn[i+1]) in ans:\n                        ans.remove(tuple(rn[i+1]))\n                    mn, mx = rn[i+1]\n                    rn[i] = [min(mn, rn[i][0]), max(mx, rn[i][1])]\n                    rn[rn[i][0]] = rn[rn[i][1]] = rn[i]\n                    \n                \n            else:\n                rn[i] = [i, i]\n                if temp[i-1] == 1:\n                    if tuple(rn[i-1]) in ans:\n                        ans.remove(tuple(rn[i-1]))\n                    mn, mx = rn[i-1]\n                    rn[i] = [min(mn, rn[i][0]), max(mx, rn[i][1])]\n                    rn[rn[i][0]] = rn[rn[i][1]] = rn[i]\n                \n                if temp[i+1] == 1:\n                    if tuple(rn[i+1]) in ans:\n                        ans.remove(tuple(rn[i+1]))\n                    mn, mx = rn[i+1]\n                    rn[i] = [min(mn, rn[i][0]), max(mx, rn[i][1])]\n                    rn[rn[i][0]] = rn[rn[i][1]] = rn[i]\n            \n            if rn[i][1]-rn[i][0] == m-1:\n                ans.add(tuple(rn[i]))\n            if ans:\n                fans = st\n        if fans:\n            return fans\n        return -1\n                \n            \n          \n        \n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        indeces = {}\n        for i in range(len(arr)):\n            indeces[arr[i]] = i\n            \n        leftToRight = {}\n        rightToLeft = {}\n        result = -1\n        numOfGroup = 0\n        \n        for i in range(len(arr)):\n            num = arr[i]\n            if rightToLeft.get(num-1) is not None and leftToRight.get(num+1) is not None:\n                leftToRight[rightToLeft[num-1]] = leftToRight[num+1]\n                rightToLeft[leftToRight[num+1]] = rightToLeft[num-1]\n                if leftToRight[num+1] - rightToLeft[num-1] + 1 == m:\n                    numOfGroup += 1\n                if leftToRight.get(num+1) - (num+1) + 1 == m:\n                    numOfGroup -= 1\n                if num-1 - rightToLeft.get(num-1) + 1 == m:\n                    numOfGroup -= 1\n                leftToRight[num+1] = None\n                rightToLeft[num-1] = None\n            elif rightToLeft.get(num-1) is not None:\n                rightToLeft[num] = rightToLeft[num-1]\n                leftToRight[rightToLeft[num-1]] = num\n                if num - rightToLeft[num-1] + 1 == m:\n                    numOfGroup += 1\n                if num - 1 - rightToLeft[num-1] + 1 == m:\n                    numOfGroup -= 1\n                rightToLeft[num-1] = None\n            elif leftToRight.get(num+1) is not None:\n                leftToRight[num] = leftToRight[num+1]\n                rightToLeft[leftToRight[num+1]] = num\n                if leftToRight[num+1] - num + 1 == m:\n                    numOfGroup += 1\n                if leftToRight[num+1] - (num + 1) + 1 == m:\n                    numOfGroup -= 1\n                leftToRight[num+1] = None\n            else:\n                leftToRight[num] = num\n                rightToLeft[num] = num\n                if m == 1:\n                    numOfGroup += 1\n            if numOfGroup > 0:\n                result = i+1\n                \n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        table = collections.defaultdict(int)\n        size = [0] * len(arr)\n        parent = [-1] * len(arr)\n        res = 0\n        for i in range(len(arr)):\n            pos = arr[i] - 1\n            idx = self.find(pos, parent)\n            if idx == -1:\n                parent[pos] = pos\n                size[pos] = 1\n                table[size[pos]] = table[size[pos]] + 1\n            self.unionAround(pos, arr, parent, size, table)\n            if m in table:\n                res = i + 1\n        if res == 0:\n            return -1\n        return res\n        \n    \n    def unionAround(self, i, arr, parent, size, table):\n        if i > 0:\n            self.union(i, i-1, parent, size, table)\n        if i < len(arr) - 1:\n            self.union(i, i+1, parent, size, table)\n    \n    def union(self, i, j, parent, size, table):\n        x = self.find(i, parent)\n        y = self.find(j, parent)\n        if y == -1:\n            return\n        if x != y:\n            table[size[y]] = table[size[y]]-1\n            if table[size[y]] == 0:\n                del table[size[y]]\n                \n            table[size[x]] = table[size[x]]-1\n            if table[size[x]] == 0:\n                del table[size[x]]\n            \n            size[y] += size[x]\n            parent[x] = y\n            \n            table[size[y]] = table[size[y]] + 1\n    \n    def find(self, i, parent):\n        if parent[i] == -1:\n            return -1\n        if parent[i] == i:\n            return i\n        return self.find(parent[i], parent)\n        \n        \n        \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parents = {}\n        weights = {}\n        \n        def find(p): \n            if p not in parents:\n                parents[p] = p\n                weights[p] = 1\n            if parents[p] != p:\n                parents[p] = find(parents[p])\n            return parents[p]\n        \n        def union(p, q):\n            i, j = find(p), find(q)\n            if i == j:\n                return\n            if weights[i] >= weights[j]:\n                parents[j] = i\n                weights[i] += weights[j] # do not need to reset weights[j] to 0 since we only care about the weights at the root.\n            else:\n                parents[i] = j\n                weights[j] += weights[i]\n            \n        def connected(p, q):\n            return find(p) == find(q)\n        \n        status = [0]*len(arr)\n        \n        cnt = collections.Counter()\n        last = -1\n        \n        for step, info in enumerate(arr):\n            i = info-1\n            status[i] = 1\n            \n            if i == 0 or status[i-1] == 0:\n                left = False\n            else:\n                left = True\n            \n            if i >= len(arr)-1 or status[i+1] == 0:\n                right = False\n            else:\n                right = True\n            \n            # print(left, right)\n            if (not left) and (not right):\n                cnt[1] += 1\n                p = find(arr[i])\n                \n            elif left and right:\n                # combine all three\n                pleft = find(arr[i-1])\n                pright = find(arr[i+1])\n                size_left = weights[pleft]\n                size_right = weights[pright]\n                cnt[size_left] -= 1\n                cnt[size_right] -= 1\n                cnt[size_left + size_right + 1] += 1\n                union(arr[i-1], arr[i])\n                union(arr[i], arr[i+1])\n                \n            elif left:\n                pleft = find(arr[i-1])\n                \n                size_left = weights[pleft]\n                \n                cnt[size_left] -= 1\n                cnt[size_left + 1] += 1\n                union(arr[i-1], arr[i])\n                # print(parents, weights, pleft)\n                # print(\\\"size_left:\\\", size_left)\n            elif right:\n                pright = find(arr[i+1])\n                size_right = weights[pright]\n                cnt[size_right] -= 1\n                cnt[size_right+1] += 1\n                union(arr[i], arr[i+1])\n                \n            if cnt[m] > 0:\n                last = step+1\n            # print(cnt)\n            \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        output = -1\n        uf = UF()\n        seen = set()\n        for step, idx in enumerate(arr, 1):\n            uf.add(idx)\n            seen.add(idx)\n            if idx - 1 in seen:\n                uf.join(idx - 1, idx)\n            if idx + 1 in seen:\n                uf.join(idx, idx + 1)\n            if uf.size_counts[m]:\n                output = step\n        return output\n\nclass UF:\n    \n    def __init__(self):\n        self.parents = {}\n        self.sizes = {}\n        self.size_counts = collections.Counter()\n        \n    def add(self, n):\n        self.parents[n] = n\n        self.sizes[n] = 1\n        self.size_counts[1] += 1\n    \n    def find(self, n):\n        p = self.parents\n        while p[n] != n:\n            p[n] = p[p[n]]\n            n = p[n]\n        return n\n    \n    def join(self, a, b):\n        a = self.find(a)\n        b = self.find(b)\n        if a == b:\n            return\n\n        s = self.sizes\n        sc = self.size_counts\n        sc[s[a]] -= 1\n        sc[s[b]] -= 1\n        sc[s[a] + s[b]] += 1\n        \n        p = self.parents\n        if s[a] < s[b]:\n            p[a] = b\n            s[b] += s[a]\n        else:\n            p[b] = a\n            s[a] += s[b]\n", "class Subset:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0] * n\n    \n    def find(self,i):\n        if self.parent[i] != i:\n            self.parent[i] = self.find(self.parent[i])\n        return self.parent[i]\n\n    def union(self,u,v):\n        if self.rank[u] > self.rank[v]:\n            self.parent[v] = self.find(u)\n        if self.rank[v] > self.rank[u]:\n            self.parent[u] = self.find(v)\n        if self.rank[u] == self.rank[v]:\n            self.parent[v] = self.find(u)\n            self.rank[u] += self.rank[v]\n            \nclass Solution:       \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        subset = Subset(n)\n        ls = [0] * n\n        size = [1] * n\n        res = -1\n        cnt = 0\n        for i in range(n):\n            idx = arr[i] - 1\n            ls[idx] = 1\n            sizeMiddle = 1\n            if idx > 0:\n                if ls[idx-1] == 1:\n                    p = subset.find(idx-1)\n                    sizeLeft = size[p]\n                    subset.union(idx,p)\n                    if sizeLeft == m:\n                        cnt -= 1\n                    sizeMiddle += sizeLeft\n            if idx < n-1:\n                if ls[idx+1] == 1:\n                    p2 = subset.find(idx+1)\n                    sizeRight = size[p2]\n                    subset.union(idx,p2)\n                    if sizeRight == m:\n                        cnt -= 1\n                    sizeMiddle += sizeRight\n            finalP = subset.find(idx)\n            size[finalP] = sizeMiddle\n            if sizeMiddle == m:\n                cnt += 1\n            if cnt > 0:\n                res = max(res,i+1)\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dp = [(-1, -1)] * (len(arr) + 1)\n        groups = collections.defaultdict(int)\n        if len(arr) == 1:\n            return 1\n        res = -1\n        for i, a in enumerate(arr):\n            leftPos, rightPos = a, a\n            if a == 1:\n                rightPos = a if dp[a+1][1] == -1 else dp[a+1][1]\n            elif a == len(arr):\n                leftPos = a if  dp[a-1][0] == -1 else dp[a-1][0]\n            else:\n                leftPos = a if  dp[a-1][0] == -1 else dp[a-1][0]\n                rightPos = a if dp[a+1][1] == -1 else dp[a+1][1]\n            \n            dp[a] = (leftPos, rightPos)\n            dp[leftPos] = (leftPos, rightPos)\n            dp[rightPos] = (leftPos, rightPos)\n\n            groups[rightPos - leftPos + 1] += 1\n            groups[a - leftPos] -= 1\n            groups[rightPos - a] -= 1\n            if groups[m] >= 1:\n                res = i + 1\n        return res", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        while u != self.parents[u]:\n            self.parents[u] = self.parents[self.parents[u]]\n            u = self.parents[u]\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n                \n                    \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr = [i - 1 for i in arr]\n        n = len(arr)\n        uf = UnionFind(n)\n        s = ['0'] * n\n        steps = -1\n        if m == 1:\n            steps = 1\n        for i, idx in enumerate(arr):\n            s[idx] = '1'\n            uf.sz_count[1] += 1\n            if idx > 0 and s[idx-1] == '1':\n                uf.find_and_union(idx, idx-1)\n            if idx < n-1 and s[idx+1] == '1':\n                uf.find_and_union(idx, idx+1)\n            if uf.sz_count[m] > 0:\n                steps = i + 1\n        return steps\n\nclass UnionFind:\n    def __init__(self, n):\n        self.component_count = n\n        self.parents = list(range(n))\n        self.size = [1] * n\n        self.sz_count = Counter()\n\n    def find(self, x):\n        if self.parents[x] != x:\n            self.parents[x] = self.find(self.parents[x])\n        return self.parents[x]\n\n    def union(self, x, y):\n        if self.size[x] < self.size[y]:\n            x, y = y, x\n        self.parents[y] = x\n        self.sz_count[self.size[x]] -= 1\n        self.sz_count[self.size[y]] -= 1\n        self.size[x] += self.size[y]\n        self.sz_count[self.size[x]] += 1\n        self.component_count -= 1\n\n    # return true if two are newly unioned, false if already unioned.\n    def find_and_union(self, x, y):\n        x0 = self.find(x)\n        y0 = self.find(y)\n        if x0 != y0:\n            return self.union(x0, y0)\n        return 0", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        size = [0] * (len(arr) + 2)\n        count = collections.defaultdict(int)\n        \n        answer = -1\n        for i, value in enumerate(arr):\n            left, right = size[value - 1], size[value + 1]\n            size[value] = size[value - left] = size[value + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[size[value]] += 1\n            \n            if count[m]:\n                answer = i + 1\n        \n        return answer\n        \n    def findLatestStep_my(self, arr: List[int], m: int) -> int:\n        parent = [0] * (len(arr) + 2)\n        size = [1] * (len(arr) + 1)\n        \n        count = collections.defaultdict(int)\n        \n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                parent[px] = py\n                count[size[py]] -= 1\n                count[size[px]] -= 1\n                size[py] += size[px]\n                count[size[py]] += 1\n        \n        answer = -1\n        for i, value in enumerate(arr):\n            parent[value] = value\n            count[1] += 1\n            \n            if parent[value - 1]:\n                union(value - 1, value)\n            if parent[value + 1]:\n                union(value, value + 1)\n            \n            if count[m]:\n                answer = i + 1\n        \n        return answer", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        \n        steps = n\n        a1 = [[1, n]]\n        a2 = [n]\n        if m == n:\n            return steps\n        \n        while steps > 0:\n            steps -= 1\n            i = arr[steps]\n            \n            l = 0\n            r = len(a1) - 1\n            \n            while l <= r:\n                mid = (l + r) // 2\n                if a1[mid][0] > i:\n                    r = mid - 1\n                elif a1[mid][1] < i:\n                    l = mid + 1\n                else:\n                    left = [a1[mid][0], i - 1]\n                    right = [i + 1, a1[mid][1]]\n                    \n                    if left[0] > left[1]:\n                        if right[0] > right[1]:\n                            a1.pop(mid)\n                            a2.pop(mid)\n                            break\n                        else:\n                            a1[mid] = right\n                            a2[mid] = right[1] - right[0] + 1\n                            if a2[mid] == m:\n                                return steps\n                    else:\n                        if right[0] > right[1]:\n                            a1[mid] = left\n                            a2[mid] = left[1] - left[0] + 1\n                            if a2[mid] == m:\n                                return steps\n                        else:\n                            a1[mid] = right\n                            a2[mid] = right[1] - right[0] + 1\n                            a1.insert(mid, left)\n                            a2.insert(mid, left[1] - left[0] + 1)\n                            if a2[mid] == m or a2[mid + 1] == m:\n                                return steps\n        return -1", "class DSU:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.sz = [1] * N\n\n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    def get_size(self, x):\n        return self.sz[self.find(x)]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        if xr == yr:\n            return False\n        if self.sz[xr] < self.sz[yr]:\n            xr, yr = yr, xr\n        self.par[yr] = xr\n        self.sz[xr] += self.sz[yr]\n        self.sz[yr] = self.sz[xr]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        dsu = DSU(n)\n        cur_string = [0] * n\n        ans = -1\n        cur_m_count = 0\n        for step_0indexed, pos_1indexed in enumerate(arr):\n            pos_to_be1 = pos_1indexed-1\n            cur_string[pos_to_be1] = 1 \n            if pos_to_be1 >= 1 and cur_string[pos_to_be1-1] == 1:\n                if dsu.get_size(pos_to_be1-1) == m:\n                    cur_m_count -= 1\n                dsu.union(pos_to_be1, pos_to_be1-1)\n            if pos_to_be1 < n-1 and cur_string[pos_to_be1+1] == 1:\n                if dsu.get_size(pos_to_be1+1) == m:\n                    cur_m_count -= 1\n                dsu.union(pos_to_be1, pos_to_be1+1)\n                \n            if dsu.get_size(pos_to_be1) == m:\n                cur_m_count += 1\n            if cur_m_count > 0:\n                ans = step_0indexed + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        d=[[i-1,i+1] for i in range(0,n+2)]\n        latest = -1\n        for i,j in enumerate(arr):\n            a,b = d[j]\n            if d[a][1]-a==m+1 or a-d[a][0]==m+1 or d[b][1]-b==m+1 or b-d[b][0]==m+1:\n                latest=i\n            if b-a==m+1:\n                latest=i+1\n            if a>=0:\n                d[a][1]=b\n            if b<=n+1:\n                d[b][0]=a            \n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        p = list(range(n))\n        size = [0]*n\n\n        def find(x):\n            if x!=p[x]:\n                p[x] = find(p[x])\n            return p[x]\n\n        def union(x,y):\n            px,py = find(x),find(y)\n            if px == py:\n                return False\n            if size[px]>size[py]:\n                p[py] = px\n                size[px]+=size[py]\n            else:\n                p[px] =py\n                size[py] += size[px]\n            return True\n\n        if m == len(arr):\n            return m\n        ans = -1\n        for step,i in enumerate(arr):\n            i -= 1\n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[find(j)]==m:\n                        ans = step\n            if ans == m:\n                break\n            size[i] = 1\n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[j]:\n                        union(i,j)\n        return ans", "class UnionFind:\n    def __init__(self):\n        self.parent = {}\n        self.rank = {}\n\n    def add(self, x):\n        self.parent[x] = x\n        self.rank[x] = 0\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        xRoot, yRoot = self.find(x), self.find(y)\n\n        if xRoot == yRoot:\n            return\n\n        xRank, yRank = self.rank[xRoot], self.rank[yRoot]\n        if xRank < yRank:\n            yRoot, xRoot = xRoot, yRoot\n\n        self.parent[yRoot] = xRoot\n        self.rank[xRoot] += self.rank[yRoot]\n        # if self.rank[ yRoot] == self.rank[xRoot]:\n        #     self.rank[xRoot] += 1\n\n        return\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return len(arr)\n        if m > len(arr):\n            return -1\n        uf = UnionFind()\n        \n        for i in range(1, len(arr)+1):\n            uf.add(i)\n        ans = -1\n        seen = set()\n        \n        for i, n in enumerate(arr):\n            uf.rank[n] = 1\n            if n - 1 >= 1 and uf.rank[n-1] != 0:\n                if uf.rank[uf.find(n-1)] == m:\n                    ans = i\n                uf.union(n, n-1)\n            if n + 1 <= len(arr) and uf.rank[n+1] != 0:\n                if uf.rank[uf.find(n+1)] == m:\n                    ans = i\n                uf.union(n, n + 1)\n                \n        return ans\n        \n        \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # length = [0] * (len(arr) + 2)\n        # cnt = [0] * (len(arr) + 1)\n        # ans = -1\n        # for i, a in enumerate(arr):\n        #     left, right = length[a - 1], length[a + 1]\n        #     length[a] = length[a - left] = length[a + right] = left + right + 1\n        #     cnt[left] -= 1\n        #     cnt[right] -= 1\n        #     cnt[length[a]] += 1\n        #     if cnt[m]:\n        #         ans = i + 1\n        # return ans\n        \n        # Union-Find\n        uf = {}\n        seen = [0] * (len(arr) + 1)\n\n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n\n        def union(x, y):\n            seen[find(y)] += seen[find(x)]\n            uf[find(x)] = find(y)\n\n        ans, n = -1, len(arr)\n        for i, a in enumerate(arr, 1):\n            seen[a] = 1\n            for b in [a - 1, a + 1]:\n                if 1 <= b <= n and seen[b]:\n                    if seen[find(b)] == m:\n                        ans = i - 1\n                    union(a, b)\n        if m == n:\n            ans = n\n        return ans\n                \n                \n                \n                \n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            \n            return parent[x]\n        \n        def union(x, y):\n            xr, yr = find(x), find(y)\n            if xr == yr:\n                return False\n            if sizes[xr] < sizes[yr]:\n                (xr, yr) = (yr, xr)\n            \n            parent[yr] = xr\n            size_counter[sizes[xr]] -= 1\n            size_counter[sizes[yr]] -= 1\n            sizes[xr] += sizes[yr]\n            size_counter[sizes[xr]] += 1\n            \n            \n        n = len(arr)\n        parent = list(range(n + 1))\n        sizes = [1] * (n + 1)\n        size_counter = [0] * (n + 1)\n        last = -2\n        status = [False] * (n + 2)\n        for i, x in enumerate(arr):\n            status[x] = True\n            size_counter[1] += 1\n            prev = status[x - 1]\n            next = status[x + 1]\n            if prev:\n                union(x, x -1)\n            if next:\n                union(x, x + 1)\n            if size_counter[m]:\n                last = i\n        \n        return last + 1", "class Solution:\n    # https://leetcode.com/problems/find-latest-group-of-size-m/discuss/806786/JavaC%2B%2BPython-Count-the-Length-of-Groups-O(N)\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        length = [0 for _ in range(len(arr) + 2)]\n        res = -1\n        # n starts from 1.\n        for i, n in enumerate(arr):\n            left, right = length[n - 1], length[n + 1]\n            if left == m or right == m:\n                #update res for each time satisfying conditiong. so return the latest one.\n                res = i\n            # update edge. [0111010], change middle 0 t0 1. left = 3, right = 1.total length = 3 + 1 + 1 = 5. edge, length[1] = 5, length[6] = 5\n            length[n - left] = length[n + right] = left + right + 1\n        return res\n            \n", "class Solution:\n    def findLatestStep(self, arr, m):\n        D = dict() # D[x] records the index of the end in the interval, +: right end, -: left end\n        \n        c, ret = 0, -1 # c: count of m-intervals, ret: return index\n        for k, x in enumerate(arr, 1):\n            D[x], S = 0, 0 # S: shift\n            \n            # discuss in cases\n            if x-1 in D and x+1 in D:\n                i, j = D[x-1], -D[x+1]\n                if i+1 == m: # i+1 is the length\n                    c -= 1\n                if j+1 == m:\n                    c -= 1\n                S = i+j+2\n                D[x-i-1], D[x+j+1] = -S, S\n            elif x-1 in D:\n                i = D[x-1]\n                if i+1 == m:\n                    c -= 1\n                S = i+1\n                D[x-i-1], D[x] = -S, S\n            elif x+1 in D:\n                j = -D[x+1]\n                if j+1 == m:\n                    c -= 1\n                S = j+1\n                D[x+j+1], D[x] = S, -S\n                \n            if S+1 == m: # find a m-inteval\n                c += 1\n            if c > 0: # no m-interval in this round\n                ret = k\n        \n        return ret", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        \n        parents = list(range(N))\n        sizes = [0 for _ in range(N)]\n        m_count = 0\n        \n        def find(i):\n            if i != parents[i]:\n                parents[i] = find(parents[i])\n            return parents[i]\n\n        def merge(i, j):\n            nonlocal m_count\n            parent_i = find(i)\n            parent_j = find(j)\n            if parent_i != parent_j:\n                if sizes[parent_j] == m:\n                    m_count -= 1\n                if sizes[parent_i] == m:\n                    m_count -= 1\n                sizes[parent_j] += sizes[parent_i]\n                if sizes[parent_j] == m:\n                    m_count += 1\n                parents[parent_i] = parent_j\n                \n        groups = [0]*N\n        latest_round = -1\n        for i, a in enumerate(arr, start=1):\n            a -= 1\n            groups[a] = 1\n            sizes[a] = 1\n            if m == 1:\n                m_count += 1\n            if a-1 >= 0 and groups[a-1] == 1:\n                merge(a-1, a)\n            if a+1 < N and groups[a+1] == 1:\n                merge(a, a+1)\n            if m_count > 0:\n                latest_round = i\n        return latest_round", "from typing import List\nclass UnionFindSet:\n    def __init__(self, n):\n        self.parent = list(range(n+2))\n        self.rank = [0]*(n+2)\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, a, b):\n        pa, pb = self.find(a), self.find(b)\n        if pa == pb:\n            return False\n        if self.rank[pa] > self.rank[pb]:\n            self.parent[pb] = pa\n            self.rank[pa] += self.rank[pb]\n        else:\n            self.parent[pa] = pb\n            self.rank[pb] += self.rank[pa]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFindSet(n)\n        ans = -1\n\n        for step, idx in enumerate(arr):\n            uf.rank[idx] = 1\n            for j in [idx+1, idx-1]:\n                if uf.rank[uf.find(j)] == m:\n                    ans = step\n                if uf.rank[j]:\n                    uf.union(idx,j)\n        for i in range (1,n+1):\n            if uf.rank[uf.find(i)] == m:\n                return n \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        visited = [0 for _ in range(n)]\n        d = [0 for _ in range(n)]\n        \n        cnt = 0\n        ans = -1\n        for step, i in enumerate(arr):\n            i = i-1\n            lhs, rhs = 0, 0\n            start, end = i, i\n            visited[i] = 1\n            if i+1 < n and visited[i+1]:\n                rhs = d[i+1]\n                end = i + rhs\n                if rhs == m:\n                    cnt -= 1\n            if i- 1 >= 0 and visited[i-1]:\n                lhs = d[i-1]\n                start = i - lhs\n                if lhs == m:\n                    cnt -= 1\n                    \n            length = lhs + rhs + 1\n            d[start] = length\n            d[end] = length\n            # print(start, end, length)\n            if length == m:\n                cnt += 1\n            if cnt > 0:\n                ans = step+1\n            # print(cnt)\n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parents = list(range(N))\n        sizes = [0] * N\n        \n        islands = set()\n        \n        def union(one, two):\n            r1 = findroot(one)\n            r2 = findroot(two)\n            \n            if r1 == r2: return sizes[r1]\n            if sizes[r1] == m and r1 in islands:\n                islands.remove(r1)\n            if sizes[r2] == m and r2 in islands:\n                islands.remove(r2)\n            big, small = (r1, r2) if sizes[r1] > sizes[r2] else (r2, r1)\n            parents[small] = big\n            sizes[big] += sizes[small]\n            return sizes[big]\n        \n        def findroot(pos):\n            if parents[pos] != pos:\n                parents[pos] = findroot(parents[pos])\n            return parents[pos]\n        \n        last_round = -1\n        for i, pos in enumerate(arr, 1):\n            pos -= 1\n            sizes[pos] += 1\n            sz = sizes[pos]\n            if pos < N - 1 and sizes[pos + 1]:\n                sz = union(pos, pos+1)\n            if pos > 0 and sizes[pos - 1]:\n                sz = union(pos-1, pos)\n            if sz == m:\n                islands.add(findroot(pos))\n            if islands:\n                last_round = i\n        \n        return last_round", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dic = {}\n        def count_cluster(y,x,cur_count):\n            length = 0\n            if y[x-1] == 0:\n                if x <n:\n                    if y[x+1] ==0:\n                        y[x] = 1\n                        dic[x] = x\n                        if m==1:\n                            cur_count+=1\n                    else:\n                        oldr = y[x+1]\n                        y[x] = 1 + y[x+1]\n                        y[dic[x+1]] = y[x]\n                        dic[x] = dic[x+1]\n                        dic[dic[x+1]] = x\n                        if oldr == m-1:\n                            cur_count +=1\n                        if oldr == m:\n                            cur_count -=1\n                else:\n                    y[x] = 1\n                    dic[x] = x\n                    if m==1:\n                        cur_count+=1\n            else:\n                if x <n:\n                    if y[x+1] ==0:\n                        oldl = y[x-1]\n                        y[x] = y[x-1] +1\n                        y[dic[x-1]] = y[x]\n                        dic[x] = dic[x-1]\n                        dic[dic[x-1]] = x\n                        if oldl == m-1:\n                            cur_count +=1\n                        if oldl == m:\n                            cur_count -=1\n                    else:\n                        oldr = y[x+1]\n                        oldl = y[x-1]\n                        y[x] = y[x-1] + 1 + y[x+1]\n                        temp = dic[x-1]\n                        \n                        y[dic[x-1]] = y[x]\n                        # dic[x] = dic[x-1]\n                        dic[dic[x-1]] = dic[x+1]\n                        \n                        y[dic[x+1]] = y[x]\n                        # dic[x] = dic[x+1]\n                        dic[dic[x+1]] = temp\n                        \n                        if oldr==m:\n                            cur_count -= 1\n                        if oldl ==m:\n                            cur_count-=1\n                        if oldr+oldl == m-1:\n                            cur_count+=1\n                else:\n                    oldl = y[x-1]\n                    y[x] = y[x-1] +1\n                    y[dic[x-1]] = y[x]\n                    dic[x] = dic[x-1]\n                    dic[dic[x-1]] = x\n                    if oldl == m-1:\n                        cur_count +=1\n                    if oldl == m:\n                        cur_count -=1\n                \n            return cur_count     \n        n = len(arr)\n\n        s = [0] * (n+1)\n        # narr = [(x,idx) for idx, x in enumerate(arr)]\n        # x = sorted(narr,key=lambda x: x[0])\n        last = -1\n        cur_count = 0\n        for idx,x in enumerate(arr):\n            # print(s,idx,x,cur_count)\n            # s[x] = 1\n            cur_count=count_cluster(s,x,cur_count)\n            if cur_count>0:\n                last = idx+1\n        print(last)\n        return last\n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        res=-1\n        x=0\n        n=len(A)\n        l2c={i:0 for i in range(1,n+1)}\n        d={}\n        for i in range(1,n+1):\n            j=A[i-1]\n            start=end=j\n            if j-1 in d:\n                start=d[j-1][0]\n                l=d[j-1][-1]-d[j-1][0]+1\n                l2c[l]-=1\n            if j+1 in d:\n                end = d[j+1][1]\n                l=d[j+1][-1]-d[j+1][0]+1\n                l2c[l]-=1\n            d[start]=[start,end]\n            d[end]=[start,end]\n            l2c[end-start+1]+=1\n            if l2c[m]>0:res=i\n        return res\n        \n        \n        \n    def findLatestStep1(self, A: List[int], m: int) -> int:\n        res=-1\n        x=0\n        n=len(A)\n        for i in range(1,n+1):\n            j=A[i-1]\n            k=1<<(n-j)\n            x+=k\n            s=bin(x)[2:]\n            ss=s.split('0')\n            if any(len(s2)==m for s2 in ss):res=i\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        A = [0 for _ in range(n+2)]\n        left = [-1 for _ in range(n+2)]\n        right = [-1 for _ in range(n+2)]\n        count = 0\n        res = -1\n        \n        for i,a in enumerate(arr):\n            if A[a-1] == 0 and A[a+1]==0:\n                left[a] = a\n                right[a] = a\n            elif A[a-1] == 0:\n                if abs(left[a+1]-right[a+1])+1 == m:\n                    count -= 1\n                left[a] = a\n                right[a] = right[a+1]\n                left[right[a]] = a\n            elif A[a+1] == 0:\n                if abs(left[a-1]-right[a-1])+1==m:\n                    count -= 1\n                left[a] = left[a-1]\n                right[a] = a\n                right[left[a]] = a\n            else:\n                if abs(left[a+1]-right[a+1])+1 == m:\n                    count -= 1\n                if abs(left[a-1]-right[a-1])+1==m:\n                    count -= 1\n                left[a] = left[a-1]\n                right[a] = right[a+1]\n                right[left[a]] = right[a]\n                left[right[a]] = left[a]\n            \n            A[a] = 1    \n            if abs(left[a]-right[a])+1 == m:\n                count += 1\n            if count >= 1:\n                res = i+1\n                \n            # print(left, right, res, count)\n        \n        return res\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr) + 1\n        group = [i for i in range(n)]\n        bits = [False] * n\n        root_to_size = [0] * n\n        \n        size_count = collections.defaultdict(int)\n        size_count[0] = n\n        ans = -1\n        for step, num in enumerate(arr, start=1):\n            g1 = self.find(group, num)\n            bits[num] = True\n            \n            size_count[root_to_size[g1]] -= 1\n            root_to_size[g1] += 1\n            size_count[root_to_size[g1]] += 1\n            \n            if num+1 <= len(arr) and bits[num+1]:\n                g2 = self.find(group, num+1)\n                group[g2] = g1\n                combined_size = root_to_size[g1] + root_to_size[g2]\n                size_count[root_to_size[g1]] -= 1\n                size_count[root_to_size[g2]] -= 1\n                root_to_size[g1] = combined_size\n                size_count[root_to_size[g1]] += 1\n                \n            if num-1 >= 1 and bits[num-1]:\n                g2 = self.find(group, num-1)\n                group[g2] = g1\n                combined_size = root_to_size[g1] + root_to_size[g2]\n                size_count[root_to_size[g1]] -= 1\n                size_count[root_to_size[g2]] -= 1\n                root_to_size[g1] = combined_size\n                size_count[root_to_size[g1]] += 1\n            \n            if m in size_count and size_count[m] > 0:\n                ans = step\n            # print(ans, step, size_count)\n        return ans\n        \n        \n    def find(self, group, i):\n        while group[i] != i:\n            group[i] = group[group[i]]\n            i = group[i]\n        return i", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        \n        n = len(a)\n        a = [i-1 for i in a]\n        val = [[i,i] for i in range(n)]\n        par = [i for i in range(n)]\n        lis = [0]*n\n        def find(chi):\n            if par[chi] == chi:\n                return chi\n            temp = find(par[chi])\n            par[chi] = temp\n            return temp\n        \n        def union(i,j):\n            pari = find(i)\n            parj = find(j)\n            \n            par[parj] = pari\n            val[pari][0] = min(val[parj][0], val[pari][0])\n            val[pari][1] = max(val[parj][1], val[pari][1])\n        \n        ans = -1\n        cnt = 0\n        for i in range(len(a)):\n            lis[a[i]] = 1\n            if a[i]-1 >= 0 and lis[a[i]-1] == 1:\n                tval = val[find(a[i]-1)]\n                if tval[1]-tval[0] +1 == m:\n                    cnt-=1\n                union(a[i]-1, a[i])\n            if a[i]+1 < n and lis[a[i]+1] == 1:\n                tval = val[find(a[i]+1)]\n                if tval[1]-tval[0] +1 == m:\n                    cnt-=1\n                union(a[i]+1, a[i])\n            tval = val[find(a[i])]\n            if tval[1]-tval[0] +1 == m:\n                cnt+=1\n            if cnt >=1 :\n                ans = i+1\n            # print(par, cnt)\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        n = len(arr)\n        que = collections.deque([(1, n)])\n        \n        for i in range(n-1, -1, -1):\n            \n            k = len(que)\n            \n            for j in range(k):\n                l, r = que.popleft()\n                if r - l + 1 == m:\n                    return i+1\n                \n                if l <= arr[i] <= r:\n                    if arr[i]-l >= m:\n                        que.append((l, arr[i]-1))\n                    if r-arr[i] >= m:\n                        que.append((arr[i]+1, r))\n                else:\n                    que.append((l, r))\n        return -1\n            \n            \n            \n        \n        \n        \n        # change endpoint .\n        # n = len(arr)\n        # if m == n:\n        #     return m\n        # length = [0] * (n+2)\n        # # count = [0] * (n+1)\n        # res = -1\n        # for i, num in enumerate(arr):\n        #     left = length[num-1]\n        #     right = length[num + 1]\n        #     # I almost came up with this, change the endpoint.\n        #     length[num-left] = length[num+right] = left+right+1\n        #     if left == m or right == m:\n        #         res = i\n        # return res\n    \n    \n    \n    # if m == len(A): return m\n    #     length = [0] * (len(A) + 2)\n    #     res = -1\n    #     for i, a in enumerate(A):\n    #         left, right = length[a - 1], length[a + 1]\n    #         if left == m or right == m:\n    #             res = i\n    #         length[a - left] = length[a + right] = left + right + 1\n    #     return res\n                \n            \n            \n                \n            \n            \n        # Union-find\n#         n = len(arr)\n#         p = [i for i in range(n+1)]\n#         count = [0] * (n+1)\n#         ### I didn't come up with this groups at first. It shouldn't be hard.\n#         groups = [0] * (n+1)\n#         def findp(x):\n#             while x != p[x]:\n#                 x = p[x]\n#             return x\n        \n#         def union(x, y):\n            \n#             groups[count[y]] -= 1\n#             groups[count[x]] -= 1\n#             if count[x] >= count[y]:\n#                 p[y] = x\n#                 count[x] += count[y]\n#                 groups[count[x]] += 1\n#             else:\n#                 p[x] = y\n#                 count[y] += count[x]\n#                 groups[count[y]] += 1\n        \n#         res = -1\n        \n#         for i, num in enumerate(arr):\n#             # print(p)\n#             # print(count)\n#             count[num] = 1\n#             left = num-1\n#             right = num + 1\n#             groups[1] += 1\n#             if left >= 1 and count[left] != 0:\n#                 pl = findp(left)\n#                 pm = findp(num)\n#                 if pl != pm:\n#                     union(pl, pm)\n#             if right <= n and count[right] != 0:\n#                 pr = findp(right)\n#                 pm = findp(num)\n#                 if pr != pm:\n#                     union(pr, pm)\n            \n#             if groups[m] > 0:\n#                 res = i+1\n#         return res\n                    \n                \n                \n            \n        \n                \n        \n        \n        \n        \n         \n        \n            \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        s,lastOcc,countsDict,n=[0]*(len(arr)+1),-1,defaultdict(int),len(arr)\n        for traversei,ind in enumerate(arr):\n            i=ind-1\n            newSize=s[i-1]+s[i+1]+1\n            countsDict[s[i+1]]-=1\n            countsDict[s[i-1]]-=1\n            countsDict[newSize]+=1\n            s[i-s[i-1]]=s[i+s[i+1]]=newSize\n            if countsDict[m]>0:\n                    lastOcc=traversei+1\n        return lastOcc", "class UnionFind:\n    def __init__(self, n):\n        self.parent = [-1 for i in range(n)]\n        self.size = [0 for _ in range(n)]\n        self.size_count = [0 for _ in range(n + 1)]\n        self.size_count[0] = n\n        \n    def init(self, x):\n        self.parent[x] = x\n        self.size[x] = 1\n        self.size_count[1] += 1\n        self.size_count[0] -= 1\n        \n    def find(self, x):\n        if self.parent[x] == -1:\n            return -1\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        p = self.find(x)\n        q = self.find(y)\n        if p == q:\n            return\n        if p == -1 or q == -1:\n            return\n        father, son = p, q\n        self.parent[son] = father\n        self.size_count[self.size[son]] -= 1\n        self.size_count[self.size[father]] -= 1\n        self.size[father] += self.size[son]\n        self.size_count[self.size[father]] += 1\n    \n    def get_size(self, x):\n        if self.find(x) == -1:\n            return 0\n        return self.size[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(n + 1)\n        step = -1\n        for idx, num in enumerate(arr):\n            left, right = num - 1, num + 1\n            uf.init(num)\n            if left >= 1:\n                uf.union(left, num)\n            if right <= n:\n                uf.union(num, right)\n            if uf.size_count[m]:\n                step = max(step, idx + 1)\n        return step", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dp = [(-1, -1)] * (len(arr) + 1)\n        groups = collections.defaultdict(int)\n        if len(arr) == 1:\n            return 1\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = -1, -1\n            if a == 1:\n                right = a + 1\n            elif a == len(arr):\n                left = a - 1\n            else:\n                left = a - 1\n                right = a + 1\n            leftPos = a if left == -1 or dp[left][0] == -1 else dp[left][0]\n            rightPos = a if right == -1 or dp[right][1] == -1 else dp[right][1]\n            \n            dp[a] = (leftPos, rightPos)\n            if leftPos != a:\n                dp[leftPos] = (leftPos, rightPos)\n            if rightPos != a:\n                dp[rightPos] = (leftPos, rightPos)\n\n            groups[rightPos - leftPos + 1] += 1\n            groups[a - leftPos] -= 1\n            groups[rightPos - a] -= 1\n            if groups[m] >= 1:\n                res = i + 1\n            #print(a, left, right, leftPos, rightPos, groups, dp)\n        return res", "class UnionFind:\n    def __init__(self, n):\n        self.parent = [-1 for i in range(n)]\n        self.size = [0 for _ in range(n)]\n        self.size_count = [0 for _ in range(n + 1)]\n        self.size_count[0] = n\n        \n    def init(self, x):\n        self.parent[x] = x\n        self.size[x] = 1\n        self.size_count[1] += 1\n        self.size_count[0] -= 1\n        \n    def find(self, x):\n        if self.parent[x] == -1:\n            return -1\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        p = self.find(x)\n        q = self.find(y)\n        if p == q:\n            return\n        if p == -1 or q == -1:\n            return\n        father, son = p, q\n        self.parent[son] = father\n        self.size_count[self.size[son]] -= 1\n        self.size_count[self.size[father]] -= 1\n        self.size[father] += self.size[son]\n        self.size_count[self.size[father]] += 1\n    \n    def get_size(self, x):\n        if self.find(x) == -1:\n            return 0\n        return self.size[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(n + 1)\n        res = -1\n        for step, num in enumerate(arr):\n            left, right = num - 1, num + 1\n            uf.init(num)\n            if left >= 1:\n                uf.union(left, num)\n            if right <= n:\n                uf.union(num, right)\n            if uf.size_count[m]:\n                res = max(res, step + 1)\n        return res", "from collections import defaultdict\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        forLib = defaultdict(int)\n        backLib = defaultdict(int)\n        memo = {0: len(arr)}\n        for i in range(len(arr)):\n            index = arr[i]\n            val = backLib[index - 1] + 1 + forLib[index + 1]\n            if val not in memo:\n                memo[val] = 0\n            memo[val] += 1\n            memo[backLib[index - 1]] -= 1\n            memo[forLib[index + 1]] -= 1\n            if val == m:\n                ans = i + 1\n            if (backLib[index - 1] == m or forLib[index + 1] == m) and memo[m] == 0:\n                ans = i  \n            forLib[index - backLib[index - 1]] = val\n            backLib[index + forLib[index + 1]] = val\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        mem = {}\n        count = collections.Counter()\n        group_size = {}\n        def find(k):\n            if mem[k] != k:\n                mem[k] = find(mem[k])\n            return mem[k]\n\n        def union(n1, n2):\n            f1, f2 = find(n1), find(n2)\n            if f1 != f2:\n                count[group_size[f1]] -= 1\n                count[group_size[f2]] -= 1\n                group_size[f1] += group_size[f2]\n                count[group_size[f1]] += 1\n                mem[f2] = f1\n\n        for idx, v in enumerate(arr, 1):\n            mem[v] = v\n            group_size[v] = 1\n            count[1] += 1\n            left = v - 1 if v - 1 in mem else v\n            right = v + 1 if v + 1 in mem else v\n            union(left, v)\n            union(v, right)\n            if count[m] > 0:\n                res = idx\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        d={i:[i-1,i+1] for i in range(0,n+2)}\n        latest = -1\n        for i,j in enumerate(arr):\n            a,b = d.pop(j)\n            if d[a][1]-a==m+1 or a-d[a][0]==m+1 or d[b][1]-b==m+1 or b-d[b][0]==m+1:\n                latest=i\n            if b-a==m+1:\n                latest=i+1\n            if a>=0:\n                d[a][1]=b\n            if b<=n+1:\n                d[b][0]=a            \n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        L = len(arr)\n        parent = [0] * (L+1)\n        size = [1] * (L+1)\n\n        def find(x):\n            if parent[x] == 0:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            if find(x) == find(y):\n                return\n            px = find(x)\n            py = find(y)\n            if size[px] < size[py]:\n                px, py = py, px\n                \n            if size[px] == m:\n                good.discard(px)\n            if size[py] == m:\n                good.discard(py)\n                \n            parent[py] = px\n            size[px] += size[py]\n\n        bs = [0] * (L+1)\n        ret = -1\n        step = 0\n        good = set()\n        \n        for a in arr:\n            step += 1\n            bs[a] = 1\n            if a-1>=0 and bs[a-1] == 1:\n                union(a, a-1)\n            if a+1 <= L and bs[a+1] == 1:\n                union(a, a+1)\n            \n            if size[find(a)] == m:\n                good.add(find(a))\n            # print(step, good)\n            if len(good) > 0:\n                ret = step\n                \n        return ret", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        arr.insert(0, 0)\n        day = [0] * (n + 1)\n        for i in range(1, n+1):\n            day[arr[i]] = i\n        ans = -1\n        max_q = MaxQueue(m)\n        for i in range(1, n+1):\n            max_q.pop_expired(i)\n            max_q.push(day[i], i)\n            if i < m:\n                continue\n            left = right = math.inf\n            if i - m >= 1:\n                left = day[i-m]\n            if i + 1 <= n:\n                right = day[i+1]\n            if max_q.max() < (d := min(left, right)):\n                ans = max(ans, d - 1)\n        return ans\n\nclass MaxQueue:\n    def __init__(self, size):\n        self.queue = deque()\n        self.size = size\n\n    def push(self, x, pos):\n        while self.queue and self.queue[-1][0] < x:\n            self.queue.pop()\n        self.queue.append([x, pos])\n\n    def pop_expired(self, pos):\n        if self.queue and pos - self.queue[0][1] >= self.size:\n            self.queue.popleft()\n\n    def max(self):\n        return self.queue[0][0]", "\n\nimport collections\nclass Node:\n    def __init__(self, val):\n        self.size = 1\n        self.val = val\n        self.parent = self\n        \nclass UnionFind:\n    def __init__(self):\n        self.map = {}\n        self.sizes = collections.defaultdict(int)\n        \n    def find(self, node):\n        if node.val not in self.map:\n            self.map[node.val] = node\n            self.sizes[node.size] += 1\n        elif node.parent != node:\n            node = self.find(node.parent)\n        return node\n    \n    \n    def merge(self, node1, node2):\n        parent1, parent2 = self.find(node1), self.find(node2)\n        if parent1 != parent2:\n            if parent1.size >= parent2.size:\n                self.sizes[parent1.size] -= 1\n                self.sizes[parent2.size] -= 1\n                parent2.parent = parent1\n                parent1.size += parent2.size\n                self.sizes[parent1.size] += 1\n            else:\n                self.sizes[parent1.size] -= 1\n                self.sizes[parent2.size] -= 1\n                parent1.parent = parent2\n                parent2.size += parent1.size\n                self.sizes[parent2.size] += 1\n\nclass Solution:\n    def findLatestStep(self, arr, m: int) -> int:\n        uf = UnionFind()\n        ans = -1\n        for i, val in enumerate(arr):\n            node = Node(val)\n            uf.find(node)\n            if val - 1 in uf.map:\n                uf.merge(node, uf.map[val - 1])\n            if val + 1 in uf.map:\n                uf.merge(node, uf.map[val + 1])\n                \n            if uf.sizes[m] > 0:\n                ans = i + 1\n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        # \u3082\u3057u\u304c\u81ea\u5206\u306e\u89aa\u3068\u9055\u3048\u3070u\u306b\u81ea\u5206\u306e\u89aa\u306e\u89aa\u3092\u89aa\u3068\u3059\u308b\n        # \u3069\u3053\u304b\u306b\u65e2\u306b\u6240\u5c5e\u3057\u3066\u308c\u3070\u3053\u3053\u304cTrue\u3064\u307e\u308aparent\u3068\u81ea\u5206\u81ea\u8eab\u304c\u9055\u3046\u3053\u3068\u306b\u306a\u308b\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n            \n        return self.parents[u]\n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        \n        if pu == pv:\n            return False\n        \n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n\n        return ans\n# class UnionFindSet:\n#     def __init__(self, n):\n#         self.parents = list(range(n))\n#         self.ranks = [0] * n\n        \n#     def find(self, u):\n#         if u != self.parents[u]:\n#             self.parents[u] = self.find(self.parents[u])\n#         return self.parents[u]\n    \n#     def union(self, u, v):\n#         pu, pv = self.find(u), self.find(v)\n#         if pu == pv:\n#             return False\n#         if self.ranks[pu] > self.ranks[pv]:\n#             self.parents[pv] = pu\n#             self.ranks[pu] += self.ranks[pv]\n#         else:\n#             self.parents[pu] = pv\n#             self.ranks[pv] += self.ranks[pu]\n#         return True\n\n# class Solution:\n#     def findLatestStep(self, arr: List[int], m: int) -> int:\n#         n, ans = len(arr), -1\n#         uf = UnionFindSet(n)\n        \n#         for step, i in enumerate(arr):\n#             i -= 1\n#             uf.ranks[i] = 1\n#             for j in (i - 1, i + 1):\n#                 if 0 <= j < n:\n#                     if uf.ranks[uf.find(j)] == m:\n#                         ans = step\n#                     if uf.ranks[j]:\n#                         uf.union(i, j)\n        \n#         for i in range(n):\n#             if uf.ranks[uf.find(i)] == m:\n#                 return n\n            \n#         return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n\n        if len(arr) == m:\n            return m\n        \n        move = -1\n        l = {x : (0,0) for x in range(len(arr)+2)}\n        \n        for i, a in enumerate(arr):\n    \n            l[a] = (a,a)\n            b,c = a,a\n            #print(i,a,l)\n        \n            # Check Left\n            if l[a-1][0]:\n                \n                #Check Prev Length\n                if l[a-1][1] - l[a-1][0] + 1 == m:\n                    move = i\n                \n                # Left Boarder \n                b = l[a-1][0]\n                \n            # Check Right\n            if l[a+1][0]:\n                #Check Prev Length\n                if l[a+1][1] - l[a+1][0] + 1 == m:\n                    move = i\n                \n                # Right Boarder\n                c = l[a+1][1]\n                \n                            \n            # Update   \n            l[a] = (b,c)\n            l[b] = (b,c)\n            l[c] = (b,c)\n                   \n            # Check Current Length \n            if l[a][1] - l[a][0] + 1 == m:\n                move = i+1\n           \n\n        return move\n\n        \n        \n     \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans", "class Subsets:\n    def __init__(self,parent,rank):\n        self.parent=parent\n        self.rank=rank\n\ndef find(subsets,node):\n    if subsets[node].parent!=node:\n        subsets[node].parent=find(subsets,subsets[node].parent)\n    return subsets[node].parent\n\ndef union(subsets,x,y):\n    \n    xr=find(subsets,x)\n    yr=find(subsets,y)\n    \n    if xr==yr:\n        return False\n    else:\n        \n        xr=subsets[xr]\n        yr=subsets[yr]\n        \n        r1=xr.rank\n        r2=yr.rank\n        \n        if r1<r2:\n            xr.parent=yr.parent\n            yr.rank+=xr.rank\n        elif r2<r1:\n            yr.parent=xr.parent\n            xr.rank+=yr.rank\n        else:\n            xr.parent=yr.parent\n            yr.rank+=xr.rank\n            \n        return True\n            \n        \nclass Solution:\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        subsets=[Subsets(i,1) for i in range(len(arr))]\n        lst=[0]*len(arr)\n        parents = set()\n        ans=-1\n        time=1\n        \n        for index in arr:\n            \n            index-=1\n            lst[index]=1\n            \n            if index+1<len(arr) and lst[index+1]==1:\n                p=find(subsets,index+1)\n                if p in parents:\n                    parents.remove(p)\n                union(subsets,index+1,index)\n                \n                    \n            if index-1>=0 and lst[index-1]==1:\n                p=find(subsets,index-1)\n                if p in parents:\n                    parents.remove(p)\n                union(subsets,index-1,index)\n                \n                        \n            if subsets[find(subsets,index)].rank==m:\n                parents.add(find(subsets,index))\n                \n            if len(parents):\n                ans=time\n                \n            #print(parents)\n            \n            time+=1\n        \n        return ans\n            \n                \n                \n            \n            \n            \n            \n            \n            \n            \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n            \n        \n        n = len(arr)\n        p = [i for i in range(n+1)]\n        count = [0] * (n+1)\n        groups = [0] * (n+1)\n        def findp(x):\n            while x != p[x]:\n                x = p[x]\n            return x\n        \n        def union(x, y):\n            \n            groups[count[y]] -= 1\n            groups[count[x]] -= 1\n            if count[x] >= count[y]:\n                p[y] = x\n                count[x] += count[y]\n                groups[count[x]] += 1\n            else:\n                p[x] = y\n                count[y] += count[x]\n                groups[count[y]] += 1\n        \n        res = -1\n        \n        for i, num in enumerate(arr):\n            # print(p)\n            # print(count)\n            count[num] = 1\n            left = num-1\n            right = num + 1\n            groups[1] += 1\n            if left >= 1 and count[left] != 0:\n                pl = findp(left)\n                pm = findp(num)\n                if pl != pm:\n                    union(pl, pm)\n            if right <= n and count[right] != 0:\n                pr = findp(right)\n                pm = findp(num)\n                if pr != pm:\n                    union(pr, pm)\n            \n            if groups[m] > 0:\n                res = i+1\n        return res\n                    \n                \n                \n            \n        \n                \n        \n        \n        \n        \n         \n        \n            \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        count=[0]*(n+2)\n        lens=[0]*(n+2)\n        res=-1\n        for i,a in enumerate(arr):\n            if lens[a]:\n                continue\n            l=lens[a-1]\n            r=lens[a+1]\n            t=l+r+1\n            lens[a-l]=lens[a+r]=lens[a]=t\n            count[l]-=1\n            count[r]-=1\n            count[t]+=1\n            if count[m]:\n                res=i+1\n        return res", "\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr = [a - 1 for a in arr]\n        N = len(arr)\n        state = [False for _ in range(N)]\n        heads = [i for i in range(N)]\n        children = {i: [i] for i in range(N)}\n        counts = {0: N}\n\n        last = -1\n        for it, x in enumerate(arr):\n            state[x] = True\n            # print(state, heads, children, counts)\n            neighbors = [i for i in [x + 1, x - 1] if 0 <= i < N and state[i]]\n            counts[0] -= 1\n            if not neighbors:\n                counts[1] = counts.get(1, 0) + 1\n                if counts.get(m, 0) > 0:\n                    last = it\n                continue\n            neighbors.sort(key=lambda x: len(children[heads[x]]))\n            h = heads[neighbors[0]]\n            heads[x] = h\n            counts[len(children[h])] -= 1\n            children[h].append(x)\n            if len(neighbors) == 2:\n                h2 = heads[neighbors[1]]\n                for y in children[h2]:\n                    heads[y] = h\n                    children[h].append(y)\n                counts[len(children[h2])] -= 1\n            counts[len(children[h])] = counts.get(len(children[h]), 0) + 1\n            if counts.get(m, 0) > 0:\n                last = it\n        if last == -1: return -1\n        return last + 1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        answer = -1\n        n = len(arr)\n        parent = {}\n        size = {}\n        sizes = 0\n        def root(x):\n            return x if parent[x] == x else root(parent[x])\n        def merge(x, y):\n            nonlocal sizes\n            x = root(x)\n            y = root(y)\n            if size[y] == m: sizes -= 1\n            if size[x] < size[y]: x, y = y, x\n            parent[y] = x\n            size[x] += size[y]\n            del size[y]\n        for t, x in enumerate(arr):\n            parent[x] = x\n            size[x] = 1\n            if x+1 in parent: merge(x, x+1)\n            if x-1 in parent: merge(x, x-1)\n            if size[root(x)] == m: sizes += 1\n            if sizes: answer = t+1\n        return answer", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bit = [None] * (len(arr)+1)\n        res = -1\n        step = 1\n        group = 0\n        for i in range(len(arr)):\n            #print(step, arr[i], group)\n            temp = 1\n            right = 0\n            left = 0\n            #print(bit)\n            if arr[i] - 1 > 0 and bit[arr[i]-1] != None:\n                if bit[arr[i]-1] == 'True':\n                    bit[arr[i]-m] = False\n                    bit[arr[i]-1] = False\n                    bit[arr[i]] = False\n                    group -= 1\n                elif bit[arr[i]-1] == False:\n                    bit[arr[i]] = False\n                else:\n                    right += bit[arr[i]-1]\n                \n            if arr[i] + 1 <= len(arr) and bit[arr[i]+1] != None:\n                \n                    \n                if bit[arr[i]+1] == 'True':\n                    bit[arr[i]+m] = False\n                    bit[arr[i]+1] = False\n                    bit[arr[i]] = False\n                    group -= 1\n                elif bit[arr[i]] == False:\n                    if bit[arr[i]+1]:\n                        bit[arr[i]+bit[arr[i]+1]] = False\n                    bit[arr[i]+1] = False\n                elif bit[arr[i]+1] == False:\n                    bit[arr[i]] = False\n                else:\n                    left += bit[arr[i]+1]\n            if bit[arr[i]] == None:\n                #print(arr[i],right , left)\n                temp += right + left\n                bit[arr[i]] = temp\n                if right:\n                    bit[arr[i]-right] += left + 1\n                if left:\n                    bit[arr[i]+left] += right + 1\n                if temp == m:\n                    bit[arr[i]-right] = 'True'\n                    bit[arr[i]+left] = 'True'\n                    group += 1\n            #print(bit)\n            if group > 0:\n                res = step\n            step += 1\n        return res", "class UnionFind:\n    def __init__(self):\n        self.parent = dict()\n        self.rank = dict()\n        self.size = dict()\n        self.sizes = collections.defaultdict(int)\n        \n        return\n    \n    def find(self, x):\n        if x not in self.parent:\n            self.parent[x] = x\n            self.rank[x] = 0\n            self.size[x] = 1\n            self.sizes[1] += 1\n        \n        root = x\n        while self.parent[root] != root:\n            root = self.parent[root]\n        \n        while self.parent[x] != root:\n            parent = self.parent[x]\n            self.parent[x] = root\n            x = parent\n        \n        return root\n    \n    def union(self, x, y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n        \n        if x_root == y_root:\n            return\n        \n        if self.size[x_root] < self.size[y_root]:\n            x_root, y_root = y_root, x_root\n            \n        y_size = self.size[y_root]\n        x_size = self.size[x_root]\n        \n        self.sizes[x_size] -= 1\n        self.sizes[y_size] -= 1\n        \n        \n        self.parent[y_root] = x_root        \n        self.size[x_root] += self.size[y_root]\n        \n        self.sizes[self.size[x_root]] += 1\n        \n        return\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        \n        binary_string = [0] * n\n        \n        uf = UnionFind()\n        \n        max_step = -1\n        step = 1\n        \n        for i in arr:\n            index = i - 1\n            binary_string[index] = 1\n            \n            root = uf.find(i)\n            \n            if index - 1 >= 0 and binary_string[index - 1] == 1:\n                uf.union(root, i - 1)\n                \n            if index + 1 < len(binary_string) and binary_string[index + 1] == 1:\n                uf.union(root, i + 1)  \n            \n            if uf.sizes[m] > 0:\n                max_step = step\n                \n            step += 1\n        return max_step\n        \n", "class DisjointUnionSets:\n    def __init__(self,n):\n        self.rank = [0] * n \n        self.parent = [0] * n\n        self.n = n\n        self.makeSet()\n\n    def makeSet(self):\n        for i in range(self.n):\n            self.parent[i] = i\n        \n    def find(self ,x): \n        if (self.parent[x] != x):\n            self.parent[x] = self.find(self.parent[x]); \n        return self.parent[x]; \n    \n    def union(self, x, y): \n        xRoot = self.find(x)\n        yRoot = self.find(y)\n   \n        if (xRoot == yRoot): \n            return; \n  \n        if (self.rank[xRoot] < self.rank[yRoot]):\n            self.parent[xRoot] = yRoot\n            self.rank[yRoot]+=self.rank[xRoot]\n        else: \n            self.parent[yRoot] = xRoot; \n            self.rank[xRoot]+=self.rank[yRoot]\n\n\n\nclass Solution:\n    def findLatestStep(self, arr, m: int) -> int:\n        n, ans = len(arr), -1\n        uf = DisjointUnionSets(n)\n        \n        for step, i in enumerate(arr):\n            i-=1\n            uf.rank[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = step\n                    if uf.rank[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.rank[uf.find(i)] == m:\n                return n\n        return ans\n", "class UnionSet:\n    def __init__(self,n):\n        self.parent = list(range(n))\n        self.rank = [0] * n\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self,x,y):\n        xParent = self.find(x)\n        yParent = self.find(y)\n        if xParent == yParent:\n            return\n        \n        if self.rank[xParent] > self.rank[yParent]:\n            self.parent[yParent] = xParent\n            self.rank[xParent]+=self.rank[yParent]\n        else:\n            self.parent[xParent] = yParent\n            self.rank[yParent]+=self.rank[xParent]\n\n\nclass Solution:\n    def findLatestStep(self, arr, m: int) -> int:\n        us = UnionSet(len(arr))\n        ans = -1\n        for step,idx in enumerate(arr):\n            idx-=1\n            us.rank[idx] = 1      \n            for j in (-1, 1):\n                neighbour = idx+j\n                if 0<=neighbour<len(arr):\n                    if us.rank[us.find(neighbour)] == m:\n                        ans = step\n                    if us.rank[neighbour]:\n                        us.union(neighbour,idx)\n        \n        for i in range(len(arr)):\n            if us.rank[us.find(i)] == m:\n                return len(arr)\n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        index=[0]*(n+2)\n        length=[0]*(n+1)\n        ans=-1\n        for i in range(n):\n            x=arr[i]\n            l_l=index[x-1]\n            r_l=index[x+1]\n            new_l=1+l_l+r_l\n            \n            index[x]=new_l\n            index[x-l_l]=new_l\n            index[x+r_l]=new_l\n            \n            \n            \n            if length[l_l]:\n                length[l_l]-=1\n            if length[r_l]:\n                length[r_l]-=1\n            length[new_l]+=1\n            \n            if length[m]>0:\n                ans=i+1\n                \n        return ans\n            \n            \n            \n            \n            \n            \n                \n            \n            \n            \n            \n                    \n        \n        \n        \n            \n            \n            \n            \n            \n            \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dsu = DSU()\n        used = set()\n        candidates = set()\n        ans = -1\n        for index, i in enumerate(arr):\n            if i + 1 in used:\n                dsu.union(i, i + 1)\n            if i - 1 in used:\n                dsu.union(i, i - 1)\n            used.add(i)\n                        \n            if dsu.get_count(i) == m:\n                candidates.add(i)\n            \n            cur_candidates = set()\n            for c in candidates:\n                if dsu.get_count(c) == m:\n                    cur_candidates.add(c)\n                    ans = max(ans, index + 1)\n            candidates = cur_candidates\n            \n        return ans\n        \nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = defaultdict(lambda x: 1)\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = self.father[_b]\n            self.count[_b] += self.count[_a]\n    \n    def get_count(self, a):\n        return self.count[self.find(a)]", "class Solution:\n    def __init__(self):\n        self.ans = -1\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n            n = len(arr)\n            if n == m: return n\n            \n            sz = [1]*n\n            group = [i for i in range(n)]\n            \n            def find(i):\n                root = i\n                while group[root] != root:\n                    root = group[root]\n                while i != root:\n                    nxt = group[i]\n                    group[i] = root\n                    i = nxt\n                return root\n            \n            def union(i, j):\n                root1 = find(i)\n                root2 = find(j)\n                if(sz[root1] > sz[root2]):\n                    sz[root1] += sz[root2]\n                    group[root2] = root1\n                else:\n                    sz[root2] += sz[root1]\n                    group[root1] = root2\n            \n            nums = [0]*n\n            cnt = 0\n            for i in range(n):\n                nums[arr[i]-1] = 1\n                if arr[i]-2 >= 0 and nums[arr[i]-2] == 1:\n                    if sz[find(arr[i]-2)] == m:\n                        cnt -= 1\n                    union(arr[i]-1, arr[i]-2)\n                if arr[i] < n and nums[arr[i]] == 1:\n                    if sz[find(arr[i])] == m:\n                        cnt -= 1\n                    union(arr[i]-1, arr[i])\n                if sz[find(arr[i]-1)] == m:\n                    cnt += 1\n                if cnt:\n                    self.ans = i+1\n            return self.ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        class UF:\n            def __init__(self):\n                self.size = 1\n                self.parent = self\n\n            def find(self):\n                if self.parent is not self:\n                    self.parent = self.parent.find()\n                return self.parent\n\n            def union(self, other):\n                p1, p2 = self.find(), other.find()\n                if p1 is p2:\n                    return\n\n                if p2.size < p1.size:\n                    p1, p2 = p2, p1\n\n                p2.size += p1.size\n                p1.parent = p2\n\n        groups = {}\n        sizes = collections.Counter()\n\n        res = -1\n        for i, n in enumerate(arr):\n            n -= 1\n            groups[n] = g = UF()\n            sizes[1] += 1\n\n            if n - 1 in groups:\n                sizes[groups[n-1].find().size] -= 1\n                sizes[g.find().size] -= 1\n                groups[n - 1].union(g)\n                sizes[g.find().size] += 1\n\n            if n + 1 in groups:\n                sizes[groups[n+1].find().size] -= 1\n                sizes[g.find().size] -= 1\n                groups[n + 1].union(g)\n                sizes[g.find().size] += 1\n\n            if sizes[m] > 0:\n                res = i + 1\n\n        return res", "# class Solution(object):\n#     def findLatestStep(self, arr, m):\n#         \\\"\\\"\\\"\n#         :type arr: List[int]\n#         :type m: int\n#         :rtype: int\n#         \\\"\\\"\\\"\n#         self.rank = collections.defaultdict(int)\n#         self.p = collections.defaultdict(int)\n        \n#         def find(i):\n#             if i not in self.p:\n#                 self.p[i] = i\n#                 self.rank[i] = 1\n#                 return i\n#             p = self.p[i]\n#             while p != self.p[p]:\n#                 p = self.p[p]\n#             self.p[i] = p\n#             return p\n        \n#         def union(i, j):\n#             ip, jp = find(i), find(j)\n#             if ip == jp:\n#                 return False\n#             ir, jr = self.rank[ip], self.rank[jp]\n#             if ir > jr:\n#                 self.p[jp] = ip\n#                 self.rank[ip] += self.rank[jp]\n#                 self.rank.pop(jp)\n#             else:\n#                 self.p[ip] = jp\n#                 self.rank[jp] += self.rank[ip]\n#             return True\n        \n        \n#         status = [0] * len(arr)\n#         res = -1\n#         l = len(arr)\n#         for step, i in enumerate(arr):\n#             i -= 1\n#             status[i] = 1\n#             self.p[i] = i\n#             self.rank[i] = 1\n#             for j in [i-1, i+1]:\n#                 if 0<= j < l:\n#                     if self.rank[find(j)] == m:\n#                         res = step\n#                         print(self.p)\n#                         print(self.rank)\n#                     if status[j] == 1:\n#                         union(i, j)\n                        \n#         for i in range(l):\n#             if self.rank[find(i)] == m:\n#                 return l\n            \n#         return res\n\nclass UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        dsu = DSU()\n        used = set()\n        ans = -1\n        for index, i in enumerate(arr):\n            if i + 1 in used and dsu.get_count(i + 1) == m or i - 1 in used and dsu.get_count(i - 1) == m:\n                ans = index\n            if i + 1 in used:\n                dsu.union(i, i + 1)\n            if i - 1 in used:\n                dsu.union(i, i - 1)\n            used.add(i)\n            \n        return ans\n        \nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = {}\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = self.father[_b]\n            self.count[_b] += self.count[_a]\n    \n    def get_count(self, a):\n        return self.count[self.find(a)]", "class UnionFind():\n    def __init__(self, n, m):\n        self.parents={}\n        self.size={}\n        self.rev_map={}\n        self.m=m\n        for i in range(n):\n            self.parents[i]=i\n            self.size[i]=0\n            self.rev_map[i]=0\n        self.rev_map[i+1]=0\n        self.rev_map[0]=0\n    def union(self, n1, n2):\n        \n        p1=self.find_parent(n1)\n        p2=self.find_parent(n2)\n        self.parents[p1]=p2\n        self.rev_map[self.size[p1]]-=1\n        self.rev_map[self.size[p2]]-=1\n        self.size[p2]=self.size[p1]+self.size[p2]\n        self.rev_map[self.size[p2]]+=1\n        \n        \n    def find_parent(self, n1):\n        if self.parents[n1]==n1:\n            return n1\n        self.parents[n1]=self.find_parent(self.parents[n1])\n        return self.parents[n1]\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        u=UnionFind(len(arr),m)\n        d=[0]*max(arr)\n        best=-1\n        # arr=[i-1 for i in arr]\n        for i in range(len(arr)):\n            \n            d[arr[i]-1]=1\n            u.size[u.find_parent(arr[i]-1)]=1\n\n            u.rev_map[u.size[u.find_parent(arr[i]-1)]]+=1\n            # u.rev_map[u.size[u.find_parent(arr[i])]]+=1\n            if arr[i]-2>=0 and d[arr[i]-2]==1:\n                u.union(arr[i]-2,arr[i]-1)\n            if arr[i]<len(arr) and d[arr[i]]==1:\n                u.union(arr[i]-1,arr[i])\n            if u.rev_map[m]>=1:\n                best=i\n            # print(u.rev_map)\n        if best==-1:\n              return -1\n        return best+1", "import bisect\nimport math\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # print(\\\"-----\\\"*5)\n        arr = [i-1 for i in arr]\n        splitted = [(0,len(arr)-1),] # indices \\\"1\\\"s started with\n        step = len(arr)\n        if len(arr) == m: return step\n        for n in reversed(arr):\n            step -= 1\n            i = bisect.bisect_right(splitted, (n,math.inf))\n            range_ = splitted[i-1]\n            left = (range_[0], n-1)\n            right = (n+1, range_[1])\n            if left[1]-left[0]+1 == m or right[1]-right[0]+1 == m:\n                return step\n            replace = []\n            if left[1] >= left[0]:\n                replace.append(left)\n            if right[1] >= right[0]:\n                replace.append(right)\n            \n            splitted[i-1:i] = replace\n            # print(splitted)\n        return -1", "import sys\ninput = sys.stdin.readline\n\nclass Unionfind:\n    def __init__(self, n):\n        self.par = [-1]*n\n        self.rank = [1]*n\n    \n    def root(self, x):\n        r = x\n        \n        while not self.par[r]<0:\n            r = self.par[r]\n        \n        t = x\n        \n        while t!=r:\n            tmp = t\n            t = self.par[t]\n            self.par[tmp] = r\n        \n        return r\n    \n    def unite(self, x, y):\n        rx = self.root(x)\n        ry = self.root(y)\n        \n        if rx==ry:\n            return\n        \n        if self.rank[rx]<=self.rank[ry]:\n            self.par[ry] += self.par[rx]\n            self.par[rx] = ry\n            \n            if self.rank[rx]==self.rank[ry]:\n                self.rank[ry] += 1\n        else:\n            self.par[rx] += self.par[ry]\n            self.par[ry] = rx\n    \n    def is_same(self, x, y):\n        return self.root(x)==self.root(y)\n    \n    def count(self, x):\n        return -self.par[self.root(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr = list(map(lambda x: x-1, arr))\n        n = len(arr)\n        now = [0]*n\n        ans = -1\n        uf = Unionfind(n)\n        cnt = [0]*(n+1)\n        \n        for i in range(n):\n            p = arr[i]\n            now[p] = 1\n            cnt[1] += 1\n            \n            if p-1>=0 and now[p-1]==1:\n                cnt[uf.count(p)] -= 1\n                cnt[uf.count(p-1)] -= 1\n                uf.unite(p-1, p)\n                cnt[uf.count(p)] += 1\n            \n            if p+1<n and now[p+1]==1:\n                cnt[uf.count(p)] -= 1\n                cnt[uf.count(p+1)] -= 1\n                uf.unite(p, p+1)\n                cnt[uf.count(p)] += 1\n            \n            if cnt[m]>0:\n                ans = i+1\n        \n        return ans", "\nclass Solution:\n  def findLatestStep(self, arr: List[int], m: int) -> int:\n    if len(arr) == m:\n      return m\n\n    result = -1\n    length = []\n    for i in range(len(arr) + 2):\n      length.append(0)\n\n    for index, value in enumerate(arr):\n      left = length[value - 1]\n      right = length[value + 1]\n      if left == m or right == m:\n        result = index\n\n      length[value-left] = left + right + 1\n      length[value + right] = left + right + 1\n      pass\n\n    return result", "class DSU:\n    def __init__(self, count):\n        self.parent = [i for i in range(count)]\n        self.size = [1 for _ in range(count)]\n    \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        while x != root:\n            next_node = self.parent[x]\n            self.parent[x] = root\n            x = next_node\n        return root\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n        if r1 == r2:\n            return\n        if self.size[r1] < self.size[r2]:\n            self.size[r2] += self.size[r1]\n            self.parent[r1] = r2\n        else:\n            self.size[r1] += self.size[r2]\n            self.parent[r2] = r1\n    \n    def get_size(self, x):\n        return self.size[self.find(x)]\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        components = [0 for _ in range(len(arr))]\n        size_count = collections.Counter()\n        dsu = DSU(len(arr))\n        ans = -1\n        for i, num in enumerate(arr, 1):\n            num -= 1\n            components[num] = 1\n            for adj in (num - 1, num + 1):\n                if 0 <= adj < len(arr) and components[adj]:\n                    size_count[dsu.get_size(adj)] -= 1\n                    dsu.union(num, adj)\n            size_count[dsu.get_size(num)] += 1\n            if size_count[m] > 0:\n                ans = i # step\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        memo = [[1, len(arr)]]\n        if m == len(arr):\n            return len(arr)\n        for j in range(len(arr) - 1,- 1, -1):\n            i = arr[j]\n            left,right = 0, len(memo) - 1\n            while left <= right:\n                mid = (left + right) // 2\n                if memo[mid][0] <= i:\n                    left = mid + 1\n                else:\n                    right = mid - 1\n            a,b = memo[right][0], memo[right][1]\n            if i - a == m or a + b - i - 1 == m:\n                return j\n            flag = True\n            if i - a > 0:\n                memo[right][1] = i -a\n            else:\n                memo.pop(right)\n                flag = False\n            if a + b - i - 1 > 0:\n                memo[right + flag: right + flag] = [[i + 1, a + b - i - 1]]\n            \n        return -1\n", "class DSU:\n    \n    def __init__(self, N):\n        self.parents = list(range(N))\n        self.size = [1] * N\n    \n    def find(self, x):\n        if x != self.parents[x]:\n            self.parents[x] = self.find(self.parents[x])\n        \n        return self.parents[x]\n    \n    def union(self, x, y):\n        xr = self.find(x)\n        yr = self.find(y)\n        \n        if xr != yr:\n            if self.size[xr] < self.size[yr]:\n                xr, yr = yr, xr\n            self.parents[yr] = xr\n            self.size[xr] += self.size[yr]\n            self.size[yr] = self.size[xr]\n    \n    def sz(self, x):\n        return self.size[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count = Counter()\n        N = len(arr)\n        S = [0] * N\n        dsu = DSU(N)\n        \n        ans = -1\n        for i, a in enumerate(arr, 1):\n            a -= 1\n            S[a] = 1\n            \n            for b in (a - 1, a + 1):\n                if 0 <= b < N and S[b]:\n                    count[dsu.sz(b)] -= 1\n                    dsu.union(a, b)\n            \n            count[dsu.sz(a)] += 1\n            if count[m] > 0:\n                ans = i\n        \n        return ans\n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n\n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n\n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        '''\n        length_dict = {}\n        \n        length_edge = [0]*len(arr)\n        \n        result = -1\n        \n        for i in range(len(arr)):\n            index = arr[i] - 1\n            \n            left_length = 0\n            right_length = 0\n            if index>0:\n                left_length = length_edge[index - 1]\n            if index<len(arr)-1:\n                right_length = length_edge[index + 1]\n            length_edge[index+right_length] = 1 + left_length + right_length\n            length_edge[index-left_length] = 1 + left_length + right_length\n            \n            if left_length in length_dict:\n                length_dict[left_length] -= 1\n            if right_length in length_dict:\n                length_dict[right_length] -= 1\n            if 1 + left_length + right_length not in length_dict:\n                length_dict[1 + left_length + right_length] = 0\n            length_dict[1 + left_length + right_length] += 1\n            \n            if m in length_dict and length_dict[m]>0:\n                result = i + 1\n        return result\n        '''\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        groups = {}\n        groups[0] = len(arr)\n        \n        result = -1\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            \n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    '''\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    '''\n                    groups[uf.ranks[uf.find(j)]] -= 1\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n            \n            '''\n            if uf.ranks[uf.find(i)] == m:\n                ans = step + 1\n            '''\n            group = uf.ranks[uf.find(i)]\n            if group not in groups:\n                groups[group] = 0\n            groups[group] += 1\n            if m in groups and groups[m]>0:\n                result = step + 1\n        '''\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n        return ans\n        '''\n        \n        return result\n            \n", "class DSU:\n    \n    def __init__(self, count):\n        self.parent = [i for i in range(count)]\n        self.size = [1 for _ in range(count)]\n    \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        while x != root:\n            next_node = self.parent[x]\n            self.parent[x] = root\n            x = next_node\n        return root\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n        if r1 == r2:\n            return\n        if self.size[r1] < self.size[r2]:\n            self.size[r2] += self.size[r1]\n            self.parent[r1] = r2\n        else:\n            self.size[r1] += self.size[r2]\n            self.parent[r2] = r1\n            \n    def get_size(self, x):\n        return self.size[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        components = [0 for _ in range(len(arr))]\n        ans = -1\n        dsu = DSU(len(arr))\n        size_count = collections.Counter()\n        for i, n in enumerate(arr, 1):\n            n -= 1\n            components[n] = 1\n            for adj in (n - 1, n + 1):\n                if 0 <= adj < len(arr) and components[adj]:\n                    size_count[dsu.get_size(adj)] -= 1\n                    dsu.union(n, adj)\n            size_count[dsu.get_size(n)] += 1\n            if size_count[m] > 0:\n                ans = i\n        return ans\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        d = {}\n        step = 1\n        ans = -1\n        s = set()\n        \n        for a in arr:\n            \n            if a not in d:\n                \n                left = d.get(a-1, [])\n                right = d.get(a+1, [])\n                \n                \n                s = 1\n                \n                if left:\n                    s += left[0]\n                    if left[0] == m:\n                        ans = max(ans, step-1)\n                \n                if right:\n                    s += right[0]\n                    if right[0] == m:\n                        ans = max(ans, step-1)\n                \n                # print(s, step, left, right)\n                \n                if s == m:\n                    ans = max(ans, step)\n                    \n                d[a] = [s,step]\n                \n                if left:\n                    d[a- left [0]] = [s,step]\n                \n                if right:\n                    d[a+ right[0]] = [s,step]\n                \n                # print(step, d)\n            step += 1\n        \n        \n\n        \n        \n        return ans", "class Solution:\n    def findLatestStep(self, A: List[int], T: int, last = -1) -> int:\n        seen, ok = set(), set()\n        A = [i - 1 for i in A]\n        N = len(A)\n        P = [i for i in range(N)]\n        L = [1] * N\n        def find(x):\n            if x != P[x]:\n                P[x] = find(P[x])\n            return P[x]\n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            P[b] = a\n            L[a] += L[b]\n            return L[a]\n        step = 1\n        for i in A:\n            seen.add(i)\n            if 0 < i and find(P[i - 1]) in ok: ok.remove(find(P[i - 1]))\n            if i + 1 < N and find(P[i + 1]) in ok: ok.remove(find(P[i + 1]))\n            if i - 1 in seen: L[i] = union(i, i - 1)\n            if i + 1 in seen: L[i] = union(i, i + 1)\n            if L[i] == T:\n                ok.add(i)\n            if len(ok):\n                last = step\n            step += 1\n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m==n: return m\n        length = [0 for _ in range(n+2)]\n        res = -1\n        \n        for step, pos in enumerate(arr):\n            left, right = length[pos-1], length[pos+1]\n            if left==m or right==m:\n                res = step\n            length[pos-left]=length[pos+right] = left+right+1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parent = {}\n        size = {}\n        ds_sizes = Counter()\n\n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n\n        def decrement_size(x):\n            ds_sizes[x] -= 1\n            if ds_sizes[x] == 0:\n                del ds_sizes[x]\n\n        def union(x, y):\n            px, py = find(x), find(y)\n\n            if px is py:\n                return\n\n            if size[px] < size[py]:\n                px, py = py, px\n\n            parent[py] = px\n            decrement_size(size[px])\n            decrement_size(size[py])\n            size[px] += size[py]\n            ds_sizes[size[px]] += 1\n\n        def make_set(x):\n            if x in parent:\n                return\n            parent[x] = x\n            size[x] = 1\n            ds_sizes[1] += 1\n\n        steps = 0\n        last_step = -1\n\n        for n in arr:\n            make_set(n)\n\n            for neighbor in (n + 1, n - 1):\n                if neighbor in parent:\n                    union(n, neighbor)\n\n            steps += 1\n            if m in ds_sizes:\n                last_step = steps\n\n        return last_step", "import copy\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        opts = [i for i in range(n+1)] # 0...n+1\n        if m > n:\n            return -1\n        if m == n:\n            return n\n        left,right = [i for i in range(n+2)],[i for i in range(n+2)]\n        def find_l(node):\n            if left[node]!=node:\n                left[node] = find_l(left[node])\n            return left[node]\n        def find_r(node):\n            if right[node]!=node:\n                right[node] = find_r(right[node])\n            return right[node]\n        ret = -1\n        cnt = collections.defaultdict(int)\n        for i,ind in enumerate(arr):\n            left[ind] = l_par = find_l(ind-1)\n            right[ind] = r_par = find_r(ind+1)\n            if ind - l_par == 1 and r_par - ind == 1:\n                # print('1')\n                cnt[1] += 1\n            elif ind - l_par != 1 and r_par - ind != 1:\n                # print('2')\n                l_dis = ind - l_par - 1\n                r_dis = r_par - ind - 1\n                cnt[l_dis] -= 1\n                if cnt[l_dis] == 0:\n                    del cnt[l_dis]\n                cnt[r_dis] -= 1\n                if cnt[r_dis] == 0:\n                    del cnt[r_dis]\n                # print(l_dis,r_dis,cnt)\n                cnt[l_dis+r_dis+1] += 1\n            else:\n                # print('3')\n                dis = 0\n                if ind - l_par == 1:\n                    dis = r_par - ind\n                elif r_par - ind == 1:\n                    dis = ind - l_par\n                cnt[dis-1] -= 1\n                if cnt[dis-1] == 0:\n                    del cnt[dis-1]\n                cnt[dis] += 1\n            if m in cnt:\n                ret = i+1\n            # print('aaaaaaaaaa',left,right,cnt)\n        \n        return ret\n                    \n                \n            \n", "class Subset:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0] * n\n    \n    def find(self,i):\n        if self.parent[i] != i:\n            self.parent[i] = self.find(self.parent[i])\n        return self.parent[i]\n\n    def union(self,u,v):\n        if self.rank[u] > self.rank[v]:\n            self.parent[v] = self.find(u)\n        if self.rank[v] > self.rank[u]:\n            self.parent[u] = self.find(v)\n        if self.rank[u] == self.rank[v]:\n            self.parent[v] = self.find(u)\n            self.rank[u] += self.rank[v]\n            \nclass Solution:       \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        subset = Subset(n)\n        ls = [0] * n\n        size = [1] * n\n        res = -1\n        cnt = 0\n        for i in range(n):\n            idx = arr[i] - 1\n            ls[idx] = 1\n            sizeMiddle = 1\n            if idx > 0:\n                if ls[idx-1] == 1:\n                    p = subset.find(idx-1)\n                    sizeLeft = size[p]\n                    subset.union(min(idx,p),max(idx,p))\n                    if sizeLeft == m:\n                        cnt -= 1\n                    sizeMiddle += sizeLeft\n            if idx < n-1:\n                if ls[idx+1] == 1:\n                    p2 = subset.find(idx+1)\n                    sizeRight = size[p2]\n                    subset.union(min(idx,p2),max(idx,p2))\n                    if sizeRight == m:\n                        cnt -= 1\n                    sizeMiddle += sizeRight\n            finalP = subset.find(idx)\n            size[finalP] = sizeMiddle\n            if sizeMiddle == m:\n                cnt += 1\n            if cnt > 0:\n                res = max(res,i+1)\n        return res", "class UnionFind:\n    def __init__(self):\n        self.sets = {}\n        self.size = {}\n        self.sizes = collections.defaultdict(int)\n    def make_set(self, s):\n        self.sets[s] = s\n        self.size[s] = 1\n        self.sizes[1] += 1\n    def find(self, s):\n        if self.sets[s] != s:\n            self.sets[s] = self.find(self.sets[s])\n        return self.sets[s]\n    def union(self, s1, s2):\n        a, b = self.find(s1), self.find(s2)\n        if a == b:\n            return\n        self.sizes[self.size[a]] -= 1\n        self.sizes[self.size[b]] -= 1\n        if self.sizes[self.size[a]] == 0:\n            self.sizes.pop(self.size[a], None)\n        if self.sizes[self.size[b]] == 0:\n            self.sizes.pop(self.size[b], None)\n        self.sets[a] = b\n        self.size[b] += self.size[a]\n        self.sizes[self.size[b]] += 1\n    def get_size(self, m):\n        return m in self.sizes\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        seen = set()\n        uf = UnionFind()\n        res = -1\n        for i, v in enumerate(arr, 1):\n            uf.make_set(v)\n            if v + 1 in seen:\n                uf.union(v, v + 1)\n            if v - 1 in seen:\n                uf.union(v, v - 1)\n            seen.add(v)\n            if uf.get_size(m):\n                res = i\n        return res\n            \n            \n", "class UnionFind:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n\n    def find(self, src):\n        if self.parents[src] == src:\n            return src\n        self.parents[src] = self.find(self.parents[src])\n        return self.parents[src]\n    \n    def union(self, src, dest):\n        rootSrc, rootDest = self.find(src), self.find(dest)\n        if rootDest == rootSrc:\n            return False\n        \n        if self.ranks[rootSrc] > self.ranks[rootDest]:\n            self.parents[rootDest] = rootSrc\n            self.ranks[rootSrc] += self.ranks[rootDest]\n        else:\n            self.parents[rootSrc] = rootDest\n            self.ranks[rootDest] += self.ranks[rootSrc]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, result = len(arr), -1\n        uf = UnionFind(n)\n\n        for step, idx in enumerate(arr):\n            idx -= 1\n            uf.ranks[idx] = 1\n            for j in (idx - 1, idx + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        result = step\n                    if uf.ranks[j]:\n                        uf.union(idx, j)\n\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def root(x):\n            if x == group[x]:\n                return x\n            group[x] = root(group[x])\n            return group[x]\n            \n        def same(x, y):\n            return root(x) == root(y)\n            \n        def unite(x, y):\n            nonlocal cnt\n            x = root(x)\n            y = root(y)\n            cnt -= (sz[x] == m)\n            #print(x, y, sz[x], sz[y])\n            if sz[x] < sz[y]:\n                x, y = y, x\n            group[y] = x\n            sz[x] += sz[y]\n            \n            \n            \n        group = [-1 for i in range(len(arr) + 1)]\n        sz = [0 for i in range(len(arr) + 1)]\n        ones = [False for i in range(len(arr) + 1)]\n        cnt = 0\n        latest = -1\n        for i in range(len(arr)):\n            index = arr[i]\n            ones[index] = True\n            sz[index] = 1\n            group[index] = arr[i]\n            if index - 1 >= 1 and ones[index-1]:\n                unite(index - 1, index)\n            if index + 1 <= len(arr) and ones[index+1]:\n                unite(index + 1, index)\n            if sz[root(index)] == m:\n                cnt += 1\n            if cnt > 0:\n                latest = i + 1\n            #print(group, sz, ones, cnt)\n        return latest", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        F = [0] * n\n        d = collections.defaultdict(int)\n        \n        def find(x):\n            if F[x] < 0:\n                return x\n            else:\n                F[x] = find(F[x])\n                return F[x]\n        \n        t = [0] * n\n        ans = -1\n        \n        for i in range(n):\n            ind = arr[i] - 1\n            d[1] += 1\n            t[ind] = 1\n            F[ind] = -1\n            for newind in [ind-1, ind+1]:\n                if newind < 0 or newind >= n or t[newind] == 0:\n                    continue\n                new = find(newind)\n                d[-F[ind]] -= 1\n                d[-F[new]] -= 1\n                d[-F[ind]-F[new]] += 1\n                F[ind] += F[new]\n                F[new] = ind\n\n            if d[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def dfs(start, end, cur):\n            if end - start + 1 < m: return -2\n            if end - start + 1 == m: return cur\n            while arr[cur] < start or arr[cur] > end:\n                cur -= 1\n            return max(dfs(start, arr[cur] - 1, cur - 1), dfs(arr[cur] + 1, end, cur - 1))\n        return dfs(1, len(arr), len(arr) - 1) + 1", "\n\nclass Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        \n        n = len(a)\n        \n        c = Counter()\n        par = {}\n        sz = {}\n        \n        def add(u):\n            \n            c[1] += 1\n            sz[u] = 1\n            par[u] = u\n        \n        def merge(u, v):\n            \n            ru = find(u)\n            rv = find(v)\n            \n            if ru != rv:\n                \n                c[sz[ru]] -= 1\n                c[sz[rv]] -= 1\n                c[sz[ru] + sz[rv]] += 1\n                \n                par[rv] = ru\n                sz[ru] += sz[rv]\n                \n        def find(u):\n            \n            if par[u] != u:\n                par[u] = find(par[u])\n            \n            return par[u]\n        \n        ret = -1\n        \n        for i,x in zip(list(range(1, n+1)), a):\n            \n            add(x)\n            \n            if x-1 in par:\n                merge(x-1, x)\n            \n            if x+1 in par:\n                merge(x+1, x)\n            \n            #print(c[m])\n            \n            if c[m]:\n                #print(\\\"hi\\\")\n                ret = i\n        \n        return ret\n", "# union find problem\nclass UnionNode:\n    def __init__(self,value,parent=None):\n        self.value = value\n        self.parent = parent\n        self.size = 1\n        \nclass UnionFind:\n    def __init__(self):\n        return\n    \n    def findGroup(self,curNode):\n        while(curNode!=curNode.parent):\n            curNode = curNode.parent\n        return curNode\n    \n    def merge(self,node1,node2):\n        root1,root2 = self.findGroup(node1),self.findGroup(node2)\n        if(root1==root2):\n            return -1\n        if(root1.size>root2.size):\n            root2.parent = root1\n            root1.size += root2.size\n            return root1.size\n        else:\n            root1.parent = root2\n            root2.size += root1.size\n            return root2.size\n            \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        numOfm = 0\n        res = -1\n        string = [UnionNode(0) for _ in range(len(arr))]\n        theUnionFind = UnionFind()\n        for i in range(len(arr)):\n            step = i+1\n            loc = arr[i]-1\n            thisUnionNode = string[loc]\n            thisUnionNode.value = 1\n            thisUnionNode.parent = thisUnionNode\n            thisSize = 1\n            if(loc-1>=0 and string[loc-1].value==1):\n                # merge with left nei\n                \n                # if left nei has size m, numOfm -= 1\n                newSize = theUnionFind.merge(string[loc-1],string[loc])\n                if(newSize-thisSize==m):\n                    numOfm -= 1\n                thisSize = newSize\n            if(loc+1<len(string) and string[loc+1].value==1):\n                # merge with right nei\n                \n                # if right nei has size m, numOfm -= 1\n                newSize = theUnionFind.merge(string[loc+1],string[loc])\n                if(newSize-thisSize==m):\n                    numOfm -= 1\n                thisSize = newSize\n            #print(thisSize)\n            if(thisSize==m):\n                numOfm += 1\n            if(numOfm > 0):\n                res = step\n        \n        return res\n        \n        \n        \n        \n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        n = len(A)\n        arr = [0]*n\n        parent = [i for i in range(n)]\n        rank = [1]*n\n        groupSize = [0]*n\n        groupMap = set()\n        ans = -1\n        \n        def ugm(x):\n            nonlocal m\n            if groupSize[x] == m:\n                groupMap.add(x)\n            else:\n                if x in groupMap:\n                    groupMap.remove(x)\n        \n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def join(x,y):\n            px = find(x)\n            py = find(y)\n            if px != py:\n                if px < py:\n                    parent[py] = px\n                    groupSize[px]+=groupSize[py]\n                    groupSize[py]=0\n                else:\n                    parent[px] = py\n                    groupSize[py]+=groupSize[px]\n                    groupSize[px]=0\n                ugm(px)\n                ugm(py)\n            \n        \n        for ind, num in enumerate(A):\n            num-=1\n            arr[num]=1\n            groupSize[num]=1\n            ugm(num)\n            # print(arr)\n            if num-1 >= 0 and arr[num-1]:\n                join(num-1,num)\n            \n            if num+1 < n and arr[num+1]:\n                join(num,num+1)\n            # print(groupMap)\n            if len(groupMap) > 0:\n                ans = ind+1\n        return ans\n            \n            \n", "class UF:\n    def __init__(self, N):\n        self.N = N\n        self.size = [0]*N\n        self.stat = [False]*N\n        self.id = list(range(N))\n        self.sizes = collections.Counter()\n        \n    def find(self, x):\n        if self.id[x] != x:\n            self.id[x] = self.find(self.id[x])\n        return self.id[x]\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        \n        if px != py:\n            self.size[px] += self.size[py]\n            self.id[py] = px\n            self.sizes[self.size[py]] -= 1\n\n    def set(self, x):\n        self.stat[x] = True\n        self.size[x] += 1\n        if x-1 >= 0 and self.stat[x-1]:\n            self.union(x, x-1)\n        if x+1 < self.N and self.stat[x+1]:\n            self.union(x, x+1)\n        self.sizes[self.size[x]] += 1\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UF(n)\n        ans = -1\n        for step, idx in enumerate(arr, 1):\n            uf.set(idx-1)\n            if uf.sizes[m] > 0:\n                ans = step\n\n        return ans", "class Group:\n    def __init__(self, x, y):\n        self.left = x\n        self.right = y\n        # self.update()\n        self.n = y - x + 1\n        \n#     def update(self):\n#         self.n = self.right - self.left + 1\n        \n#     def add_left(self, x):\n#         self.left = x\n#         self.update()\n        \n#     def add_right(self, y):\n#         self.right = y\n#         self.update()\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        groups = [None] * (1+len(arr))\n        group_size = collections.defaultdict(int)\n        visited = set()\n        res = -1\n        for step, x in enumerate(arr, 1):\n            visited.add(x)\n            left = right = x\n            lsize = rsize = 0\n            if x>1 and x-1 in visited:\n                left = groups[x-1].left\n                lsize = groups[x-1].n\n            if x<len(arr) and x+1 in visited:\n                right = groups[x+1].right\n                rsize = groups[x+1].n\n            g = Group(left, right)\n            groups[left] = g\n            groups[right] = g\n            group_size[lsize+rsize+1] += 1\n            if lsize != 0:\n                group_size[lsize] -= 1\n            if rsize != 0:\n                group_size[rsize] -= 1\n                \n            if group_size[m] > 0:\n                res = step\n        return res\n                \n        \n#         def find(parent, i):\n#             if parent[i] == -1:\n#                 return i \n#             if parent[i] != -1:\n#                 return find(parent, parent[i]) \n\n#         def union(parent, x, y): \n#             px = find(parent, x) \n#             py = find(parent, y) \n#             parent[px] = py\n            \n#         parent = [-1] * (1+len(arr))\n#         for x in arr:\n#             parent[x] = x\n#             if x > 1 and parent[x-1] != -1:\n#                 union(parent, x, y)\n#                 parent[x] = x\n            \n        \n", "class UF:\n    def __init__(self, n):\n        self.p = [-1 for _ in range(n+1)]\n        self.size = [0 for _ in range(n+1)]\n        \n    def find(self, x):\n        if self.p[x] == -1:\n            return -1\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, a, b):\n        pa = self.find(a)\n        pb = self.find(b)\n        self.p[pa] = pb\n        self.size[pb] += self.size[pa]\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UF(len(arr))\n        ans = -1\n\n        for i, x in enumerate(arr):\n            uf.p[x] = x\n            uf.size[x] = 1\n\n            if x > 0 and uf.find(x - 1) != -1:\n                if uf.size[uf.find(x-1)] == m:\n                    ans = i\n                uf.union(x, x-1)\n\n            if x < n and uf.find(x + 1) != -1:\n                if uf.size[uf.find(x+1)] == m:\n                    ans = i\n                uf.union(x, x+1)\n            if uf.size[uf.find(x)] == m:\n                ans = i+1\n\n        return ans\n\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n: return n \n        arr.append(n+1)\n        start = {}\n        finish = {}\n        last = -1\n        for level,i in enumerate(arr):\n            if i-1 not in finish: finish[i-1] = i \n            if i+1 not in start: start[i+1] = i\n\n            s, f = finish[i-1], start[i+1]\n            start[s] = f \n            finish[f] = s\n            \n            for os, of in [[i+1, start[i+1]], [finish[i-1], i-1]]:\n                if of-os+1 == m: last = level\n                \n            del start[i+1]\n            del finish[i-1]\n            \n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ranges = [None for _ in range(len(arr))]\n        lefts = set([])\n        \n        best = -1\n        for rnd, flipped in enumerate(arr):\n            i = flipped - 1\n            left = right = i\n\n            if i > 0 and ranges[i-1] is not None:\n                left = ranges[i-1][0]\n                if left in lefts:\n                    lefts.remove(left)\n            if i < len(ranges)-1 and ranges[i+1] is not None:\n                right = ranges[i+1][1]\n                if ranges[i+1][0] in lefts:\n                    lefts.remove(ranges[i+1][0])\n\n            ranges[i] = [left, right]\n            ranges[left] = [left, right]\n            ranges[right] = [left, right]\n            if right - left + 1 == m:\n                lefts.add(left)\n            if len(lefts) > 0:\n                best = rnd + 1\n        return best", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length, count = [0 for i in range(len(arr) + 2)], [0 for i in range(len(arr) + 2)]\n        ans = -1\n        for i, num in enumerate(arr):\n            left, right = length[num - 1], length[num + 1]\n            length[num - left], length[num + right] = left + right + 1, left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[left + right + 1] += 1\n            if count[m] > 0:\n                ans = i + 1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(n + 1, m)\n        ans = -1\n        visited = set()\n        for i in range(n):\n            a = arr[i]\n            uf.add(a)\n            if a - 1 in visited:\n                uf.union(a, a - 1)\n            if a + 1 in visited:\n                uf.union(a, a + 1)\n            if uf.cnt > 0:\n                ans = i + 1\n            visited.add(a)\n        return ans\n        \n        \nclass UnionFind:\n    def __init__(self, n, m):\n        self.id = [-1 for _ in range(n)]\n        self.size = [0 for _ in range(n)]\n        self.cnt = 0\n        self.m = m\n        \n    def add(self, i):\n        self.id[i] = i\n        self.size[i] = 1\n        if self.get_size(i) == self.m:\n            self.cnt += 1\n        \n    def find(self, i):\n        root = i\n        while root != self.id[root]:\n            root = self.id[root]\n        while root != i:\n            j = self.id[i]\n            self.id[i] = root\n            i = j\n        return root\n    \n    def union(self, i, j):\n        root_i = self.find(i)\n        root_j = self.find(j)\n        if root_i == root_j:\n            return\n        if self.get_size(i) == self.m:\n            self.cnt -= 1\n        if self.get_size(j) == self.m:\n            self.cnt -= 1\n        if self.size[root_i] < self.size[root_j]:\n            self.id[root_i] = root_j\n            self.size[root_j] += self.size[root_i]\n        else:\n            self.id[root_j] = root_i\n            self.size[root_i] += self.size[root_j]\n        if self.get_size(root_i) == self.m:\n            self.cnt += 1\n    \n    def get_size(self, i):\n        return self.size[self.find(i)]", "class DSU:\n    def __init__(self, size):\n        self.parent = [i for i in range(size)]\n        self.size = [1] * size\n    def find(self, value):\n        if value == self.parent[value]:\n            return value\n        self.parent[value] = self.find(self.parent[value])\n        return self.parent[value]\n    def merge(self, value1, value2):\n        p1, p2 = self.parent[value1], self.parent[value2]\n        if p1 == p2:\n            return\n        self.parent[p1] = p2\n        self.size[p2] += self.size[p1]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        c = Counter()\n        d = DSU(n + 2)\n        vis = [0] * (n + 2)\n        answer = -1\n        for i in range(n):\n            c[1] += 1\n            vis[arr[i]] = 1\n            if vis[arr[i]-1] and d.find(arr[i]) != d.find(arr[i]-1):\n                c[d.size[d.find(arr[i])]] -= 1\n                c[d.size[d.find(arr[i]-1)]] -= 1\n                d.merge(arr[i], arr[i]-1)\n                c[d.size[d.find(arr[i])]] += 1\n            if vis[arr[i]+1] and d.find(arr[i]) != d.find(arr[i]+1):\n                c[d.size[d.find(arr[i])]] -= 1\n                c[d.size[d.find(arr[i]+1)]] -= 1\n                d.merge(arr[i], arr[i]+1)\n                c[d.size[d.find(arr[i])]] += 1\n            if c[m] > 0:\n                answer = i + 1\n        return answer\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        from collections import defaultdict\n        n = len(arr)\n        parent = [i for i in range(0, n + 1)]\n        group_count = defaultdict(int)\n        l = [0] * n\n        dd = defaultdict(int)\n        def union(left, right):\n            left_p = find(left)\n            right_p = find(right)\n            if left_p != right_p:\n                parent[right_p] = left_p\n                dd[group_count[right_p - 1]] -= 1\n                dd[group_count[left_p - 1]] -= 1\n                group_count[left_p - 1] += group_count[right_p - 1]\n                group_count[right_p - 1] = 0\n                dd[group_count[left_p - 1]] += 1\n            # print(left, right, group_count)\n            \n        def find(i):\n            p = parent[i]\n            if parent[p] != p:\n                pp = find(p)\n                parent[i] = pp\n            return parent[i]\n        \n        last = -1\n        for idx, num in enumerate(arr):\n            l[num - 1] = 1\n            group_count[num - 1] = 1\n            dd[1] += 1\n            if num > 1 and l[num - 2] == 1:\n                union(num - 1, num)\n            if num != n and l[num] == 1:\n                union(num, num + 1)\n                \n            # print(group_count)\n                \n            if m in dd and dd[m] > 0:\n                last = idx + 1\n            # print(idx, num, l, parent)\n            # print(q)\n        return last\n", "class UnionFind:\n    def __init__(self, n):\n        self.parent = {}\n        self.size = [0] * (n + 1)\n        self.groups = collections.defaultdict(int)\n        for i in range(1, n + 1):\n            self.parent[i] = i\n            \n    def find(self, cur):\n        if self.parent[cur] == cur:\n            return cur\n        self.parent[cur] = self.find(self.parent[cur])\n        return self.parent[cur]\n    \n    def union(self, a, b):\n        root_a = self.find(a)\n        root_b = self.find(b)\n        \n        if root_a != root_b:\n            self.parent[root_b] = root_a\n            self.groups[self.size[root_a]] -= 1\n            self.groups[self.size[root_b]] -= 1\n            self.size[root_a] += self.size[root_b]\n            self.groups[self.size[root_a]] += 1\n            \n            \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        result = 0\n        UF = UnionFind(len(arr))\n        for i in range(len(arr)):\n            cur = arr[i]\n            UF.size[cur] = 1\n            UF.groups[1] += 1\n            if cur - 1 >= 1 and UF.size[cur - 1] > 0:\n                UF.union(cur, cur - 1)\n            if cur + 1 <= len(arr) and UF.size[cur + 1] > 0:\n                UF.union(cur, cur + 1)\n            if m in UF.groups and UF.groups[m] > 0:\n                    result = i + 1\n        return -1 if result == 0 else result\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        mystr =[0]*len(arr)\n        latest = -1\n        mydict = {}\n        count = 0\n        for i in range(len(arr)):\n            mystr[arr[i]-1] = 1\n            if arr[i]-2 not in mydict.keys() and arr[i] not in mydict.keys():\n                mydict[arr[i]-1] = [arr[i]-1,arr[i]-1, False]\n                if m == 1:\n                    count += 1\n                    mydict[arr[i]-1] = [arr[i]-1,arr[i]-1, True]\n                \n            elif arr[i]-2 in mydict.keys() and arr[i] not in mydict.keys():\n                head = mydict[arr[i]-2][0]\n                if mydict[arr[i]-2][2] == True:\n                    count -= 1\n                del mydict[arr[i]-2]\n                mydict[head] = [head,arr[i]-1, False]\n                mydict[arr[i]-1] = [head,arr[i]-1, False]        \n                if arr[i]-head == m:\n                    count += 1\n                    mydict[head] = [head,arr[i]-1, True]\n                    mydict[arr[i]-1] = [head,arr[i]-1, True]     \n\n            elif arr[i]-2 not in mydict.keys()  and arr[i] in mydict.keys():\n                tail = mydict[arr[i]][1]\n                if mydict[arr[i]][2] == True:\n                    count -= 1\n                del mydict[arr[i]]\n                mydict[tail] = [arr[i]-1,tail, False]\n                mydict[arr[i]-1] = [arr[i]-1,tail, False]             \n                if tail - (arr[i]-1) + 1 == m:\n                    count += 1\n                    mydict[tail] = [arr[i]-1,tail, True]\n                    mydict[arr[i]-1] = [arr[i]-1,tail, True]   \n                \n            else:\n                head = mydict[arr[i]-2][0]\n                tail = mydict[arr[i]][1]\n                if mydict[arr[i]-2][2] == True:\n                    count -= 1\n                if mydict[arr[i]][2] == True:\n                    count -= 1\n                del mydict[arr[i]-2]\n                del mydict[arr[i]]\n                \n                mydict[head] = [head,tail, False]\n                mydict[tail] = [head,tail, False]           \n                if tail - head + 1 == m:\n                    count += 1\n                    mydict[head] = [head,tail, True]\n                    mydict[tail] = [head,tail, True]   \n            if count > 0:\n                latest = i+1\n        return(latest)", "class Solution:\n    class UnionFind:\n        def __init__(self, n, m):\n            self.n = n\n            self.m = m\n            self.rank = [0] * n\n            self.parent = [n for i in range(n)]\n            self.counts = [0] * n\n            self.counts_num = [0] * 100005\n            \n        def set(self, idx):\n            self.rank[idx] = 1\n            self.parent[idx] = idx\n            self.counts[idx] = 1\n            self.counts_num[self.counts[idx]] += 1\n            if self.find(idx-1) != self.n:\n                self.unite(idx, idx-1)\n            if self.find(idx+1) != self.n:\n                self.unite(idx, idx+1)\n            \n        def find(self, idx):\n            if idx == self.n or self.parent[idx] == idx:\n                return idx\n            self.parent[idx] = self.find(self.parent[idx])\n            return self.parent[idx]\n            \n        def unite(self, idx, idx2):\n            if idx < 0 or idx2 < 0 or idx >= self.n or idx2 >= self.n:\n                return\n            root = self.find(idx)\n            root2 = self.find(idx2)\n            if root == root2:\n                return\n            self.counts_num[self.counts[root]] -= 1\n            self.counts_num[self.counts[root2]] -= 1\n            if self.rank[root] > self.rank[root2]:\n                self.parent[root2] = root\n                self.rank[root] += 1\n                self.counts[root] += self.counts[root2]\n                self.counts[root2] = 0\n            else:\n                self.parent[root] = root2\n                self.rank[root2] += 1\n                self.counts[root2] += self.counts[root]\n                self.counts[root] = 0\n            self.counts_num[self.counts[root]] += 1\n            self.counts_num[self.counts[root2]] += 1\n\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = self.UnionFind(n, m)\n        ans = -2\n        for i, num in enumerate(arr):\n            uf.set(num - 1)\n            if uf.counts_num[m] > 0:\n                ans = max(ans, i)\n            \n        return ans + 1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def union(x, y):\n            mp[right[y] - left[y] + 1] -= 1\n            mp[right[x] - left[x] + 1] -= 1\n            ll = left[x]\n            rr = right[y]\n            left[ll] = left[rr] = ll\n            right[rr] = right[ll] = rr\n            mp[rr - ll + 1] += 1\n            \n        res = -1\n        mp = Counter()\n        n = len(arr)\n        left = [-1] * (n + 1)\n        right = [-1] * (n + 1)\n        for i, a in enumerate(arr):\n            mp[1] += 1\n            left[a] = right[a] = a\n                        \n            if a - 1 > 0 and left[a - 1] != -1:\n                union(a-1, a)                \n            if a + 1 <= n and left[a + 1] != -1:\n                union(a, a + 1)\n                \n            if mp[m] != 0:\n                res = i + 1\n        return res\n            \n", "class UnionFind:\n    \n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.rank = [0] * n\n        \n    def find(self, u):\n        if u != self.parent[u]:\n            # path compression\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv: # ALREADY in the same set\n            return\n        \n        if self.rank[pu] > self.rank[pv]:\n            self.parent[pv] = pu\n            self.rank[pu] += self.rank[pv]\n            \n        elif self.rank[pv] > self.rank[pu]:\n            self.parent[pu] = pv\n            self.rank[pv] += self.rank[pu]\n            \n        else:\n            self.parent[pu] = pv\n            self.rank[pv] += self.rank[pu]\n            \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:   \n        n, ans = len(arr), -1\n        uf = UnionFind(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.rank[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = step\n                    if uf.rank[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.rank[uf.find(i)] == m:\n                return n\n            \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        day = [0] * (n + 1)\n        for i, a in enumerate(arr):\n            day[a] = i + 1\n        ans = -1\n        max_q = MaxQueue(m)\n        for i in range(1, n+1):\n            max_q.pop_expired(i)\n            max_q.push(day[i], i)\n            if i < m:\n                continue\n            left = right = math.inf\n            if i - m >= 1:\n                left = day[i-m]\n            if i + 1 <= n:\n                right = day[i+1]\n            if max_q.max() < (d := min(left, right)):\n                ans = max(ans, d - 1)\n        return ans\n\nclass MaxQueue:\n    def __init__(self, size):\n        self.queue = deque()\n        self.size = size\n\n    def push(self, x, pos):\n        while self.queue and self.queue[-1][0] < x:\n            self.queue.pop()\n        self.queue.append([x, pos])\n\n    def pop_expired(self, pos):\n        if self.queue and pos - self.queue[0][1] >= self.size:\n            self.queue.popleft()\n\n    def max(self):\n        return self.queue[0][0]", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        mp = Counter()\n        n = len(arr)\n        v = [False] * (n + 1)\n        left = [0] * (n + 1)\n        right = [0] * (n + 1)\n        for i, a in enumerate(arr):\n            v[a] = True\n            mp[1] += 1\n            left[a] = a\n            right[a] = a\n            if a - 1 > 0 and v[a - 1]:\n                mp[right[a] - left[a] + 1] -= 1\n                mp[right[a-1] - left[a-1] + 1] -= 1\n                ll = left[a - 1]\n                rr = right[a]\n                left[ll] = left[rr] = ll\n                right[rr] = right[ll] = rr\n                mp[rr - ll + 1] += 1\n            if a + 1 <= n and v[a + 1]:\n                mp[right[a] - left[a] + 1] -= 1\n                mp[right[a+1] - left[a+1] + 1] -= 1\n                ll = left[a]\n                rr = right[a+1]\n                left[ll] = left[rr] = ll\n                right[rr] = right[ll] = rr\n                mp[rr - ll + 1] += 1\n                \n            if mp[m] != 0:\n                res = i + 1\n        return res\n            \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[uf.find(j)]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans", "class UnionFind:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.rank = [0]*N\n        self.size = [0]*N\n    \n    def find(self, x):\n        if self.par[x]!=x:\n            self.par[x]=self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        \n        if px==py: return\n        if self.rank[px]<self.rank[py]:\n            self.par[px]=py\n            self.size[py]+=self.size[px]\n        elif self.rank[px]>self.rank[py]:\n            self.par[py]=px\n            self.size[px]+=self.size[py]\n        else:\n            self.par[py]=px\n            self.size[px]+=self.size[py]\n            self.rank[px]+=1\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr = [0]+arr\n        N = len(arr)\n        uf = UnionFind(N)\n        res = []\n        seen = set()\n        matched = set()\n        \n        for i in range(1, N):\n            seen.add(arr[i])\n            matched.add(arr[i])\n            uf.size[arr[i]]=1\n            if arr[i]-1>=0 and arr[i]-1 in seen:\n                uf.union(arr[i], arr[i]-1)\n            if arr[i]+1<N and arr[i]+1 in seen:\n                uf.union(arr[i], arr[i]+1)\n                \n            for j in list(matched):\n                idx = uf.find(j)\n                if uf.size[idx]!=m:\n                    matched.remove(j)\n\n            if matched: \n                res.append(i)\n\n        return res[-1] if res else -1\n        \n        \n        \n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents=[i for i in range(n)]\n        self.ranks=[0]*n  ## check whether the position is 1\n        \n    def find(self, x):\n        if x !=self.parents[x]:\n            self.parents[x]=self.find(self.parents[x])\n        return self.parents[x]\n    \n    def union(self,x,y):\n        px,py=self.find(x), self.find(y)\n        if px==py: return False\n        if self.ranks[px]>self.ranks[py]:\n            self.parents[py]=px\n            self.ranks[px]+=self.ranks[py]\n        elif self.ranks[px]<self.ranks[py]:\n            self.parents[px]=py\n            self.ranks[py]+=self.ranks[px]\n        else:\n            self.parents[py]=px\n            self.ranks[px]+=self.ranks[py]\n        return True\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m==len(arr):\n            return m \n        uf,ans=UnionFindSet(len(arr)),-1\n        for step, idx in enumerate(arr):\n            idx-=1\n            uf.ranks[idx]=1\n            for j in [idx-1,idx+1]:\n                if 0<=j<len(arr):\n                    if uf.ranks[uf.find(j)]==m:\n                        ans=step\n                    if uf.ranks[j]:  ### j is 1\n                        uf.union(idx,j)\n                        \n        #for i in range(n):\n        #    if uf.ranks[uf.find(i)]==m:\n        #        return n\n        return ans\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parents = list(range(n+1))\n        ranks = [0] * (n+1)\n        groupCounts = [0] * (n+1)\n        counts = [1] * (n+1)\n        visited = [False] * (n+1)\n        \n        def find(x):\n            if parents[x] != x:\n                parents[x] = find(parents[x])\n            \n            return parents[x]\n    \n        def union(x, y):\n            r1 = find(x)\n            r2 = find(y)\n            \n            if r1 != r2:\n                groupCounts[counts[r1]] -= 1\n                groupCounts[counts[r2]] -= 1\n                counts[r1] = counts[r2] = counts[r1] + counts[r2]\n                groupCounts[counts[r1]] += 1\n                \n                if ranks[r1] >= ranks[r2]:\n                    parents[r2] = r1\n                    ranks[r1] += ranks[r2]\n                else:\n                    parents[r1] = r2\n                    ranks[r2] += ranks[r1]\n        \n        last = -1\n        \n        for step, index in enumerate(arr):\n            groupCounts[1] += 1\n            if index-1 > 0 and visited[index-1]:\n                union(index, index-1)\n            \n            if index+1 <= n and visited[index+1]:\n                union(index, index+1)\n            \n            visited[index] = True\n            \n            if groupCounts[m]:\n                last = step + 1\n\n        return last\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def find_set(x):\n            if parents[x][0] == x:\n                return x\n            else:\n                return find_set(parents[x][0])\n\n\n        def union_set(x, y):\n            x_root = find_set(x)\n            y_root = find_set(y)\n            parents[y_root][1] += parents[x_root][1]\n            parents[x_root][0] = y_root\n\n\n        n = len(arr)\n        parents = [[i, 1] for i in range(n)]\n        visited = [False for i in range(n)]\n        answer = -1\n        d = {}\n        for i in range(n):\n            num = arr[i] - 1\n            visited[num] = True\n            if num > 0 and visited[num - 1]:\n                d[parents[find_set(num - 1)][1]] -= 1\n                union_set(num - 1, num)\n            if num + 1 < n and visited[num + 1]:\n                d[parents[find_set(num + 1)][1]] -= 1\n                union_set(num + 1, num)\n            d[parents[num][1]] = 1 if parents[num][1] not in d else d[parents[num][1]] + 1\n            if m in d and d[m] > 0:\n                answer = i + 1\n        return answer", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        n = len(arr)\n        \n        if n == m: return n;\n        \n        g = [0] * (n + 2)\n        for i, x in enumerate(arr):\n            l = g[x - 1]\n            r = g[x + 1]\n            \n            if l == m or r == m: res = i\n            \n            g[x - l] = g[x + r] = l + r + 1;\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        degree = [0] * n\n        par = list(range(n))\n\n        def find(x: int) -> int:\n            if par[x] == x:\n                return x\n            return find(par[x])\n\n        def union(x: int, y: int) -> None:\n            px, py = find(x), find(y)\n            if px == py:\n                return\n            if degree[px] > degree[py]:\n                par[py] = px\n                degree[px] += degree[py]\n            else:\n                par[px] = py\n                degree[py] += degree[px]\n\n        res = -1\n        for i, num in enumerate(arr):\n            num -= 1\n            degree[num] = 1\n            for nei in (num - 1, num + 1):\n                if 0 <= nei < n:\n                    if degree[find(nei)] == m:\n                        res = i\n                    if degree[nei]:\n                        union(nei, num)\n\n        # Check the last\n        for i in range(n):\n            if degree[find(i)] == m:\n                return n\n        return res", "from collections import defaultdict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        size_records = defaultdict(int)\n        range_records = defaultdict(list)\n        ans = -1\n        for index, i in enumerate(arr):\n            new_range = [i, i]\n            if range_records[i-1]:\n                new_range = [range_records[i-1][0], i]\n                size_records[range_records[i-1][1] - range_records[i-1][0] + 1] -= 1\n            if range_records[i+1]:\n                new_range = [new_range[0], range_records[i+1][1]]\n                size_records[range_records[i+1][1] - range_records[i+1][0] + 1] -= 1\n            # print(new_range)\n            size_records[new_range[1] - new_range[0] + 1] += 1\n            range_records[new_range[0]] = new_range\n            range_records[new_range[1]] = new_range\n            if size_records[m]:\n                ans = index + 1\n        return ans \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        \n        groups = defaultdict(set)\n        parents = [i for i in range(n)]\n        size = [0] * n\n        \n        def find(node):\n            if parents[node] == node:\n                return node\n            parent = find(parents[node])\n            return parent\n        \n        def union(a, b):\n            para = find(a)\n            parb = find(b)\n            if para != parb:\n                groups[parb].update(groups[para])\n                groups.pop(para)\n                parents[para] = parb\n                \n        def get_size(a):\n            parent = find(parents[a])\n            return len(groups[parent])\n        \n        def update(i):\n            check = get_size(i)\n            sizes[check] -= 1\n            if sizes[check] == 0:\n                sizes.pop(check)\n        \n        arr = [i-1 for i in arr]\n        step = 0\n        ans = -1\n        sizes = Counter()\n        for i in arr:\n            step += 1\n            size[i] += 1\n            groups[i].add(i)\n            sizes[1] += 1\n            if i-1 >= 0 and i+1 < n and size[i-1] and size[i+1]:\n                update(i-1)\n                update(i+1)\n                union(i, i-1)\n                union(i+1, i-1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i-1 >= 0 and size[i-1]:\n                update(i-1)\n                union(i, i-1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i+1 < n and size[i+1]:\n                update(i+1)\n                union(i, i+1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i+1)\n                sizes[new_size] += 1\n            if m in sizes:\n                ans = step\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bit_to_parent = [-1] * len(arr)\n        size = [0] * len(arr)\n        last_step = -1\n        groups_of_size_m = 0\n\n        def root(bit):\n            if bit_to_parent[bit] == -1:\n                return -1\n\n            root = bit\n            while root != bit_to_parent[root]:\n                root = bit_to_parent[root]\n            \n            curr = bit\n            while curr != root:\n                tmp = bit_to_parent[bit]\n                bit_to_parent[bit] = root\n                curr = tmp\n\n            # print(\\\"root\\\", bit, root)\n            return root\n        \n        def union(b1, b2):\n            # print(\\\"union\\\", b1, b2)\n            nonlocal size\n            nonlocal groups_of_size_m\n            \n            if b1 == b2:\n                size[b1] = 1\n                if m == 1:\n                    groups_of_size_m += 1\n                return\n            \n            root_b1 = root(b1)\n            root_b2 = root(b2)\n            \n            if root_b1 == -1 or root_b2 == -1:\n                # Can't union\n                return\n            \n            if size[root_b1] >= size[root_b2]:\n                parent = root_b1\n                child = root_b2\n            else:\n                parent = root_b2\n                child = root_b1\n            \n            old_parent_size = size[parent]\n            old_child_size = size[child]\n            \n            size[parent] += size[child]\n            bit_to_parent[child] = parent\n            \n            # print(\\\"union\\\", b1, b2, parent, child, old_parent_size, old_child_size, size[parent])\n            if old_parent_size == m:\n                groups_of_size_m -= 1\n            \n            if old_child_size == m:\n                groups_of_size_m -= 1\n            \n            if size[parent] == m:\n                groups_of_size_m += 1\n            \n            return parent\n        \n        for i in range(len(arr)):\n            bit = arr[i] - 1\n            bit_to_parent[bit] = bit\n            \n            union(bit, bit)\n            if bit - 1 >= 0:\n                union(bit, bit - 1)\n            if bit + 1 < len(arr):\n                union(bit, bit + 1)\n            \n            if groups_of_size_m > 0:\n                last_step = i + 1\n        \n        return last_step", "import heapq\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        times = [0] * len(arr)\n        for t, a in enumerate(arr):\n            times[a - 1] = t\n        # print(times)\n        res = -1\n        h = [(-a, i) for i, a in enumerate(times[:m])]\n        heapq.heapify(h)\n        maxtime = [-h[0][0]]\n        for i in range(m, len(times)):\n            heapq.heappush(h, (-times[i], i))\n            while h[0][1] <= i - m:\n                heapq.heappop(h)\n            maxtime.append(-h[0][0])\n        # print(maxtime)\n        if maxtime[0] < times[m]:\n            res = times[m]\n        if maxtime[-1] < times[-m - 1]:\n            res = max(res, times[-m - 1])\n        for i in range(1, len(times) - m):\n            if times[i - 1] > maxtime[i] and times[i + m] > maxtime[i]:\n                res = max(res, min(times[i - 1], times[i + m]))\n        return res", "class UnionFind:\n    \n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.rank = [0]*n\n        self.size = [0]*n\n        self.groupCount = [0]*(n+1)\n    \n    def find(self, x):\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def add(self, x):\n        self.size[x] = 1\n        self.groupCount[1] += 1\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return False\n        self.groupCount[self.size[px]] -= 1\n        self.groupCount[self.size[py]] -= 1\n        if self.rank[px] > self.rank[py]:\n            self.parent[py] = px\n            self.size[px] += self.size[py]\n            self.size[py] = 0\n        elif self.rank[py] > self.rank[px]:\n            self.parent[px] = py\n            self.size[py] += self.size[px]\n            self.size[px] = 0\n        else:\n            self.parent[px] = py\n            self.size[py] += self.size[px]\n            self.size[px] = 0\n            self.rank[py] += 1\n        self.groupCount[self.size[px]] += 1\n        self.groupCount[self.size[py]] += 1\n        return True\n    \n    def getSize(self, i):\n        px = self.find(i)\n        return self.size[px]\n    \nclass Solution:\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        disjoint = UnionFind(len(arr))\n        ans = - 1\n        val = [0]*len(arr)\n        for k in range(len(arr)):\n            index = arr[k] - 1\n            val[index] += 1\n            disjoint.add(index)\n            if index > 0 and val[index] == val[index-1]:\n                disjoint.union(index, index - 1)\n            if index + 1 < len(val) and val[index] == val[index+1]:\n                disjoint.union(index, index + 1)\n            #print(k, disjoint.groupCount)\n            if disjoint.groupCount[m] > 0:\n                ans = k + 1\n            '''\n            i = 0\n            while i < len(arr):\n                if val[i] == 1 and disjoint.getSize(i) == m:\n                    i += disjoint.getSize(i)\n                    ans = k + 1\n                    continue\n                i += 1\n            '''\n            #print(k, disjoint.size, val)\n        return ans \n    \n    '''\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def check(i):\n            val = [0]*len(arr)\n            for k in range(i+1):\n                val[arr[k]-1] = 1\n            count = 0\n            success = False\n            for k in range(len(val)):\n                if val[k] > 0:\n                    count += 1\n                else:\n                    if count == m:\n                        success = True\n                        break\n                    count = 0\n            if count == m:\n                success = True\n            return success                \n            \n        left = 0\n        right = len(arr)\n        while left < right:\n            mid = left + (right - left) //2\n            if not check(mid):\n                right = mid\n            else:\n                left = mid + 1\n        print(left)\n        if left == 0 and not check(left):\n            return -1\n        else:\n            return left\n    '''\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        groups = defaultdict(set)\n        parents = [i for i in range(n)]\n        size = [0] * n\n        \n        def find(node):\n            if parents[node] == node:\n                return node\n            parent = find(parents[node])\n            return parent\n        \n        def union(a, b):\n            para = find(a)\n            parb = find(b)\n            if para != parb:\n                groups[parb].update(groups[para])\n                groups.pop(para)\n                parents[para] = parb\n                \n        def get_size(a):\n            parent = find(parents[a])\n            return len(groups[parent])\n        \n        def update(i):\n            check = get_size(i)\n            sizes[check] -= 1\n            if sizes[check] == 0:\n                sizes.pop(check)\n        \n        arr = [i-1 for i in arr]\n        step = 0\n        ans = -1\n        sizes = Counter()\n        for i in arr:\n            step += 1\n            size[i] += 1\n            groups[i].add(i)\n            sizes[1] += 1\n            if i-1 >= 0 and i+1 < n and size[i-1] and size[i+1]:\n                update(i-1)\n                update(i+1)\n                union(i, i-1)\n                union(i+1, i-1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i-1 >= 0 and size[i-1]:\n                update(i-1)\n                union(i, i-1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i+1 < n and size[i+1]:\n                update(i+1)\n                union(i, i+1)\n                sizes[1] -= 1\n                if sizes[1] == 0:\n                    sizes.pop(1)\n                new_size = get_size(i+1)\n                sizes[new_size] += 1\n            if m in sizes:\n                ans = step\n        return ans", "class UnionSet:\n    def __init__(self, n):\n        self.par = list(range(n))\n        self.ed = list(range(n))\n    def find(self, i):\n        if self.par[i] != i:\n            par = self.find(self.par[i])\n            self.par[i] = par\n        return self.par[i]\n    def merge(self, i, j):\n        par1 = self.find(i)\n        par2 = self.find(j)\n        ed1 = self.ed[par1]\n        ed2 = self.ed[par2]\n        self.par[max(par1, par2)] = min(par1, par2)\n        self.ed[par1] = self.ed[par2] = max(ed1, ed2)\n    def get_ed(self, i):\n        return self.ed[i]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        us = UnionSet(n)\n        bits = [0] * n\n        result = -1\n        cnt = 0\n        for i, pos in enumerate(arr):\n            # print(bits)\n            # print(us.par)\n            # print(us.ed)\n            # print(cnt)\n            # print('-------')\n            pos -= 1\n            bits[pos] = 1\n            if pos > 0 and bits[pos - 1] == 1:\n                st = us.find(pos - 1)\n                ed = us.get_ed(st)\n                if ed - st + 1 == m:\n                    cnt -= 1\n                us.merge(pos, pos - 1)\n            if pos < n - 1 and bits[pos + 1] == 1:\n                st = us.find(pos + 1)\n                ed = us.get_ed(st)\n                if ed - st + 1 == m:\n                    cnt -= 1\n                us.merge(pos, pos + 1)\n            st = us.find(pos)\n            ed = us.get_ed(st)\n            if ed - st + 1 == m:\n                cnt += 1\n            if cnt > 0:\n                result = i + 1\n        return result", "from collections import defaultdict\nclass group:\n    def __init__(self,n,m):\n        self.groups=[i for i in range(n+1)]\n        self.group_size={}\n        self.m=m\n        self.m_sizes={}\n        for i in range(1,n+1):\n            self.group_size[i]=1\n        \n        \n    def union(self,i,j):\n        if i==j:\n            self.group_size[i]=1\n            gi=gj=i\n        else:\n            gi=self.get_group(i)\n            gj=self.get_group(j)\n            if self.group_size[gi]>self.group_size[gj]:\n                gj,gi=gi,gj\n            self.groups[gi]=gj\n        if self.group_size[gj]==self.m and gj in self.m_sizes  :\n            del(self.m_sizes[gj])\n        if self.group_size[gi]==self.m and gi in self.m_sizes :\n            del(self.m_sizes[gi])\n        if i!=j:\n            self.group_size[gj]+=self.group_size[gi]\n        \n        if self.group_size[gj]==self.m:\n            self.m_sizes[gj]=1\n        return self.group_size[gj]\n\n    def get_group(self,i):\n        if self.groups[i]!=i:\n            self.groups[i]=self.get_group(self.groups[i])\n        return self.groups[i]\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bits=[0]*(len(arr)+2)\n        GG=group(len(arr),m)\n        steps=0\n        latest=-1\n        for i in arr:\n            steps+=1\n            bits[i]=1\n            sz=1\n            if bits[i-1]==1:\n                sz=GG.union(i-1,i)\n            if bits[i+1]==1:\n                sz=GG.union(i,i+1)\n            if bits[i-1]==bits[i+1]==0:\n                sz=GG.union(i,i)\n            if GG.m_sizes:\n                latest=steps\n        return latest\n                \n            \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        cnt, ans = 0, -1\n        start_end, end_start = {}, {}\n        for i, n in enumerate(arr, start=1):\n            start, end = n, n\n            if n-1 in end_start:\n                start = end_start[n-1] \n                del end_start[n-1]\n                if n-start == m:\n                    cnt -= 1\n            if n+1 in start_end:\n                end = start_end[n+1]\n                del start_end[n+1]\n                if end-n == m:\n                    cnt -= 1\n            start_end[start] = end\n            end_start[end] = start\n            if end-start+1 == m:\n                cnt += 1\n            if cnt >= 1:\n                ans = i\n        return ans\n", "#Work backwards using a sorted dictionary to keep track of starting index and group length\n#Note: the key idea is to use dictionary bisect Java -> treemap.floorkey()\n\nfrom sortedcontainers import SortedDict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr) : return m\n        \n        pos2length = SortedDict()\n        \n        #means starting from index 0, there is group length of n\n        pos2length[0] = len(arr)\n        \n        #traverse the arr / break points backwards\n        for i in range(len(arr) - 1, -1, -1):\n            index = arr[i] - 1\n            interval_pos = pos2length.bisect_right(index) - 1\n            floor, length = pos2length.popitem(index = interval_pos)\n            \n            if floor != index:\n                pos2length[floor] = index - floor\n                if pos2length[floor] == m: return i\n            if floor + length - 1 != index:\n                pos2length[index + 1] = length - (index - floor) - 1\n                if pos2length[index + 1] == m: return i\n                \n        return -1\n", "class Solution:\n    def findLatestStep(self, arr, m):\n        l = [[] for _ in range(len(arr)+2)]; step = 1; cnt = 0; ans = -1\n        \n        for idx in arr:\n            l[idx].append(1)\n            \n            if l[idx][0] == m:\n                cnt += 1\n            \n            if l[idx-1] and l[idx+1]:\n                if l[idx-1][0] == m:\n                    cnt -= 1\n                if l[idx+1][0] == m:\n                    cnt -= 1\n                if l[idx][0] == m:\n                    cnt -= 1\n                    \n                _sum = l[idx-1][0] + l[idx][0] + l[idx+1][0]\n                i = 1\n                while l[idx-i]:\n                    l[idx-i] = l[idx]\n                    i+= 1\n\n                i = 1\n                while l[idx+i]:\n                    l[idx+i] = l[idx]\n                    i+= 1\n\n                l[idx].pop(); l[idx].append(_sum)\n                if l[idx][0] == m:\n                    cnt += 1\n                \n            elif l[idx-1]:\n                if l[idx-1][0] == m:\n                    cnt -= 1\n                if l[idx][0] == m:\n                    cnt -= 1\n                    \n                _sum = l[idx-1][0] + l[idx][0]\n                l[idx] = l[idx-1]\n                l[idx].pop(); l[idx].append(_sum)\n                \n                if l[idx][0] == m:\n                    cnt += 1\n                \n            elif l[idx+1]:\n                if l[idx+1][0] == m:\n                    cnt -= 1\n                if l[idx][0] == m:\n                    cnt -= 1\n                    \n                _sum = l[idx+1][0] + l[idx][0]\n                l[idx] = l[idx+1]\n                l[idx].pop(); l[idx].append(_sum)\n                \n                if l[idx][0] == m:\n                    cnt += 1\n                \n            if cnt > 0:\n                ans = step\n                \n            step += 1\n                \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n    \n        class DisjointSet:\n\n            def __init__(self, n):\n                self.parent = [-1] * n\n                self.size = [0] * n\n            \n            def make_set(self, v):\n                self.parent[v] = v\n                self.size[v] = 1\n\n            def find_set(self, v):\n                if self.parent[v] != v:\n                    self.parent[v] = self.find_set(self.parent[v])\n                return self.parent[v]\n\n            def union_sets(self, a, b):\n                a = self.find_set(a)\n                b = self.find_set(b)\n                if self.size[a] < self.size[b]:\n                    a, b = b, a\n                self.parent[b] = a\n                self.size[a] += self.size[b]\n        \n        n = len(arr)\n        if n == m:\n            return n\n        ans = -1\n        ds = DisjointSet(n)\n        for step, i in enumerate(arr):\n            i -= 1\n            ds.make_set(i)\n            for j in (i-1, i+1):\n                if 0 <= j <= n-1 and ds.parent[j] > -1:\n                    rep = ds.find_set(j)\n                    if ds.size[rep] == m:\n                        ans = step\n                    ds.union_sets(i, j)\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # union found and counter\n        counter = collections.Counter()\n        hs = {}  # record size of strings, with keys as starting index\n        n = len(arr)\n        # union find\n        def find(x, union):\n            root = x\n            if union[x] != x:\n                union[x] = find(union[x], union)\n            return union[x]\n                \n        union = {}\n        \n        res = -1\n        for i in range(n):\n            idx = arr[i]\n            union[idx] = idx\n            hs[idx] = 1 # size of 1\n            counter[1] += 1\n            if idx-1 in union:\n                left = find(idx-1, union)\n                union[idx] = find(idx-1, union)\n                # substract from counter\n                counter[hs[left]] -= 1\n                counter[hs[idx]] -= 1\n                counter[hs[left]+hs[idx]] += 1\n                hs[left] += hs[idx]\n                \n            if idx+1 in union:\n                right = find(idx+1, union)\n                union[idx+1] = find(idx, union)\n                # substract from counter\n                t = find(idx, union)\n                counter[hs[right]] -= 1\n                counter[hs[t]] -= 1\n                counter[hs[right] + hs[t]] += 1\n                hs[t] += hs[right]\n                \n            if counter[m] > 0:\n                res = i+1\n                \n        return res\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        sele = [0]*n\n        repe = [i for i in range(n)]\n        sis = [1]*n\n        def getRepe(a):\n            if repe[a]==a:\n                return a\n            repe[a] = getRepe(repe[a])\n            return repe[a]\n        def join(a,b):\n            ra,rb = getRepe(a), getRepe(b)\n            # print(ra,rb)\n            repe[b] = ra\n            sis[ra]+=sis[rb]\n        def sete(x):\n            # print('-',x)\n            if x>0 and sele[x-1]:\n                join(x-1,x)\n            if x < n-1 and sele[x+1]:\n                join(x,x+1)\n            sele[x]=1\n        res = -1\n        for i,v in enumerate(arr,1):\n            if v>1 and sele[v-2] and sis[getRepe(v-2)]==m:\n                res = i - 1\n            if v<n and sele[v] and sis[getRepe(v)]==m:\n                res = i-1\n            sete(v-1)\n            if sis[getRepe(v-1)]==m:\n                res = i\n        return res", "class DSU():\n    \n    def __init__(self):\n        self.size={}\n        self.parent={}\n    \n    def find(self,x):\n        if x!=self.parent[x]:\n            self.parent[x]=self.find(self.parent[x])\n        \n        return self.parent[x]\n    \n    def union(self,x,y):\n        xp,yp=self.find(x),self.find(y)\n        if xp==yp:\n            return False\n        \n        if self.size[xp]<self.parent[yp]:\n            xp,yp=yp,xp\n        \n        self.size[xp]+=self.size[yp]\n        self.parent[yp]=xp\n        return True\n    \n    def add_node(self,x):\n        self.parent[x]=x\n        self.size[x]=1\n    \n    def get_size(self,x):\n        return self.size[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        dsu=DSU()\n        sizes=collections.Counter()\n        ans=-1\n        for i,n in enumerate(arr,1):\n            dsu.add_node(n)\n            for nn in [n-1,n+1]:\n                if nn in dsu.parent:\n                    sizes[dsu.get_size(nn)]-=1\n                    dsu.union(n,nn)\n            sizes[dsu.get_size(n)]+=1\n            if sizes[m]>0:\n                ans=i\n        return ans\n                \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        counts = defaultdict(int)\n        root = [i for i in range(len(arr))]\n        size = [0 for i in range(len(arr))]\n        rank = [1 for i in range(len(arr))]\n        def find(i):\n            if root[i-1] != i-1:\n                root[i-1] = find(root[i-1]+1)\n            return root[i-1]\n        def union(i,j):\n            pi = find(i)\n            pj = find(j)\n            length = size[pi]+size[pj]\n            if pi != pj:\n                if rank[pi] <= rank[pj]:\n                    root[pi] = pj\n                    if rank[pi] == rank[pj]:\n                        rank[pj] += 1\n                else:\n                    root[pj] = pi\n                size[root[pi]] = length\n        step = -1\n        for i in range(len(arr)):\n            size[arr[i]-1] += 1\n            if arr[i] - 1 != 0 and size[find(arr[i]-1)] != 0:\n                counts[size[find(arr[i]-1)]] -= 1\n                union(arr[i]-1, arr[i])\n            if arr[i] + 1 != len(arr)+1 and size[find(arr[i]+1)] != 0:\n                counts[size[find(arr[i]+1)]] -= 1\n                union(arr[i]+1, arr[i])\n            counts[size[find(arr[i])]] += 1\n            if counts[m] != 0:\n                step = i+1\n        return step\n    '''\n    [5,3,4,7,8,14,11,9,2,12,1,13,10,6]\n6\n    '''", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if pu < pv:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, res = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in [i - 1, i + 1]:\n                if 0 <= j < n:\n                    # \u67e5\u770b\u672a\u5408\u5e76\u524d\u4e0a\u4e00\u6b65\u65f6\uff0c\u662f\u5426\u4e3am\n                    if uf.ranks[uf.find(j)] == m:\n                        res = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        for i in range(n):                \n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0] * (len(arr) + 2)\n        cnt = [0] * (len(arr) + 1)\n        res = -1\n        for i, num in enumerate(arr):\n            left, right = length[num - 1], length[num + 1]\n            length[num] = length[num - left] = length[num + right] = left + right + 1\n            cnt[length[num]] += 1\n            cnt[left] -= 1\n            cnt[right] -= 1\n            if cnt[m] > 0:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=max(arr)\n\n        dp=[[0,[i,i]] for i in range(n+2)]\n        \n        memo={}\n        res=-1\n        \n        for j,i in enumerate(arr):  \n            \n            dp[i][0]=1\n            val=1\n            \n            if dp[i-1][0]:\n                memo[dp[i-1][0]]-=1\n                left,right,val=dp[i-1][1][0],i,val+dp[i-1][0]\n                dp[left]=dp[right]=[val,[left,right]]\n\n\n            if dp[i+1][0]:\n                memo[dp[i+1][0]]-=1\n                left,right,val=dp[i][1][0],dp[i+1][1][1],val+dp[i+1][0]\n                dp[left]=dp[right]=[val,[left,right]]\n\n            memo[val]=memo.get(val,0)+1\n\n\n            if memo.get(m,0):\n                res=j+1\n                \n        return res", "class Solution:\n    def findLatestStep(self, A: List[int], T: int, last = -1) -> int:\n        seen, ok = set(), set()\n        A = [i - 1 for i in A]      # \u2b50\ufe0f -1 for 0-based indexing\n        N = len(A)\n        P = [i for i in range(N)]   # \\\\U0001f642 parent representative sets\n        L = [1] * N                 # \\\\U0001f925 length of each representative set\n        def find(x):\n            if x != P[x]:\n                P[x] = find(P[x])\n            return P[x]\n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            P[b] = a                # \\\\U0001f517 arbitrary choice for parent representative\n            return L[a] + L[b]\n        step = 1\n        for i in A:\n            seen.add(i)\n            if 0 < i     and find(P[i - 1]) in ok: ok.remove(find(P[i - 1]))\n            if i + 1 < N and find(P[i + 1]) in ok: ok.remove(find(P[i + 1]))\n            if i - 1 in seen: L[i] = union(i, i - 1)\n            if i + 1 in seen: L[i] = union(i, i + 1)\n            if L[i] == T:\n                ok.add(i)          # \u2705 i is the parent reprentative of the set with \\\\U0001f3af target T length\n            if len(ok):\n                last = step\n            step += 1\n        return last", "#Work backwards using a sorted dictionary to keep track of starting index and group length\n#Note: the key idea is to use dictionary bisect Java -> treemap.floorkey()\n\nfrom sortedcontainers import SortedDict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr) : return m\n        \n        pos2length = SortedDict()\n        \n        #means starting from index 0, there is group length of n\n        pos2length[0] = len(arr)\n        \n        #traverse the arr / break points backwards\n        for i in range(len(arr) - 1, -1, -1):\n            index = arr[i] - 1\n            \n            #this is equivalent to Java -> treemap.floorkey() function\n            interval_index = pos2length.bisect_right(index) - 1\n            floor, length = pos2length.popitem(index = interval_index)\n            \n            if floor != index:\n                pos2length[floor] = index - floor\n                if pos2length[floor] == m: return i\n            if floor + length - 1 != index:\n                pos2length[index + 1] = length - (index - floor) - 1\n                if pos2length[index + 1] == m: return i\n                \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parent = [i for i in range(n + 1)]\n        size = [0] * (n + 1)\n        counter = collections.Counter()\n        def find(x):\n            if x != parent[x]:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            x, y = min(x, y), max(x, y)\n            px, py = find(x), find(y)\n            if px != py:\n                counter[size[px]] -= 1\n                counter[size[py]] -= 1\n                parent[py] = px\n                size[px] += size[py]\n                counter[size[px]] += 1\n        A = [0] * (n + 2)\n        res = -1\n        for i, cur in enumerate(arr):\n            A[cur] = 1\n            size[cur] = 1\n            counter[1] += 1\n            if A[cur - 1] == 1:\n                union(cur - 1, cur)\n            if A[cur + 1] == 1:\n                union(cur, cur + 1)\n            if counter[m] > 0:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        arr = [x - 1 for x in arr]\n        parent = [x for x in range(N)]\n        size = [1 for _ in range(N)]\n        used = [False for _ in range(N)]\n        \n        def ufind(a):\n            if a == parent[a]:\n                return a\n            parent[a] = ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a, b):\n            sa = ufind(a)\n            sb = ufind(b)\n            \n            if sa != sb:\n                parent[sa] = parent[sb]\n                size[sb] += size[sa]\n        \n        def usize(a):\n            return size[ufind(a)]\n            \n        counts = [0] * (N+1)\n        \n        latest = -1\n        for index, x in enumerate(arr):\n            left = 0\n            if x - 1 >= 0 and used[x - 1]:\n                left = usize(x - 1)\n                \n            right = 0\n            if x + 1 < N and used[x + 1]:\n                right = usize(x + 1)\n                \n            current = 1\n            counts[1] += 1\n            if left > 0:\n                counts[left] -= 1\n            if right > 0:\n                counts[right] -= 1\n            counts[1] -= 1\n            used[x] = True\n            \n            new_size = left + right + current\n            #print(x, left, right)\n            counts[new_size] += 1\n            if left > 0:\n                uunion(x, x - 1)\n            if right > 0:\n                uunion(x, x + 1)\n            \n            #print(counts)\n            if counts[m] > 0:\n                latest = max(latest, index + 1)\n        return latest", "from collections import defaultdict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == 0:\n            return 0\n        if not arr:\n            return -1\n        step = 0\n        uf = UF(len(arr), m)\n        res = -1\n        for num in arr:\n            step += 1\n            # uf.add(num)\n            if uf.add(num):\n                res = step - 1\n#             print(uf.cnt.items(), step, num)\n#             print(uf.length_list, res)\n        \n        if uf.cnt.get(m):\n            return step\n        return res\n        \nclass UF:\n    def __init__(self, n, m):\n        self.max_length = n + 1\n        self.target = m\n        self.length_list = [0 for _ in range(self.max_length)] # length of each idx. Always check root node length.\n        self.cnt = defaultdict(int) # Save length we have.\n        self.par = defaultdict(int)\n        \n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n        \n    def union(self, x, y):\n        par_x = self.find(x)\n        par_y = self.find(y)\n        if par_x != par_y:\n            self.par[par_x] = par_y\n        self.cnt[self.length_list[par_x]] -= 1\n        self.cnt[self.length_list[par_y]] -= 1\n        self.length_list[par_y] += self.length_list[par_x]\n        self.cnt[self.length_list[par_y]] += 1\n        return False\n\n    def add(self, x):\n        tmp = self.cnt.get(self.target)\n        self.par[x] = x\n        self.length_list[x] = 1\n        self.cnt[1] += 1\n        if x >= 2 and self.length_list[x-1] > 0:\n            self.union(x, x-1)\n        if x <= self.max_length - 2 and self.length_list[x+1] > 0:\n            self.union(x, x+1)\n        # print(tmp, self.cnt[self.target], self.target)\n        if tmp and self.cnt[self.target] == 0:\n            return True\n        return False\n        \n", "# class Solution:\n#     def findLatestStep(self, A, m):\n#         length = [0] * (len(A) + 2)\n#         count = [0] * (len(A) + 1)\n#         res = -1\n#         for i, a in enumerate(A):\n#             left, right = length[a - 1], length[a + 1]\n#             length[a] = length[a - left] = length[a + right] = left + right + 1\n#             count[left] -= 1\n#             count[right] -= 1\n#             count[length[a]] += 1\n#             if count[m]:\n#                 res = i + 1\n#         return res        \n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        sz, cnt = [0]*n, defaultdict(int)\n        res = -2\n        parent = [i for i in range(n)]\n\n        def find(x):\n            if x != parent[x]:\n                parent[x] = find(parent[x])\n            return parent[x]\n\n        def union(x, y):\n            rx, ry = find(x), find(y)\n            cnt[sz[rx]] -= 1\n            cnt[sz[ry]] -= 1\n            cnt[sz[rx]+sz[ry]] += 1\n            parent[ry] = rx\n            sz[rx] += sz[ry]\n            return\n\n        for idx, a in enumerate(arr):\n            a -= 1\n            sz[a] = 1\n            cnt[1] += 1\n            if a-1 >= 0 and sz[a-1] > 0:\n                union(a-1,a)\n            if a+1 < n and sz[a+1] > 0:\n                union(a,a+1)\n            if cnt[m] > 0:\n                res = idx\n        return res+1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parents = list(range(n))\n        ranks = [0] * n\n        groupCounts = [0] * (n+1)\n        counts = [1] * n\n        visited = [False] * n\n        \n        def find(x):\n            if parents[x] != x:\n                parents[x] = find(parents[x])\n            \n            return parents[x]\n    \n        def union(x, y):\n            r1 = find(x)\n            r2 = find(y)\n            \n            if r1 != r2:\n                groupCounts[counts[r1]] -= 1\n                groupCounts[counts[r2]] -= 1\n                counts[r1] = counts[r2] = counts[r1] + counts[r2]\n                groupCounts[counts[r1]] += 1\n                \n                if ranks[r1] >= ranks[r2]:\n                    parents[r2] = r1\n                    ranks[r1] += 1\n                else:\n                    parents[r1] = r2\n                    ranks[r2] += 1\n        \n        last = -1\n        \n        for step, index in enumerate(arr):\n            index -= 1\n            groupCounts[1] += 1\n            if index-1 >= 0 and visited[index-1]:\n                union(index, index-1)\n            \n            if index+1 < n and visited[index+1]:\n                union(index, index+1)\n            \n            visited[index] = True\n            \n            if groupCounts[m]:\n                last = step + 1\n\n        return last\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        parents = list(range(n))\n        ranks = [0] * n\n        counts = [1] * n\n        groupCounts = [0] * (n+1)\n        cur_string = [0] * n\n        \n        def find(x):\n            if parents[x] != x:\n                parents[x] = find(parents[x])\n            \n            return parents[x]\n        \n        def union(x,y):\n            r1 = find(x)\n            r2 = find(y)\n            \n            groupCounts[counts[r1]] -= 1\n            groupCounts[counts[r2]] -= 1\n            counts[r1] = counts[r2] = counts[r1] + counts[r2]\n            groupCounts[counts[r1]] += 1\n            \n            if r1 != r2:\n                if ranks[r1] >= ranks[r2]:\n                    parents[r2] = r1\n                    ranks[r1] += 1\n                else:\n                    parents[r1] = r2\n                    ranks[r2] += 1\n        \n        ans = -1\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            groupCounts[1] += 1\n            \n            if i - 1 >= 0 and cur_string[i-1] == 1:\n                union(i, i-1)\n            \n            if i + 1 < n and cur_string[i+1] == 1:\n                union(i, i+1)\n            \n            cur_string[i] = 1\n            \n            if groupCounts[m]:\n                ans = step + 1\n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        comps = [0 for _ in range(len(arr) + 2)]\n        size = collections.defaultdict(int)\n        ans = -1\n        for i, n in enumerate(arr):\n            left, right = comps[n - 1], comps[n + 1]\n            comps[n - left] = comps[n + right] = comps[n] = left + right + 1\n            # print(comps)\n            \n            size[comps[n]] += 1\n            size[left] -= 1\n            size[right] -= 1\n            if size[m] > 0:\n                ans = i + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        dp = [[0,0] for _ in range(n+2)]\n        num = [0]*(n+2)\n        d = defaultdict(int)\n        ans = -1\n        for i in range(1,n+1):\n            x = arr[i-1]\n            num[x] = 1\n            l = dp[x-1][1]\n            r = dp[x+1][0]\n\n            # print(i,l,r)\n            d[l] -= 1\n            d[r] -= 1\n            d[dp[x-1][0]] -= 1\n            d[dp[x+1][1]] -= 1\n            dp[x-1] = [0,0]\n            dp[x+1] = [0,0]\n            d[0] += 4\n\n            d[dp[x-l][0]] -= 1\n            d[dp[x+r][1]] -= 1\n            dp[x-l][0] = r+l+1\n            dp[x+r][1] = r+l+1\n            d[r+l+1] += 2\n#             if num[x+1] == 1 and num[x-1] == 1:\n#                 l = dp[x-1][1]\n#                 r = dp[x+1][0]\n                \n#                 # print(i,l,r)\n#                 d[l] -= 1\n#                 d[r] -= 1\n#                 d[dp[x-1][0]] -= 1\n#                 d[dp[x+1][1]] -= 1\n#                 dp[x-1] = [0,0]\n#                 dp[x+1] = [0,0]\n#                 d[0] += 4\n                \n#                 d[dp[x-l][0]] -= 1\n#                 d[dp[x+r][1]] -= 1\n#                 dp[x-l][0] = r+l+1\n#                 dp[x+r][1] = r+l+1\n#                 d[r+l+1] += 2\n#             elif num[x+1] == 1:\n#                 r = dp[x+1][0]\n                \n#                 d[r] -= 1\n#                 d[dp[x+1][1]] -= 1\n#                 dp[x+1] = [0,0]\n#                 d[0] += 2\n                \n#                 d[dp[x-l][0]] -= 1\n#                 d[dp[x+r][1]] -= 1\n#                 dp[x-l][0] = r+l+1\n#                 dp[x+r][1] = r+l+1\n#                 d[r+l+1] += 2\n#             elif num[x-1] == 1:\n#                 l = dp[x-1][1]\n                \n#                 d[l] -= 1\n#                 d[dp[x-1][0]] -= 1\n#                 dp[x][1] = dp[x-1][1]+1\n#                 dp[x-1] = [0,0]\n#                 d[0] += 2\n                \n#                 d[dp[x-l][0]] -= 1\n#                 dp[x-l][0] = l+1\n#                 d[l+1] += 1\n                \n#             else:\n#                 dp[x] = [1,1]\n#                 d[1] += 2\n            \n            # print(num)\n            # print(dp)\n            # print(d)\n            \n            if d[m] != 0:\n                ans = i\n        return ans\n            \n", "class DSU:\n    def __init__(self):\n        self.p = {}\n        self.size = {}\n        self.size_to_node = collections.defaultdict(set)\n\n    def exists(self, x): return x in self.p\n    \n    def size_exists(self, x): return len(self.size_to_node[x]) > 0\n    \n    def len(self, x):\n        if self.exists(x): return self.size[self.find(x)]\n        else:              return -1\n\n    def make_set(self, x):\n        self.p[x] = x\n        self.size[x] = 1\n        self.size_to_node[1].add(x)\n        \n    def find(self, x):\n        if not self.exists(x): return None\n        \n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n\n        return self.p[x]\n\n    def union(self, x, y):\n        xr = self.find(x)\n        yr = self.find(y)\n        \n        if xr is None or yr is None: return\n        \n        self.p[xr] = yr\n        \n        self.size_to_node[self.size[yr]].remove(yr)\n        self.size_to_node[self.size[xr]].remove(xr)\n        \n        self.size[yr] += self.size[xr]\n        self.size_to_node[self.size[yr]].add(yr)\n        \n        del self.size[xr]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dsu = DSU()\n        latest_group = -1\n        \n        for i, x in enumerate(arr):\n            dsu.make_set(x)\n            dsu.union(x, x-1)\n            dsu.union(x, x+1)\n            \n            if dsu.size_exists(m):\n                latest_group = i+1\n        \n        return latest_group", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        def find_set(x):\n            if parents[x][0] == x:\n                return x\n            else:\n                return find_set(parents[x][0])\n\n\n        def union_set(x, y):\n            # print(x, y)\n            x_root = find_set(x)\n            y_root = find_set(y)\n            # print(x_root, y_root)\n            # print(parents[x_root], parents[y_root])\n            parents[y_root][1] += parents[x_root][1]\n            parents[x_root][0] = y_root\n\n\n        n = len(arr)\n        parents = [[i, 1] for i in range(n)]\n        # print(parents)\n        visited = [False for i in range(n)]\n        answer = -1\n        d = {}\n        for i in range(n):\n            num = arr[i] - 1\n            visited[num] = True\n            # if num > 0 and visited[num - 1]:\n            #     d[parents[num - 1][1]] -= 1\n            # if num + 1 < n and visited[num + 1]:\n            #     d[parents[num + 1][1]] -= 1\n            if num > 0 and visited[num - 1]:\n                d[parents[find_set(num - 1)][1]] -= 1\n                # print(parents)\n                union_set(num - 1, num)\n                # print(parents)\n            if num + 1 < n and visited[num + 1]:\n                d[parents[find_set(num + 1)][1]] -= 1\n                # print(parents)\n                union_set(num + 1, num)\n                # print(parents)\n            d[parents[num][1]] = 1 if parents[num][1] not in d else d[parents[num][1]] + 1\n            if m in d and d[m] > 0:\n                # print(i + 1, num + 1, d)\n                answer = i + 1\n        return answer", "class DSU:\n    def __init__(self):\n        self.p = {}\n        self.r = {}\n        self.count = collections.Counter()\n\n    def add(self, x: int):\n        self.p[x] = x\n        self.r[x] = 1\n        self.count[1] += 1\n        \n    def parent(self, x: int) -> int:\n        if self.p[x] != x:\n            self.p[x] = self.parent(self.p[x])\n        return self.p[x]\n    \n    def unite(self, x: int, y: int) -> int:\n        x = self.parent(x)\n        y = self.parent(y)\n        if x == y:\n            return self.r[x]\n        if self.r[x] > self.r[y]:\n            x, y = y, x\n        self.count[self.r[x]] -= 1\n        self.count[self.r[y]] -= 1\n        self.count[self.r[x] + self.r[y]] += 1\n        self.p[x] = y\n        self.r[y] += self.r[x]\n        return self.r[y]\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        dsu = DSU()\n        bits = [0] * (n + 2) \n        ans = -1\n        \n        for i, bit in enumerate(arr, 1):\n            dsu.add(bit)\n            bits[bit] = 1\n            if bits[bit - 1] == 1:\n                dsu.unite(bit, bit - 1)\n            if bits[bit + 1] == 1:\n                dsu.unite(bit, bit + 1)\n            if dsu.count[m] > 0:\n                ans = i\n            \n        return ans\n", "class UnionFind:\n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.rank = [0] * n\n        self.number_of_groups = n\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        x_parent, y_parent = self.find(x), self.find(y)\n        if x_parent == y_parent:\n            return False\n        if self.rank[x_parent] < self.rank[y_parent]:\n            x_parent, y_parent = y_parent, x_parent\n            \n        self.rank[x_parent] += self.rank[y_parent]\n        \n        self.parent[y_parent] = x_parent\n        \n        self.number_of_groups -= 1\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ans = -1\n        uf = UnionFind(n)\n        \n        for i, x in enumerate(arr):\n            x -= 1\n            uf.rank[x] = 1\n            for j in [x+1, x-1]:\n                if 0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = i\n                    if uf.rank[j]:\n                        uf.union(x, j)\n        \n        if any(uf.rank[uf.find(i)]==m for i in range(n)):\n            ans = n\n            \n        return ans\n", "_ROOT = object()\nclass UnionSet:\n    def __init__(self):\n        self.parents = {}\n        self.sizes = {}\n        self.size_histogram = collections.defaultdict(int)\n    \n    def has_size(self, size):\n        return self.size_histogram[size] != 0\n    \n    def add(self, x):\n        self.parents[x] = _ROOT\n        self.sizes[x] = 1\n        self.size_histogram[1] += 1\n\n        self.merge(x, x-1)\n        self.merge(x, x+1)\n        \n    def root(self, x):\n        path = []\n        while self.parents[x] != _ROOT:\n            path.append(x)\n            x = self.parents[x]\n        for y in path:\n            self.parents[y] = x\n        return x\n    \n    def merge(self, x, y):\n        if y not in self.parents:\n            return\n        x = self.root(x)\n        y = self.root(y)\n\n        self.size_histogram[self.sizes[x]] -= 1\n        self.size_histogram[self.sizes[y]] -= 1\n        merged_size = self.sizes[x] + self.sizes[y]\n        self.size_histogram[merged_size] += 1\n        if self.sizes[x] < self.sizes[y]:\n            del self.sizes[x]\n            self.parents[x] = y\n            self.sizes[y] = merged_size\n        else:\n            del self.sizes[y]\n            self.parents[y] = x\n            self.sizes[x] = merged_size\n            \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        union_set = UnionSet()\n        latest_step = -1\n        for step, pos in enumerate(arr):\n            union_set.add(pos)\n            if union_set.has_size(m):\n                latest_step = step + 1\n        return latest_step", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        groups = defaultdict(set)\n        parents = [i for i in range(n)]\n        size = [0] * n\n        \n        def find(node):\n            if parents[node] == node:\n                return node\n            parent = find(parents[node])\n            return parent\n        \n        def union(a, b):\n            para = find(a)\n            parb = find(b)\n            if para != parb:\n                groups[parb].update(groups[para])\n                groups.pop(para)\n                parents[para] = parb\n                \n        def get_size(a):\n            parent = find(parents[a])\n            return len(groups[parent])\n        \n        def update(i):\n            check = get_size(i)\n            sizes[check] -= 1\n            if sizes[check] == 0:\n                sizes.pop(check)\n        \n        arr = [i-1 for i in arr]\n        step = 0\n        ans = -1\n        sizes = Counter()\n        for i in arr:\n            step += 1\n            size[i] += 1\n            groups[i].add(i)\n            sizes[1] += 1\n            if i-1 >= 0 and i+1 < n and size[i-1] and size[i+1]:\n                update(i-1)\n                update(i+1)\n                update(i)\n                union(i, i-1)\n                union(i+1, i-1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i-1 >= 0 and size[i-1]:\n                update(i-1)\n                update(i)\n                union(i, i-1)\n                new_size = get_size(i-1)\n                sizes[new_size] += 1\n            elif i+1 < n and size[i+1]:\n                update(i+1)\n                update(i)\n                union(i, i+1)\n                new_size = get_size(i+1)\n                sizes[new_size] += 1\n            if m in sizes:\n                ans = step\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        uf = UnionFindHelper()\n        res = -1\n        for i, curr in enumerate(arr):\n            uf.add(curr)\n            step = i + 1\n            for neighbor in [curr - 1, curr + 1]:\n                if uf.contains(neighbor):\n                    if uf.getrank(neighbor) == m:\n                        res = step - 1\n                    uf.union(neighbor, curr)\n            # if uf.getrank(curr) == m:\n            #     res = step\n        return res\n        \nclass UnionFindHelper:\n    def __init__(self):\n        self.parent = {}\n        self.ranks = {}\n        self.count = 0\n        \n    def contains(self, item):\n        return item in self.parent\n    \n    def add(self, item):\n        if item not in self.parent:\n            self.parent[item] = item\n            self.ranks[item] = 1\n            self.count += 1\n    \n    def getrank(self, item):\n        return self.ranks[self.find(item)]\n    \n    def find(self, item):\n        if item != self.parent[item]:\n            self.parent[item] = self.find(self.parent[item])\n        return self.parent[item]\n    \n    def union(self, item1, item2):\n        item1 = self.find(item1)\n        item2 = self.find(item2)\n        rank1 = self.ranks[item1]\n        rank2 = self.ranks[item2]\n        if item1 != item2:\n            self.parent[item1] = item2\n            self.ranks[item2] = rank1 + rank2\n            self.count -= 1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        \n        self.parent = list(range(n + 1))\n        self.size = [0] * (n + 1)\n        \n        res = -1\n        for i, num in enumerate(arr):\n            if self.size[num] == 0:\n                self.size[num] = 1\n            if num - 1 >= 1 and self.size[num - 1] >= 1:\n                if self.size[self.find(num - 1)] == m: res = i\n                self.union(num - 1, num)\n            if num + 1 <= n and self.size[num + 1] >= 1:\n                if self.size[self.find(num + 1)] == m: res = i\n                self.union(num, num + 1)\n            # print(i, self.size, self.parent, res)\n        return res\n        \n    def union(self, a, b):\n        root_a = self.find(a)\n        root_b = self.find(b)\n        if root_a != root_b:\n            self.parent[root_a] = root_b\n            self.size[root_b] += self.size[root_a]\n    \n    def find(self, a):\n        curr = a\n        while self.parent[curr] != curr:\n            curr = self.parent[curr]\n        curr, root = a, curr\n        while self.parent[curr] != curr:\n            self.parent[curr], curr = root, self.parent[curr]\n        return root\n", "class DSU:\n  def __init__(self, m):\n    self.reps = {}\n    self.size = {}\n    self.m = m\n    self.count = 0\n  def add(self, x):\n    self.reps[x] = x\n    self.size[x] = 1\n    if self.m == 1:\n        self.count += 1\n  def find(self, x):\n    if not x == self.reps[x]:\n      self.reps[x] = self.find(self.reps[x])\n    return self.reps[x]\n  def union(self, x, y):\n    hX = self.find(x)\n    hY = self.find(y)\n    if not hX == hY:\n      h = min(hX, hY)\n      if self.size[hX] == self.m:\n        self.count -= 1\n      if self.size[hY] == self.m:\n        self.count -= 1\n      if h == hX:\n        self.reps[hY] = h\n        self.size[hX] += self.size[hY]\n        if self.size[hX] == self.m:\n          self.count += 1\n        self.size.pop(hY)\n      else:\n        self.reps[hX] = h\n        self.size[hY] += self.size[hX]\n        if self.size[hY] == self.m:\n          self.count += 1\n        self.size.pop(hX)\n\nclass Solution:\n  def findLatestStep(self, arr: List[int], m: int) -> int:\n    # dsu\n    dsu, s = DSU(m = m), -1\n    for i, x in enumerate(arr):\n      dsu.add(x)\n      if x - 1 in dsu.reps:\n        dsu.union(x - 1, x)\n      if x + 1 in dsu.reps:\n        dsu.union(x + 1, x)\n      if dsu.count > 0:\n        s = max(s, i + 1)\n    return s", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        comps = [0 for _ in range(len(arr) + 2)]\n        size = collections.defaultdict(int)\n        ans = -1\n        for i, n in enumerate(arr):\n            left, right = comps[n - 1], comps[n + 1]\n            comps[n - left] = comps[n + right] = comps[n] = left + right + 1\n            size[comps[n]] += 1\n            size[left] -= 1\n            size[right] -= 1\n            if size[m] > 0:\n                ans = i + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m==1 and len(arr)==1: return(1)\n        if m>len(arr):return(-1)\n        Bins=[0]*len(arr)\n        Gs={}#start,len\n        Ge={}#end,start ix\n        Res=-1\n        Rescnt=0\n        for y in range(len(arr)):\n            i=arr[y]-1\n            if (i==0 or Bins[i-1]==0) and (i==len(arr)-1 or Bins[i+1]==0):\n                #new group\n                # Gl[i]=1\n                # Gs[i]=i\n                Gs.update({i:1})\n                Ge.update({i:i})\n                Bins[i]=1\n                # ix=len(Gs)-1 \n                if m==1:\n                    Res=y+1\n                    Rescnt=Rescnt+1\n                    # print(Res,Rescnt)\n            else:\n                if (i==0 or Bins[i-1]==0) and (i<len(arr)-1 and Bins[i+1]==1):\n                    #extend left i+1\n                    # ix=[k for k,j in enumerate(Gs) if j[0]==(i+1)][0]\n                    Gs.update({i:Gs[i+1]+1})\n                    Ge[Gs[i+1] + i] = i\n                    tmp=Gs.pop(i+1)\n                    # tmpe=Ge.pop(i+1)\n                    Bins[i]=1\n                    if Gs[i]==m:\n                        Res=y+1\n                        Rescnt=Rescnt+1\n                    else: \n                        if tmp==m: Rescnt-=1\n                else:\n                    if (i>0 and Bins[i-1]==1) and (i==len(arr)-1 or Bins[i+1]==0):\n                        #extend right i-1\n                        # strt=i-1\n                        # while(strt>0 and Bins[strt]==1):strt-=1\n                        # if(Bins[strt]==0):strt+=1\n                        \n                        # ix=[k for k in Gs.keys() if k+Gs[k]==i][0]\n                        # ix=[k for k,j in enumerate(Gs) if j[0]==strt][0]\n                        ix=Ge[i-1]\n                        tmp=Gs[ix]\n                        Gs[ix]=Gs[ix]+1 \n                        tmpe=Ge.pop(i-1)\n                        Ge.update({i:ix})\n                        Bins[i]=1\n                        # if(Gs[ix][1]==m):Res=i\n                        if Gs[ix]==m:\n                            Res=y+1\n                            Rescnt=Rescnt+1\n                        else: \n                            if tmp==m: Rescnt-=1\n                    else:\n                        if (i>0 and Bins[i-1]==1) and (i<len(arr)-1 and Bins[i+1]==1):\n                            #merge Len=Sum+1\n\n                            # ix=[k for k in Gs.keys() if k+Gs[k]==i][0]\n                            # print('merge',i)\n                            ix=Ge[i-1]\n                            # print('ix',ix,i)\n                            tmp0=Gs[ix]\n                            Gs[ix]=Gs[ix]+Gs[i+1]+1\n                            tmp=Gs.pop(i+1)\n                            tmpe=Ge.pop(i-1)\n                            # print('ix2',tmp+i)\n                            Ge[tmp+i]=ix\n                            Bins[i]=1\n                            if Gs[ix]==m:\n                                Res=y+1\n                                Rescnt=Rescnt+1\n                            else: \n                                if tmp==m: Rescnt-=1\n                                if tmp0==m: Rescnt-=1                                \n            if Rescnt>0: Res=y+1\n            # print(i,'E',Ge)\n            # print('S',Gs)\n            \n            # for r in range(len(Gs)):\n            #         if Gs[r][1]==m:\n            #             Res=y+1\n            #             break                    \n        return(Res)", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count = collections.Counter()\n        length = collections.defaultdict(int)\n        ans = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            if count[m]:\n                ans = i + 1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parent = [i for i in range(len(arr))]\n                \n        def union(a, b):\n            par_a = find(a)\n            par_b = find(b)\n            if par_a == par_b:\n                return\n                \n            if(par_a > par_b):\n                par = par_a\n            else:\n                par = par_b\n                \n            parent[par_a] = par\n            parent[par_b] = par\n        def find(a):\n            if parent[a] == a:\n                return a\n            else :\n                parent[a] = find(parent[a])\n                return parent[a]\n        \n        ans = -1 \n        contigAtI = [0] * len(arr)\n        counts = [0] * (len(arr) + 1)\n        s = [0] * len(arr)\n        for idx, item in enumerate(arr):\n            s[item-1] = 1\n            \n            contigAtI[item-1]= 1 \n            counts[contigAtI[item-1]]+=1\n            \n            if item - 2 >= 0 and s[item-2] == 1:\n                counts[contigAtI[item-2]]-=1\n                counts[contigAtI[item-1]]-=1\n                contigAtI[item-1]+= contigAtI[item-2]\n                counts[contigAtI[item-1]]+=1\n                \n                union(item-2, item-1)\n                                \n            if item < len(arr) and s[item] == 1:\n                endPtr = find(item)\n                \n                counts[contigAtI[item-1]]-=1\n                counts[contigAtI[endPtr]]-=1\n                \n                contigAtI[endPtr] += contigAtI[item-1]\n                \n                counts[contigAtI[endPtr]]+=1\n                \n                \n                union(item-1, endPtr)\n            if counts[m] > 0:\n                ans = max(ans, idx+1)\n            \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        f = {}\n        n = len(arr)\n        ans = -1\n        ranks = [0] * (n+1)\n        \n        if m == n:\n            return m\n        \n        def find(x):\n            f.setdefault(x,x)\n            if f[x] != x:\n                f[x] = find(f[x])\n            \n            return f[x]\n        \n        def union(x,y):\n            px,py = find(x), find(y)\n            \n            if ranks[px] > ranks[py]:\n                ranks[px] += ranks[py]\n                f[py] = px\n            else:\n                ranks[py] += ranks[px]\n                f[px] = py\n\n            \n        for i,a in enumerate(arr):\n            ranks[a] = 1\n            \n            for j in [a-1,a+1]:\n                if 1<= j <= n:\n                    if ranks[find(j)] == m:\n                        ans = i\n                    if ranks[j]:\n                        union(a,j)\n        \n        return ans", "\nclass Subset:\n    \n    def __init__(self,parent,rank):\n        self.parent=parent\n        self.rank=rank\n        \ndef find(subsets,node):\n    if subsets[node].parent!=node:\n        subsets[node].parent=find(subsets,subsets[node].parent)\n    return subsets[node].parent\n\ndef union(subsets,x,y):\n    \n    xr=find(subsets,x)\n    yr=find(subsets,y)\n    if xr==yr:\n        return True\n    else:\n        xr=subsets[xr]\n        yr=subsets[yr]\n        \n        if xr.rank<yr.rank:\n            xr.parent=yr.parent\n            yr.rank+=xr.rank\n        elif xr.rank>yr.rank:\n            yr.parent=xr.parent\n            xr.rank+=yr.rank\n        else:\n            xr.parent=yr.parent\n            yr.rank=2*yr.rank\n            \n        return False\n    \nclass Solution:\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        \n        \n        a=[0 for ii in range(len(arr))]\n        subsets=[Subset(i,1) for i in range(len(arr))]\n        groups=set()\n        ans=-1\n        for j in range(len(arr)):\n            i=arr[j]-1\n            p=find(subsets,i)\n            a[i]=1\n            if i-1>=0 and a[i-1]==1:\n                if find(subsets,i-1) in groups:\n                   groups.remove(find(subsets,i-1))\n                union(subsets,i-1,i)\n            if i+1<=len(arr)-1 and a[i+1]==1:\n                if find(subsets,i+1) in groups:\n                    groups.remove(find(subsets,i+1))\n                union(subsets,i+1,i)\n            if subsets[find(subsets,i)].rank==m:\n                groups.add(find(subsets,i))\n            if subsets[find(subsets,i)].rank!=m and find(subsets,i) in groups:\n                groups.remove(find(subsets,i))\n            if len(groups):\n                ans=j+1\n            \n        return ans\n            \n            \n", "class UFDS:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        self.sizes = [1] * n\n        self.numdisjoint = n\n\n    def find(self, x):\n        xp = x\n        children = []\n        while xp != self.parents[xp]:\n            children.append(xp)\n            xp = self.parents[xp]\n        for c in children:\n            self.parents[c] = xp\n        return xp\n\n    def union(self, a, b):\n        ap = self.find(a)\n        bp = self.find(b)\n        if ap == bp:\n            return\n\n        if self.ranks[ap] < self.ranks[bp]:\n            self.parents[ap] = bp\n            self.sizes[bp] += self.sizes[ap]\n        elif self.ranks[bp] < self.ranks[ap]:\n            self.parents[bp] = ap\n            self.sizes[ap] += self.sizes[bp]\n        else:\n            self.parents[bp] = ap\n            self.ranks[ap] += 1\n            self.sizes[ap] += self.sizes[bp]\n\n        self.numdisjoint -= 1\n\n    def size(self, x):\n        return self.sizes[self.find(x)]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        s = set()\n        res = -1\n        d = [0] * (len(arr) + 1)\n        arr = [i-1 for i in arr]\n        u = UFDS(len(arr))\n        for i, val in enumerate(arr):\n            s.add(val)\n            if (val > 0) and (val-1 in s):\n                d[u.size(val-1)] -= 1\n                u.union(val-1, val)\n            if (val < len(arr)-1) and (val+1 in s):\n                d[u.size(val+1)] -= 1\n                u.union(val, val+1)\n            d[u.size(val)] += 1\n            #print(d)\n            if d[m] >= 1:\n                res = max(res, i+1)\n        #print(\\\"------------\\\")\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        parent = [i for i in range(N)]\n        rank = [0] * N\n        size = [1] * N\n        groupCount = Counter()\n        visited = set()\n        ans = -1\n        \n        for i, num in enumerate(arr, 1):\n            num -= 1\n            visited.add(num)\n            groupCount[1] += 1\n            \n            if num - 1 in visited:\n                self.union(parent, rank, size, groupCount, num, num - 1)\n                \n            if num + 1 in visited:\n                self.union(parent, rank, size, groupCount, num, num + 1)\n                \n            if groupCount[m] > 0:\n                ans = i\n                \n        return ans\n            \n    def find(self, parent, x):\n        if parent[x] != x:\n            parent[x] = self.find(parent, parent[x])\n\n        return parent[x]\n\n    def union(self, parent, rank, size, groupCount, x, y):\n        xRoot = self.find(parent, x)\n        yRoot = self.find(parent, y)\n        groupCount[size[xRoot]] -= 1\n        groupCount[size[yRoot]] -= 1\n        size[xRoot] = size[yRoot] = size[xRoot] + size[yRoot]\n        groupCount[size[xRoot]] += 1\n\n        if rank[xRoot] > rank[yRoot]:\n            parent[yRoot] = xRoot\n        elif rank[xRoot] < rank[yRoot]:\n            parent[xRoot] = yRoot\n        else:\n            parent[yRoot] = xRoot\n            rank[xRoot] += 1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        d = {}\n        sizes = {}\n        last_seen = -1\n        def find(x):\n            if d[x] != x:\n                d[x] = find(d[x])\n            return d[x]\n        for i in range(len(arr)):\n            I = arr[i]\n            d[I] = I\n            size = 1\n            if I - 1 in d:\n                if sizes[find(I - 1)] == m:\n                    last_seen = i\n                d[find(I)] = I - 1\n                sizes[find(I)] += size\n                size = sizes[find(I)]\n            if I + 1 in d:\n                if sizes[find(I + 1)] == m:\n                    last_seen = i\n                d[find(I)] = I + 1\n                sizes[find(I)] += size\n                size = sizes[find(I)]\n            sizes[find(I)] = size\n            if size == m:\n                last_seen = i + 1\n        return last_seen\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        arr = [x - 1 for x in arr]\n        parent = [x for x in range(N)]\n        size = [1 for _ in range(N)]\n        used = [False for _ in range(N)]\n        \n        def ufind(a):\n            if a == parent[a]:\n                return a\n            parent[a] = ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a, b):\n            sa = ufind(a)\n            sb = ufind(b)\n            \n            if sa != sb:\n                parent[sa] = parent[sb]\n                size[sb] += size[sa]\n                \n        def usize(a):\n            return size[ufind(a)]\n        \n        counts = [0] * (N + 1)\n        latest = -1\n        print('arr', arr)\n        \n        for index, x in enumerate(arr):\n            left = 0\n            if x - 1 >= 0 and used[x - 1]:\n                left = usize(x - 1)\n            right = 0\n            if x + 1 < N and used[x + 1]:\n                right = usize(x + 1)\n            current = 1\n            counts[1] += 1\n            if left > 0:\n                counts[left] -= 1\n            if right > 0:\n                counts[right] -= 1\n            counts[1] -= 1\n            used[x] = True\n            new_size = left + right + current\n            counts[new_size] += 1\n            if left > 0:\n                uunion(x, x - 1)\n            if right > 0:\n                uunion(x, x + 1)\n            if counts[m] > 0:\n                latest = max(latest, index + 1)\n                \n        return latest", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0]*(len(arr)+2)\n        count = [0]*(len(arr)+1)\n        ans = 0\n        for step, index in enumerate(arr):\n            left = length[index-1]\n            right = length[index+1]\n            length[index-left] = length[index+right] = right + left + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[right+left+1] += 1\n            if count[m] > 0:\n                ans = step+1 \n        if ans == 0:\n            return -1\n        return ans\n                \n                \n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        n = len(A)\n        if m == n: return n\n        dic = {0:[0, 0]}\n        def union(a, b):\n            fa = find(a)\n            fb = find(b)\n            if fa != fb:\n                dic[fa[0]] = [fb[0], fa[1] + fb[1]]\n                dic[fb[0]] = dic[fa[0]]\n                dic[a] = dic[fa[0]]\n                dic[b] = dic[fa[0]]\n        \n        def find(a):\n            if dic[a][0] != a:\n                dic[a] = find(dic[a][0])\n            return dic[a]\n                \n        \n        ans, t, ret = set(), 0, -1\n        for i, v in enumerate(A):\n            t = t | (1 << (v - 1))\n            dic[v] = [v, 1]\n            if v - 1 in dic:\n                if find(v - 1)[1] == m:\n                    ans.remove(dic[v - 1][0])\n                union(v, v - 1)\n            if v + 1 in dic:\n                if find(v + 1)[1] == m:\n                    ans.remove(dic[v + 1][0])\n                union(v, v + 1)\n            if dic[v][1] == m:\n                ans.add(dic[v][0])\n            if ans: ret = i + 1\n            # print(dic, ans)        \n        return ret", "class dsu:\n    def __init__(self,n):\n        self.par=[i for i in range(n)]\n        self.len=[1]*n\n        self.size=[0]*n\n        self.store=[0]*(n+1)\n\n    def unio(self,a,b):\n        a=self.find(a)\n        b=self.find(b)\n        \n        if self.len[a]>self.len[b]:\n            self.par[b]=a\n            self.size[a]+=self.size[b]\n            \n        elif self.len[a]<self.len[b]:\n            self.par[a]=b\n            self.size[b]+=self.size[a]\n        else:\n            self.par[b]=a\n            self.len[a]+=1\n            self.size[a]+=self.size[b]\n\n    def find(self,a):\n        if(a!=self.par[a]):\n            self.par[a]=self.find(self.par[a])\n        return self.par[a]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ds=dsu(len(arr))\n        n=len(arr)\n        t=[0]*n\n        ans=-1\n        tpp=0\n        for i in arr:\n            tpp+=1\n            curr=i-1\n            t[curr]=1\n            if(ds.size[curr]==0):\n                ds.size[curr]=1\n            flag=0\n            if(curr>=1 and t[curr-1]==1):\n                jm=ds.find(curr-1)\n                ds.store[ds.size[jm]]-=1\n                flag=1\n            if(curr<(n-1) and t[curr+1]==1):\n                jm=ds.find(curr+1)\n                ds.store[ds.size[jm]]-=1\n                flag=1\n            # if(flag):\n            #     ds.store[1]-=1\n            if(curr>=1 and t[curr-1]==1):\n                ds.unio(curr,curr-1)                \n            if(curr<(n-1) and t[curr+1]==1):\n                ds.unio(curr,curr+1)\n            jm=ds.find(curr)\n            ds.store[ds.size[jm]]+=1\n            # print(ds.store)\n            if(ds.store[m]):\n                ans=tpp\n                \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m: #\u6700\u540e\u4e00\u6b65\u624d\u51fa\u73b0\u6ee1\u8db3\u6761\u4ef6\n            return m\n        \n        A = [i for i in range(n)]\n        length = [0 for _ in range(n)]\n        ans = -1\n        def find(u):\n            if u != A[u]:\n                A[u] = find(A[u])\n            return A[u]\n        \n        def union(u, v):\n            pu, pv = find(u), find(v)\n            if pu == pv:\n                return False\n            \n            A[max(pu, pv)] = min(pu, pv)\n            #\u53ea\u4fee\u6539\u65b0\u7236\u8282\u70b9\u7684\u957f\u5ea6\uff0c\u8282\u7701\u65f6\u95f4\u3002\u5176\u4ed6\u7684\u7528\u4e0d\u5230\n            length[min(pu,pv)] += length[max(pu,pv)]\n            \n        for i, a in enumerate(arr):\n            a -= 1\n            length[a] = 1\n            for j in [a-1, a+1]:\n                #\u67e5\u627e\u4e24\u8fb9\u662f\u5426\u662f1\uff0c\u5982\u679c\u662f1\uff0c\u5219\u8054\u5408\u8d77\u6765\n                if 0 <= j < n:\n                    #\u5982\u679cj\u4f4d\u7f6e\u7684\u957f\u5ea6\u662fm\uff0c\u5219\u8bb0\u5f55\u4e0a\u4e00\u6b65\u662f\u6ee1\u8db3\u6761\u4ef6\u7684(\u6700\u540e\u4e00\u6b65\u65e0\u6cd5\u8bb0\u5f55)\n                    if length[find(j)] == m:\n                        ans = i\n                    if length[j]:\n                        union(j, a)\n                        # print(length)\n\n        # print(length)\n                        \n        return ans", "class DS:\n    def __init__(self, n):\n        self.par = list(range(n))\n        self.rank = [1] * n\n        \n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return\n        self.par[px] = py\n        self.rank[py] += self.rank[px]\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ds = DS(len(arr))\n        ans = -1\n        b_arr = [0] * len(arr)\n        \n        for i, num in enumerate(arr):\n            idx = num-1\n            b_arr[idx] = 1\n            \n            if idx > 0 and b_arr[idx-1]:\n                p = ds.find(idx-1)\n                if ds.rank[p] == m:\n                    ans = i\n                ds.union(idx, idx-1)\n                \n            if idx < len(arr)-1 and b_arr[idx+1]:\n                p = ds.find(idx+1)\n                if ds.rank[p] == m:\n                    ans = i\n                ds.union(idx, idx+1)\n                \n            p = ds.find(idx)\n            if ds.rank[p] == m:\n                ans = i+1\n        return ans", "class UnionFindSet:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0] * n\n        \n    def find(self, u):\n        if u != self.parent[u]:\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\n    \n    def union(self, u, v):\n        pu = self.find(u)\n        pv = self.find(v)\n        if pv == pu: return False\n        if self.rank[pu] < self.rank[pv]:\n            self.rank[pv] += self.rank[pu]\n            self.parent[pu] = pv\n        else:\n            self.rank[pu] += self.rank[pv]\n            self.parent[pv] = pu\n        return True\n            \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ans = -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.rank[i] = 1\n            for j in (i-1, i+1):\n                if  0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = step\n                    print(( uf.rank[uf.find(j)]))\n                    if uf.rank[j]:\n                        uf.union(i, j)\n                    \n                    \n                        \n        for i in range(n):\n            if uf.rank[uf.find(i)] == m:\n                return n\n        return ans\n        \n", "class union(object):\n    def __init__(self,n):\n        self.parent = [-1]*n\n        self.size = [0] *n\n        self.count = collections.defaultdict(int)\n    def find(self,p):\n        if self.parent[p] == -1:\n            return -1\n        if self.parent[p] != p:\n            self.parent[p] = self.find(self.parent[p])\n        return self.parent[p]\n    def union(self,p, q):\n        if self.find(p) != self.find(q):\n            pr = self.find(p)\n            qr = self.find(q)\n            \n            #print(pr,qr)\n            #print(self.count)\n            #print(self.size)\n            self.count[self.size[pr]] -= 1\n            self.count[self.size[qr]] -= 1\n            self.parent[pr] = qr\n            self.size[qr] += self.size[pr]\n            self.count[self.size[qr]] += 1\n            \n            #print(pr,qr)\n            #print(self.count)\n            #print(self.size)\n            \n            \n    def add(self,p):\n        self.parent[p] = p\n        self.size[p] = 1\n        self.count[1] += 1\n    def get_size(self , m):\n        \n        return self.count[m]>0\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if   m == len(arr):\n            return m\n        uds = union(len(arr) + 1)       \n        ans = -1\n        for i in range(len(arr)):\n            uds.add(arr[i]  ) \n            if arr[i] + 1 <= len(arr)  and uds.find(arr[i] +1  ) != -1:\n                uds.union(arr[i],arr[i] + 1)\n            if arr[i] - 1 >= 1 and uds.find(arr[i] - 1  ) != -1:\n                uds.union(arr[i] - 1,arr[i]  ) \n            if     uds.get_size( m)  :\n                ans = i + 1\n             \n            #print(uds.parent)\n            #print(uds.size)\n            #print(uds.count)\n        return ans\n            \n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n            \n        return self.parents[u]\n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        \n        if pu == pv:\n            return False\n        \n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = {}\n        n, ans = len(arr), -1\n        seen = [0] * (n + 1)\n\n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n\n        def union(x, y):\n            seen[find(y)] += seen[find(x)]\n            uf[find(x)] = find(y)\n        \n        if m == n:\n            return n\n        for i, a in enumerate(arr):\n            seen[a] = 1\n            for b in [a - 1, a + 1]:\n                if 1 <= b <= n and seen[b]:\n                    if seen[find(b)] == m:\n                        ans = i\n                    union(a, b)\n        return ans\n                \n                \n                \n                \n                \n", "class Solution:\n   def findLatestStep(self, A, m):\n        starts ={}\n        ends ={}\n        res = -1\n        count = 0\n        for i, a in enumerate(A):\n            if a-1 in ends and a+1 in starts:\n                end = starts.pop(a+1,None)\n                if (end - (a+1) +1) == m: count-=1\n                    \n                st = ends.pop(a-1,None)\n                if ((a-1)-st+1)==m: count-=1\n                \n                starts[st] = end\n                ends[end] = st\n                if(end-st+1) ==m: count+=1\n                \n            elif a-1 in ends:\n                st = ends.pop(a-1, None)\n                if ((a-1)-st+1)==m: count-=1\n                    \n                if a-1 in starts:\n                    starts.pop(a-1,None)\n                    \n                ends[a]=st\n                starts[st]=a\n                if(a-st+1) ==m: count+=1\n                \n            elif a+1 in starts:\n                end = starts.pop(a+1, None)\n                if (end - (a+1) +1) == m: count-=1\n                \n                if a+1 in ends:\n                    ends.pop(a+1,None)\n                    \n                starts[a]=end\n                ends[end]=a\n                if(end -a +1) ==m: count+=1\n            else:\n                ends[a]=a\n                starts[a]=a\n                if m ==1: count+=1\n            if count: res = i+1    \n        return res\n", "class UF:\n    def __init__(self, n):\n        self.cnt = [1] * n\n        self.fa = [i for i in range(n)]\n        \n    def find(self, x):\n        if x == self.fa[x]:\n            return x\n        \n        self.fa[x] = self.find(self.fa[x])\n        return self.fa[x]\n    \n    def unit(self, a, b):\n        a, b = self.find(a), self.find(b)\n        if a == b:\n            return False\n        \n        if self.cnt[a] < self.cnt[b]:\n            a, b = b, a\n            \n        self.cnt[a] += self.cnt[b]\n        self.fa[b] = a\n        return True\n    \n    def count(self, x):\n        return self.cnt[self.find(x)]\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # initialization\n        n = len(arr)\n        uf = UF(n + 1)\n        bits = [0] * (n + 1)\n        \n        # computing\n        result = -1\n        count = 0\n        for idx, val in enumerate(arr):\n            if val > 1 and bits[val - 1] == 1:\n                if uf.count(val - 1) == m:\n                    count -= 1\n                uf.unit(val, val - 1)\n                \n            if val < n and bits[val + 1] == 1:\n                if uf.count(val + 1) == m:                \n                    count -= 1\n                uf.unit(val, val + 1)\n                \n            if uf.count(val) == m:\n                count += 1\n                \n            if count > 0:\n                result = idx\n                \n            bits[val] = 1\n            \n                \n        return result + 1 if result != -1 else -1\n                \n        \n        \n", "class UnionFind(object):\n    def __init__(self):\n        self.parents = dict()\n        self.sizes = dict()\n    \n    def __contains__(self, i):\n        return self.parents.__contains__(i)\n    \n    def insert(self, i):\n        self.parents[i] = i\n        self.sizes[i] = 1\n\n    def find(self, i):\n        while i != self.parents[i]:\n            self.parents[i] = self.find(self.parents[i])  \n            i = self.parents[i]\n        return i\n\n    def union(self, p, q):\n        root_p, root_q = list(map(self.find, (p, q)))\n        if root_p == root_q: return\n        small, big = sorted([root_p, root_q], key=lambda x: self.sizes[x])\n        self.parents[small] = big\n        self.sizes[big] += self.sizes[small]    \n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UnionFind()\n        step_wanted = -1\n        n = len(arr)\n        for step, pos in enumerate(arr, 1):\n            uf.insert(pos)\n            for neighbor in [pos-1, pos+1]:\n                if neighbor not in uf: continue\n                if uf.sizes[uf.find(neighbor)] == m: step_wanted = step - 1\n                uf.union(pos, neighbor)\n        for i in range(1, n+1):\n            if uf.sizes[uf.find(i)] == m:\n                step_wanted = n\n        return step_wanted\n", "class DSU:\n    def __init__(self, m):\n        self.p = {}\n        self.islands = {}\n        self.m = m\n        self.hasm = 0\n    \n    def make_island(self, x):\n        self.p[x] = x\n        self.islands[x] = 1\n        if self.m == 1:\n            self.hasm += 1\n    \n    def exist(self, x):\n        if not x in self.p:\n            return False\n        return True\n    \n    def find(self, x):\n        if x != self.p[x]:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        if not self.exist(x) or not self.exist(y):\n            return\n        \n        xr = self.find(x)\n        yr = self.find(y)\n        \n        self.p[xr] = yr\n        \n        #both islands will be mutated after the following assignment\n        if self.islands[yr] == self.m:\n            self.hasm -= 1\n        if self.islands[xr] == self.m:\n            self.hasm -= 1\n            \n        self.islands[yr] = self.islands[xr] + self.islands[yr]\n        \n        if self.islands[yr] == self.m:\n            self.hasm += 1\n            \n        del self.islands[xr]\n        \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        #DSU\n        res = -1\n        dsu = DSU(m)\n        for i, x in enumerate(arr):\n            if not dsu.exist(x):\n                dsu.make_island(x)\n                dsu.union(x, x + 1)\n                dsu.union(x, x - 1)\n                if dsu.hasm != 0:\n                    res = i + 1\n        return res\n", "class Tree:\n    def __init__(self, lo, hi):\n        self.lo = lo\n        self.hi = hi\n        self.mid = None\n        self.left = self.right = None\n        \n    def size(self):\n        return self.hi - self.lo + 1\n        \n    def split(self, val, m):\n        if self.mid != None:\n            if val < self.mid:\n                if self.left.size() == 1:\n                    self.left = None\n                else:\n                    return self.left.split(val, m)\n            elif val > self.mid:\n                if self.right.size() == 1:\n                    self.right = None\n                else:\n                    return self.right.split(val, m)\n            return False\n        \n        if val == self.lo:\n            self.lo = val + 1\n            if self.hi - self.lo + 1 == m:\n                return True\n            \n        elif val == self.hi:\n            self.hi = val - 1\n            if self.hi - self.lo + 1 == m:\n                return True\n        else:\n            self.mid = val\n            check = False\n            if val - 1 >= self.lo:\n                if val - self.lo == m:\n                    return True\n                self.left = Tree(self.lo, val - 1)\n            if val + 1 <= self.hi:\n                if self.hi - val == m:\n                    return True\n                self.right = Tree(val + 1, self.hi)\n        return False\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return len(arr)\n        \n        root = Tree(1, len(arr))\n        step = len(arr) - 1\n        for i in range(len(arr)-1, -1, -1):\n            if root.split(arr[i], m):\n                return step\n            step -= 1\n        return -1\n", "class UF:\n    def __init__(self, n):\n        self.arr = list(range(n + 1))\n        self.rank = [1] * n\n        \n    def root(self, x): \n        curr = x    \n        while curr != self.arr[curr]:\n            curr = self.arr[curr]\n    \n        return curr\n    \n    def union(self, x, y):\n        root_x = self.root(x)\n        root_y = self.root(y)\n        \n        if root_x == root_y:\n            return\n        \n        rank_x = self.rank[root_x]\n        rank_y = self.rank[root_y]\n\n        if rank_x >= rank_y:\n            self.arr[root_y] = root_x\n            self.rank[root_x] += rank_y\n        else:\n            self.arr[root_x] = root_y\n            self.rank[root_y] += rank_x\n            \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UF(len(arr))\n        \n        sizes = {}\n        \n        seen = set()\n        last_time = None\n        for i, elt in enumerate(arr):\n            elt -= 1\n            \n            seen.add(elt)\n            left = elt - 1\n            right = elt + 1\n            if left >= 0 and left in seen and right < len(arr) and right in seen:\n                old_left_root = uf.root(left)\n                old_right_root = uf.root(right)\n\n                sizes[uf.rank[old_left_root]].remove(old_left_root)\n                if len(sizes[uf.rank[old_left_root]]) == 0:\n                    del sizes[uf.rank[old_left_root]]\n                sizes[uf.rank[old_right_root]].remove(old_right_root)\n                if len(sizes[uf.rank[old_right_root]]) == 0:\n                    del sizes[uf.rank[old_right_root]]\n                    \n                uf.union(left, elt)\n                uf.union(right, elt)\n\n            elif left >= 0 and left in seen:\n                old_left_root = uf.root(left) \n                sizes[uf.rank[old_left_root]].remove(old_left_root)\n                if len(sizes[uf.rank[old_left_root]]) == 0:\n                    del sizes[uf.rank[old_left_root]]\n                    \n                uf.union(left, elt)\n            \n            elif right < len(arr) and right in seen:\n                old_right_root = uf.root(right)\n                sizes[uf.rank[old_right_root]].remove(old_right_root)\n                if len(sizes[uf.rank[old_right_root]]) == 0:\n                    del sizes[uf.rank[old_right_root]]\n                    \n                uf.union(right, elt)\n            \n            new_root = uf.root(elt)\n            new_rank = uf.rank[new_root]\n            \n            if new_rank not in sizes:\n                sizes[new_rank] = set()\n            sizes[new_rank].add(new_root)\n\n            if m in sizes:\n                last_time = i\n            \n        if last_time is None:\n            return -1\n        else:\n            return last_time + 1\n                \n", "\nclass Node:\n    def __init__(self, parent, value):\n        self.value = value\n        self.parent = parent\n        self.size = 1\n        self.rank = 0\n\nclass UnionFind:\n    def __init__(self, nodes):\n        self.subsets = [Node(i, v) for i, v in enumerate(nodes)]\n        self.maxSubSetSize = 1\n\n    def union(self, i, j):\n        irep = self.find(i)\n        jrep = self.find(j)\n        if irep == jrep:\n            return\n        if self.subsets[irep].rank > self.subsets[jrep].rank:\n            self.subsets[jrep].parent = irep\n            self.subsets[irep].size += self.subsets[jrep].size\n            self.maxSubSetSize = max(self.maxSubSetSize, self.subsets[irep].size)\n        else:\n            self.subsets[irep].parent = jrep\n            self.subsets[jrep].size += self.subsets[irep].size\n            if self.subsets[irep].rank == self.subsets[jrep].rank:\n                self.subsets[jrep].rank += 1\n            self.maxSubSetSize = max(self.maxSubSetSize, self.subsets[jrep].size)\n    \n    def find(self, index):\n        if self.subsets[index].parent != index:\n            self.subsets[index].parent = self.find(self.subsets[index].parent)\n        return self.subsets[index].parent\n        \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr0 = [a - 1 for a in arr]\n        uf = UnionFind(list(range(len(arr0))))\n        lengthMSets = set()\n        last_step = -1\n        if m == 1:\n            lengthMSets.add(arr0[0])\n            last_step = 1\n        visited = [False for _ in arr0]\n        visited[arr0[0]] = True\n        for i in range(1, len(arr0), 1):\n            num = arr0[i]\n            visited[num] = True\n            if  num - 1 >= 0 and visited[num-1]:\n                left_rep = uf.find(num-1)\n                if left_rep in lengthMSets:\n                    lengthMSets.remove(left_rep)\n                uf.union(left_rep, num)\n            if num + 1 < len(visited)and  visited[num+1]:\n                right_rep = uf.find(num+1)\n                if right_rep in lengthMSets:\n                    lengthMSets.remove(right_rep)\n                uf.union(right_rep, num)\n            if uf.subsets[uf.find(num)].size == m:\n                lengthMSets.add(uf.find(num))\n            if len(lengthMSets) > 0:\n                last_step = i + 1\n        return last_step\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        uf = UnionFindHelper()\n        res = -1\n        for i, curr in enumerate(arr):\n            uf.add(curr)\n            step = i + 1\n            for neighbor in [curr - 1, curr + 1]:\n                if uf.contains(neighbor):\n                    if uf.getrank(neighbor) == m:\n                        res = step - 1\n                    uf.union(neighbor, curr)\n            if uf.getrank(curr) == m:\n                res = step\n        return res\n        \nclass UnionFindHelper:\n    def __init__(self):\n        self.parent = {}\n        self.ranks = {}\n        self.count = 0\n        \n    def contains(self, item):\n        return item in self.parent\n    \n    def add(self, item):\n        if item not in self.parent:\n            self.parent[item] = item\n            self.ranks[item] = 1\n            self.count += 1\n    \n    def getrank(self, item):\n        return self.ranks[self.find(item)]\n    \n    def find(self, item):\n        if item != self.parent[item]:\n            self.parent[item] = self.find(self.parent[item])\n        return self.parent[item]\n    \n    def union(self, item1, item2):\n        item1 = self.find(item1)\n        item2 = self.find(item2)\n        rank1 = self.ranks[item1]\n        rank2 = self.ranks[item2]\n        if item1 != item2:\n            self.parent[item1] = item2\n            self.ranks[item2] = rank1 + rank2\n            self.count -= 1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        L=len(arr)\n        S=1+2**(L+1)\n        count=1\n        account=L//m-1\n        C=2**m\n        if m==L:\n            return L\n        \n        while account:\n            k=arr.pop()\n            if m+1<=k:\n                s=S>>(k-m-1)\n                if s&(2*C-1)==1 :\n                    return L-count\n                s=s>>(m+2)\n            else:\n                s=(S>>k+1)&(2*C-1)\n            if s&(2*C-1)==C:\n                return L-count\n            S+= 1 << k\n            count+=1\n            if arr==[]:\n                break\n        Max=L+1\n        Min=0\n        while account==0:\n            k=arr.pop()\n            if L-m>=k>Min:\n                Min=k\n            elif k<Max:\n                Max=k\n            if Max-Min==m+1:\n                return L-count\n            elif Max-Min<m+1:\n                break\n            count+=1\n            if arr==[]:\n                break\n        return -1", "class DSU:\n    def __init__(self, n):\n        self.parent = []\n        for i in range(n + 2):\n            self.parent.append(i)\n        self.size = []\n        for i in range(n + 2):\n            self.size.append(1)\n    def union(self, u, v):\n        pu = self.find(u)\n        pv  = self.find(v)\n        if pu == pv:\n            return\n        if self.size[pv] > self.size[pu]:\n            pu, pv = pv, pu\n        #pu is bigger\n        self.parent[pv] = pu\n        self.size[pu] += self.size[pv]\n    def find(self, u):\n        if self.parent[u] != u:\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        current_arr = [-1] * (len(arr) + 2)\n        dsu = DSU(len(arr)+2)\n        res = -1\n        cur_sol = set()\n        for i, val in enumerate(arr):\n            if current_arr[val] == 1:\n                continue\n            else:\n                current_arr[val] = 1\n                if current_arr[val - 1] == 1:\n                    dsu.union(val, val - 1)\n                if current_arr[val + 1] == 1:\n                    dsu.union(val, val + 1)\n                pv = dsu.find(val)\n                if dsu.size[pv] == m:\n                    res = i + 1\n                    cur_sol.add(pv)\n                found = False\n                for cs in cur_sol:\n                    pcs = dsu.find(cs)\n                    if dsu.size[pcs] == m:\n                        found = True\n                if found == True:\n                    res = i + 1\n                #res = i + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        lens=[0]*(n+2)\n        count=[0]*(n+2)\n        res=-1\n        for i,num in enumerate(arr):\n            if lens[num]:\n                continue\n            l=lens[num-1]\n            r=lens[num+1]\n            t=l+r+1\n            lens[num-l]=lens[num+r]=lens[num]=t\n            count[l]-=1\n            count[r]-=1\n            count[t]+=1\n            if count[m]:\n                res=i+1\n        return res", "# https://leetcode.com/problems/find-latest-group-of-size-m/discuss/806718/Python-Clean-Union-Find-solution-with-explanation-O(N)\n# This solution utilize union by rank with 2 aims: count number of one as well as reduce the TC. One main point is that last step of group of ones of length m means we need bit set to ruin the last group of ones with length of m, or the this type of group will last until last step, so we can determine the result by determining the rank of left and right of currrent bit set. After one pass of arr, we can check if ranks of our union equal m.\nclass UnionFind:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n\n    def find(self, src: int) -> int:\n        if self.parents[src] == src:\n            return src\n        self.parents[src] = self.find(self.parents[src])\n        return self.parents[src]\n    \n    def union(self, src: int, dest: int) -> bool:\n        rootSrc, rootDest = self.find(src), self.find(dest)\n        if rootDest == rootSrc:\n            return False\n        \n        if self.ranks[rootSrc] > self.ranks[rootDest]:\n            self.parents[rootDest] = rootSrc\n            self.ranks[rootSrc] += self.ranks[rootDest]\n        else:\n            self.parents[rootSrc] = rootDest\n            self.ranks[rootDest] += self.ranks[rootSrc]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, result = len(arr), -1\n        uf = UnionFind(n)\n\n        for step, idx in enumerate(arr):\n            idx -= 1\n            uf.ranks[idx] = 1\n            for j in (idx - 1, idx + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        result = step\n                    if uf.ranks[j]:\n                        uf.union(idx, j)\n\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parents = list(range(len(arr) + 1))\n        group = [0] * (len(arr)  + 1)\n        counter = collections.Counter()\n        def find(x):\n            if x != parents[x]:\n                parents[x] = find(parents[x])\n            return parents[x]\n        \n        def union(x, y):\n            px = find(x)\n            py = find(y)\n            if px != py:\n                parents[py] = px\n                counter[group[px]] -= 1\n                counter[group[py]] -= 1\n                group[px] += group[py]\n                counter[group[px]] += 1\n            return\n        \n        visited = set()\n        ans = -1\n        \n        for i in range(len(arr)):\n            x = arr[i]\n            group[x] = 1\n            counter[1] += 1\n            for y in [x - 1, x + 1]:\n                if y in visited:\n                    union(x, y)\n            visited.add(x)\n            \n            if counter[m] > 0:\n                ans = i + 1\n        return ans", "class UnionFind:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.rank = [0]*N\n        self.size = [0]*N\n    \n    def find(self, x):\n        if self.par[x]!=x:\n            self.par[x]=self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        \n        if px==py: return\n        if self.rank[px]<self.rank[py]:\n            self.par[px]=py\n            self.size[py]+=self.size[px]\n        elif self.rank[px]>self.rank[py]:\n            self.par[py]=px\n            self.size[px]+=self.size[py]\n        else:\n            self.par[py]=px\n            self.size[px]+=self.size[py]\n            self.rank[px]+=1\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        arr = [0]+arr\n        N = len(arr)\n        uf = UnionFind(N)\n        res = []\n        seen = set()\n        matched = set()\n        \n        for i in range(1, N):\n            seen.add(arr[i])\n            matched.add(arr[i])\n            uf.size[arr[i]]=1\n            if arr[i]-1>=0 and arr[i]-1 in seen:\n                uf.union(arr[i], arr[i]-1)\n            if arr[i]+1<N and arr[i]+1 in seen:\n                uf.union(arr[i], arr[i]+1)\n                \n            all_bigger = True\n            for j in list(matched):\n                idx = uf.find(j)\n                if uf.size[idx]!=m:\n                    matched.remove(j)\n\n            if matched: \n                res.append(i)\n\n        return res[-1] if res else -1\n        \n        \n        \n        \n", "class DSU:\n    def __init__(self, n):\n        self.n = n\n        self.fa = list(range(n))\n        self.sz = [1 for _ in range(n)]\n\n    def find(self, x):\n        r = x\n        while self.fa[r] != r:\n            r = self.fa[r]\n        i = x\n        while i != r:\n            i, self.fa[i] = self.fa[i], r\n        return r\n    \n    def join(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        if x != y:\n            self.fa[x] = y\n            self.sz[y] += self.sz[x]\n    \n    def size(self, x):\n        x = self.find(x)\n        return self.sz[x]\n\nclass Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        n = len(a)\n        b = [0 for _ in range(n)]\n        dsu = DSU(n)\n        \n        ans = -1\n        valid = set()\n        for k, i in enumerate(a, 1):\n            j = i - 1\n            b[j] = 1\n            if j > 0 and b[j - 1]:\n                dsu.join(j, j - 1)\n            if j + 1 < n and b[j + 1]:\n                dsu.join(j, j + 1)\n\n            if m == dsu.size(j):\n                valid.add(j)\n            \n            valid = set(p for p in valid if m == dsu.size(p))\n            if valid:\n                ans = k\n\n        return ans", "class UnionFind:\n    def __init__(self):\n        self.parent = {}\n        self.rank = {}\n\n    def add(self, x):\n        self.parent[x] = x\n        self.rank[x] = 1\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        xRoot, yRoot = self.find(x), self.find(y)\n\n        if xRoot == yRoot:\n            return\n\n        xRank, yRank = self.rank[xRoot], self.rank[yRoot]\n        if xRank < yRank:\n            yRoot, xRoot = xRoot, yRoot\n\n        self.parent[yRoot] = xRoot\n        self.rank[xRoot] += self.rank[yRoot]\n        # if self.rank[ yRoot] == self.rank[xRoot]:\n        #     self.rank[xRoot] += 1\n\n        return\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return len(arr)\n        if m > len(arr):\n            return -1\n        uf = UnionFind()\n        \n        for i in range(1, len(arr)+1):\n            uf.add(i)\n        ans = -1\n        seen = set()\n        \n        for i, n in enumerate(arr):\n            uf.rank[n] = 1\n            if n - 1 >= 1 and n - 1 in seen:\n                if uf.rank[uf.find(n-1)] == m:\n                    ans = i\n                uf.union(n, n-1)\n            if n + 1 <= len(arr) and n+1 in seen:\n                if uf.rank[uf.find(n+1)] == m:\n                    ans = i\n                uf.union(n, n + 1)\n            seen.add(n)\n        return ans\n        \n        \n        \n        \n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parent = [i for i in (list(range(n)))]\n        self.rank = [0] * n\n        \n    def find(self, u):\n        if u != self.parent[u]:\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\n    \n    def union(self, u, v):\n        pu = self.find(u)\n        pv = self.find(v)\n        if pu == pv:\n            return False\n        if self.rank[pu] < self.rank[pv]:\n            self.rank[pv] += self.rank[pu]\n            self.parent[pu] = pv\n        else:\n            self.rank[pu] += self.rank[pv]\n            self.parent[pv] = pu\n        return True\n            \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        ans = -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.rank[i] = 1\n            for j in (i-1, i+1):\n                if  0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = step\n                    if uf.rank[j]:\n                        uf.union(i, j)\n                        \n        for i in range(n):\n            if uf.rank[uf.find(i)] == m:\n                return n\n        return ans\n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        s = '1' * n\n        sm = '1' * m\n        if m == n:\n            return n\n        for ind, i in enumerate(arr[::-1]):\n            #print(s, i, sm)\n            s = s[:i-1] +  '0' + s[i:]\n   # print((i - 1 + m < n ))\n   #          print(s[i : i  + m] , sm)\n   #          print(i, m, n)\n            if (i - 1 - m >= 0 and s[i - 1 - m: i - 1] == sm and ((i - 1 - m == 0) or s[i - 2 - m] == '0')) or  (i  + m <= n and s[i : i  + m] == sm and ((i + m == n ) or s[i + m ] == '0')):\n                return n - ind - 1\n        return -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        f = {}\n        n = len(arr)\n        ans = -1\n        ranks = [0] * (n+1)\n        \n        if m == n:\n            return m\n        \n        def find(x):\n            f.setdefault(x,x)\n            if f[x] != x:\n                f[x] = find(f[x])\n            \n            return f[x]\n        \n        def union(x,y):\n            px,py = find(x), find(y)\n            \n            if ranks[px] > ranks[py]:\n                ranks[px] += ranks[py]\n                f[py] = px\n            else:\n                ranks[py] += ranks[px]\n                f[px] = py\n\n            \n        for i,a in enumerate(arr):\n            ranks[a] += 1\n            \n            for j in [a-1,a+1]:\n                if 1<= j <= n:\n                    if ranks[find(j)] == m:\n                        ans = i\n                    if ranks[j]:\n                        union(a,j)\n        \n        return ans", "class UnionFind:\n\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.count = [1]*n\n\n    def find(self, x):\n        parent = self.parent[x]\n        if parent != x:\n            # reassign its parent to the root\n            self.parent[x] = self.find(parent)\n        return self.parent[x]\n    \n    def get_count(self, x):\n        return self.count[self.find(x)]\n        \n    def union(self, x, y):\n        xparent, yparent = self.find(x), self.find(y)\n        if xparent == yparent:\n            return\n        self.parent[yparent] = xparent  # assign yparent parent to xparent\n        self.count[xparent] += self.count[yparent]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = max(arr)\n        bits = [0]*(100005)\n        disjoint = UnionFind(n+1)\n        mapping = collections.defaultdict(int)\n        ans = -1\n\n        for ind in range(len(arr)):\n            pos = arr[ind]\n            bits[pos] = 1\n            mapping[1] += 1\n            i, j = pos-1, pos+1\n            if bits[i] and disjoint.find(i) != disjoint.find(pos):\n                mapping[disjoint.get_count(i)] -= 1\n                mapping[disjoint.get_count(pos)] -= 1\n                disjoint.union(i, pos)\n                mapping[disjoint.get_count(pos)] += 1\n            if bits[j] and disjoint.find(j) != disjoint.find(pos):\n                mapping[disjoint.get_count(j)] -= 1\n                mapping[disjoint.get_count(pos)] -= 1\n                disjoint.union(j, pos)\n                mapping[disjoint.get_count(pos)] += 1\n            if mapping[m] > 0:\n                ans = ind+1\n        return ans", "class UnionFind:\n    def __init__(self, n):\n        self.parents = [i for i in range(n)]\n        self.size = [1] * n\n\n    def find(self, i):\n        while i != self.parents[i]:\n            self.parents[i] = self.parents[self.parents[i]] # path halving\n            i = self.parents[i]\n        return i\n    \n    def union(self, a, b):\n        aPar = self.find(a)\n        bPar = self.find(b)\n        \n        if aPar == bPar:\n            return\n        \n        # union by size\n        if self.size[aPar] > self.size[bPar]:\n            self.parents[bPar] = aPar\n            self.size[aPar] += self.size[bPar]\n        else:\n            self.parents[aPar] = bPar\n            self.size[bPar] += self.size[aPar]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        uf = UnionFind(N)\n        isAlive = [False] * N\n        numM = 0\n        latest = -1\n        \n        for index, i in enumerate(arr):\n            isAlive[i-1] = True\n            if i != 1 and isAlive[i-2]:\n                if uf.size[uf.find(i-2)] == m:\n                    numM -= 1\n                uf.union(i-1, i-2)\n            if i != N and isAlive[i]:\n                if uf.size[uf.find(i)] == m:\n                    numM -= 1\n                uf.union(i-1, i)\n            if uf.size[uf.find(i-1)] == m:\n                numM += 1\n            if numM > 0:\n                latest = index + 1\n                \n        return latest\n                \n            \n            \n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        starts, ends = {}, {}\n        res = None\n        contributors = set()\n        for i, pos in enumerate(arr):\n            if pos-1 not in ends:\n                l = pos\n            else:\n                l = ends[pos-1]\n                del ends[pos-1]\n                if l in contributors:\n                    contributors.remove(l)\n            if pos+1 not in starts:\n                r = pos\n            else:\n                r = starts[pos+1]\n                del starts[pos+1]\n                if pos+1 in contributors:\n                    contributors.remove(pos+1)\n            if m == r - l + 1:\n                contributors.add(l)\n            if contributors:\n                res = i+1\n            starts[l] = r\n            ends[r] = l\n        return res if res is not None else -1", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu != pv:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n            if uf.ranks[uf.find(i)] == m:\n                ans = step + 1\n            # print(step, i, uf.ranks, ans)\n        return ans", "from sortedcontainers import SortedList\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        s = SortedList([0, n + 1])\n        \n        if n == m: return n\n        \n        for i, x in enumerate(reversed(arr)):\n            j = s.bisect_left(x)\n            s.add(x)\n            if m == x - s[j-1] - 1 or m == s[j + 1] - x - 1:\n                return n - i - 1\n            \n        return -1", "class UnionFindSet:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0 for _ in range(n)]\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xroot, yroot = self.find(x), self.find(y)\n        if xroot == yroot:\n            return\n        \n        if self.rank[xroot] > self.rank[yroot]:\n            self.rank[xroot] += self.rank[yroot]\n            self.parent[yroot] = xroot\n        else:\n            self.rank[yroot] += self.rank[xroot]\n            self.parent[xroot] = yroot\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return m\n        \n        uf = UnionFindSet(n)\n        ans = -1\n        \n        for step, idx in enumerate(arr):\n            idx -= 1\n            uf.rank[idx] = 1\n            for j in (idx - 1, idx + 1):\n                if 0 <= j < n:\n                    if uf.rank[uf.find(j)] == m:\n                        ans = step\n                    if uf.rank[j]:\n                        uf.union(idx, j)\n        \n        return ans", "from typing import List\n\n\nclass UnionFind:\n  def __init__(self, n):\n    self.parent = list(range(n))\n    self.rank = [0] * n\n\n  def find(self, u):\n    if u != self.parent[u]:\n      self.parent[u] = self.find(self.parent[u])\n    return self.parent[u]\n\n  def union(self, u, v):\n    pu, pv = self.find(u), self.find(v)\n    if pu == pv:\n      return False\n    if self.rank[pu] > self.rank[pv]:\n      self.parent[pv] = pu\n      self.rank[pu] += self.rank[pv]\n    elif self.rank[pv] > self.rank[pu]:\n      self.parent[pu] = pv\n      self.rank[pv] += self.rank[pu]\n    else:\n      self.parent[pu] = pv\n      self.rank[pv] += self.rank[pu]\n    return True\n\n\nclass Solution:\n  def findLatestStep(self, arr: List[int], m: int) -> int:\n    ans = -1\n    n = len(arr)\n    uf = UnionFind(n)\n\n    for step, k in enumerate(arr):\n      i = k - 1\n      uf.rank[i] = 1\n      for j in (i - 1, i + 1):\n        if 0 <= j < n:\n          if uf.rank[uf.find(j)] == m:\n            ans = step\n          if uf.rank[j]:\n            uf.union(i, j)\n\n    for i in range(n):\n      if uf.rank[uf.find(i)] == m:\n        return n\n\n    return ans\n", "\nclass Node:\n    def __init__(self):\n        self.left = None\n        self.right = None\n        self.length = 0\n\nclass Solution:\n    def findLatestStep(self, arr, m):\n        def remove(node):\n            left = node.left\n            node.right.left = left\n            left.right = node.right\n            \n        count = 0\n        node = {}\n        M= max(arr)\n        for i in range(M+2):\n            n = Node()\n            node[i] = n\n            if i == 0:\n                continue\n            \n            node[i-1].right = n\n            n.left = node[i-1]\n        \n        ans = -1\n        for step, i in enumerate(arr):\n            node[i].length = 1\n            if node[i].left.length > 0:\n                # merge with left\n                node[i].length += node[i].left.length\n                if node[i].left.length == m:\n                    count -= 1\n                remove(node[i].left)\n            if node[i].right.length > 0:\n                if node[i].right.length == m:\n                    count -= 1\n                node[i].length += node[i].right.length\n                remove(node[i].right)\n            if node[i].length == m:\n                count += 1\n            if count > 0:\n                ans = step + 1\n            #print(step, count, ans)\n        return ans\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        counter = [0] * (n+1)\n        parent = [i for i in range(n+1)]\n        size = [0 for i in range(n+1)]\n        \n        def find(u):\n            if parent[u] == u:\n                return u\n            parent[u] = find(parent[u])\n            return parent[u]\n        \n        def union(u, v):\n            ru, rv = find(u), find(v)\n            if size[ru] < size[rv]:\n                parent[ru] = rv\n                size[rv] += size[ru]\n            else:\n                parent[rv] = ru\n                size[ru] += size[rv]\n        \n        def getSize(p):\n            return size[find(p)]\n        \n        res = -1\n        for i, pos in enumerate(arr):\n            size[pos] = 1\n            # counter[1] += 1\n            if pos > 0:\n                if getSize(pos-1) > 0:\n                    s_last = getSize(pos-1)\n                    union(pos-1, pos)\n                    counter[s_last] -= 1\n            if pos < n:\n                if getSize(pos+1) > 0:\n                    s_next = getSize(pos+1)\n                    union(pos, pos+1)\n                    counter[s_next] -= 1\n            counter[getSize(pos)] += 1\n            if counter[m] > 0:\n                res = i+1\n        \n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        size = {i:1 for i in range(n)}\n        dp = [*range(n)]\n        res = -1\n        \n        def union(i, j):\n            size_count[size[find(i)]] -= 1\n            size_count[size[find(j)]] -= 1\n            tmp = size[find(i)] + size[find(j)]\n            size_count[tmp] += 1\n            size[find(i)] = size[find(j)] = tmp\n            dp[find(i)] = dp[find(j)]\n        \n        def find(i):            \n            if i != dp[i]: dp[i] = find(dp[i])\n            return dp[i]                \n            \n        curr = [0] * n                \n        size_count = [0] * (n + 1)\n        for k, i in enumerate([x - 1 for x in arr]):\n            curr[i] = 1\n            size_count[1] += 1\n            if i < n - 1 and curr[i + 1]:\n                union(i, i + 1)\n            if i and curr[i - 1]:\n                union(i, i - 1)\n            if size_count[m] > 0:\n                res = k + 1\n       \n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        mem = {}\n        gsizes = 0\n        inc = False\n        lastpos = -1\n        changed = False\n        \n        for i, num in enumerate(arr):\n            # print(mem)\n            gsize = 1\n            if num -1 in mem:\n                if mem[num-1][0] == m:\n                    gsizes -= 1\n                    changed = True\n                gsize += mem[num-1][0]\n            \n            if num +1 in mem:\n                if mem[num+1][0] == m:\n                    gsizes -= 1\n                    changed = True\n                gsize += mem[num+1][0]\n            \n            # print(gsize, m)\n            if gsize == m:\n                inc = True\n                changed = True\n                gsizes += 1\n            # print(gsizes)\n\n            # print(mem)\n            # if inc:\n            #     print(gsizes)\n            #     print(gsize)\n            #     print(num)\n            \n            # print(gsizes)\n            if gsizes == 0 and inc and changed:\n                changed = False\n                lastpos = i\n                # print('end')\n                # return i\n            \n            # mem[num] = (gsize, num)\n            if num +1 not in mem and num -1 not in mem:\n                end = num\n            elif num + 1 in mem:\n                end = mem[num+1][1]\n            else:\n                end = mem[num-1][1]\n            mem[num] = (gsize, end)\n            \n            if num - 1 in mem:\n                old = mem[num-1][1]\n                mem[mem[num-1][1]] = (gsize, mem[num+1][1] if num +1 in mem else num)\n                \n            if num + 1 in mem:\n                mem[mem[num+1][1]] = (gsize, old if num -1 in mem else num)\n                \n#         if gsizes:\n#             return len(arr)\n        # print(gsizes)\n            \n        # return -1 if gsizes == 0 else len(arr)\n        return len(arr) if gsizes else lastpos\n        \n            \n                \n", "from collections import defaultdict \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n\n        if m==n:\n            return m\n\n        # number at index i means the length of 1's array starting or ending at i\n        b=[0]*(n+2)\n        cnt=defaultdict(lambda : 0)\n        latest = -1\n        for i in range(n):\n            left = b[arr[i]-1]\n            right = b[arr[i]+1]\n            \n            # if left is non-zero, arr[i]-1 must be the end of a 1's array\n            # it cannot be a start because arr[i] is not yet 1\n            # in this case we merge with left, arr[i] will be the new end point\n            if left > 0 and right == 0:\n                # b[arr[i]-1]+=1\n                b[arr[i]]+=1+left\n                # arr[i]-1-left-1 is the start of the 1's array\n                b[arr[i]-1-left+1]+=1\n                cnt[left] -= 1\n                cnt[left+1] += 1\n            elif left == 0 and right > 0:\n                # b[arr[i]+1]+=1\n                b[arr[i]]+=1+right\n                # arr[i]+1+right-1 is the end of the 1's array\n                b[arr[i]+1+right-1]+=1\n                cnt[right] -= 1\n                cnt[right+1] += 1\n            # if both are non zero, we can merge the left array and right array\n            # creating an array with length left + right + 1\n            elif left > 0 and right > 0:\n                # b[arr[i]-1]+=1+right\n                # b[arr[i]+1]+=1+left\n                # b[arr[i]]+=1+left+right\n\n                # arr[i]-1-left-1 is the start of the 1's array\n                b[arr[i]-1-left+1]+=1+right\n                # arr[i]+1+right-1 is the end of the 1's array\n                b[arr[i]+1+right-1]+=1+left\n                cnt[right] -= 1\n                cnt[left] -= 1\n                cnt[1+left+right] += 1\n            else:# final case where both left and right are zero\n                b[arr[i]]+=1\n                cnt[1]+=1\n            if m in cnt:\n                if cnt[m]>0:\n                    latest = i+1\n        return latest", "class DSU:\n    \n    def __init__(self, n, m):\n        self.parents = [-1] * n\n        self.sizes = [0] * n\n        self.target = m\n        self.matches = 0\n        \n    def find(self, x):\n        parent = self.parents[x]\n        if parent in [-1, x]:\n            return parent\n        self.parents[x] = self.find(parent)\n        return self.parents[x]\n    \n    def union(self, x, y):\n        if x == y:\n            self.parents[x] = x\n            self.sizes[x] = 1\n            if 1 == self.target:\n                self.matches += 1\n        else:\n            px, py = self.find(x), self.find(y)\n            sx, sy = self.sizes[px], self.sizes[py]\n            if sy > sx:\n                px, py = py, px\n                sx, sy = sy, sx\n            self.parents[py] = px\n            self.sizes[px] = sx + sy\n            if sx == self.target:\n                self.matches -= 1\n            if sy == self.target:\n                self.matches -= 1\n            if sx + sy == self.target:\n                self.matches += 1     \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dsu = DSU(len(arr), m)\n        last_good = -1\n        for i, v in enumerate(arr):\n            v -= 1\n            dsu.union(v, v)\n            if v-1 >= 0 and dsu.find(v-1) != -1:\n                dsu.union(v, v-1)\n            if v+1 < len(arr) and dsu.find(v+1) != -1:\n                dsu.union(v, v+1)\n            if dsu.matches > 0:\n                last_good = i+1\n        return last_good\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        p = [i for i in range(n)]\n        l = [0 for i in range(n)]\n        s = [0 for i in range(n)]\n        counts = collections.Counter()\n        res = []\n        def find(a):\n            if p[a] == a: return a\n            p[a] = find(p[a])\n            \n            return p[a]\n        def union(a, b):\n            p_a, p_b = find(a), find(b)\n            if p[p_b] != p[p_a]:\n                p[p_b] = p[p_a]\n                l[p_a] += l[p_b]\n        for v in arr:\n            i = v - 1\n            s[i] = 1\n            l[i] = 1\n            f_a = f_b = False\n            if i + 1 < n and s[i + 1] == 1:\n                counts[l[find(i + 1)]] -= 1\n                union(i, i + 1)\n                f_a = True\n            if i - 1 >= 0 and s[i - 1] == 1:\n                counts[l[find(i - 1)]] -= 1\n                union(i - 1, i)\n                f_b = True\n            if f_a and f_b:\n                counts[l[find(i - 1)]] += 1\n            elif f_a:\n                counts[l[find(i)]] += 1\n            elif f_b:\n                counts[l[find(i - 1)]] += 1\n            else:\n                counts[l[find(i)]] += 1\n            res.append(counts[m])\n            \n        for i in range(n - 1, -1, -1):\n            if res[i] > 0:\n                return i + 1\n        \n        return -1\n", "from sortedcontainers import SortedList\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sl = SortedList()\n        n = len(arr)\n        if n == m:\n            return n\n        s = n\n        while s >= 1:\n            s -= 1\n            if len(sl) == 0:\n                if n-arr[s] == m or arr[s] - 1 == m:\n                    return s\n            else:\n                idx = sl.bisect_left(arr[s])\n                if idx == 0:\n                    if arr[s] - 1 == m or sl[idx] - arr[s] - 1 == m:\n                        return s\n                elif idx == len(sl):\n                    if n - arr[s] == m or arr[s] - sl[idx-1] - 1 == m:\n                        return s\n                else:\n                    if arr[s] - sl[idx-1] - 1 == m or sl[idx] - arr[s] - 1 == m:\n                        return s\n            sl.add(arr[s])\n        return -1", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\n\nclass Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        if m == len(A):\n            return len(A)\n        \n        n, ans = len(A), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(A):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i-1, i+1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i,j)\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        #union find\n        \n        \n        dsu = [False] * (len(arr) +1)\n        dsu[0] = 0\n        \n        \n        def find(a):\n            if dsu[a] == False:\n                dsu[a] = -1\n                return a\n            x = []\n            while dsu[a] >=0:\n                x.append(a)\n                a=dsu[a]\n            for b in x:\n                dsu[b] = a        \n            return a\n        def size(a):\n            pa=find(a)\n            return abs(dsu[pa])\n        def union(a,b):\n            pa,pb = find(a),find(b)\n            if pa != pb:\n                if dsu[pa] < dsu[pb]:\n                    dsu[pa] += dsu[pb]\n                    dsu[pb] = pa\n                else:\n                    dsu[pb] += dsu[pa]\n                    dsu[pa] = pb\n                return True\n            return False\n        ans=-1\n        for i,x in enumerate(arr,1):\n            find(x)\n            if x> 1 and dsu[x-1] != False:\n                if size(x-1) == m:\n                    dsu[0] -=1\n                union(x,x-1)\n            if x<len(arr) and dsu[x+1] != False:\n                if size(x+1) == m:\n                    dsu[0]-=1\n                union(x,x+1)\n            if size(x) == m:\n                dsu[0]+=1\n            #print(dsu[0])\n            if dsu[0] > 0:\n                ans = i\n        return ans\n", "from sortedcontainers import SortedList\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sizes = Counter((len(arr),))\n        groups = SortedList([[1, len(arr)]])\n        for i in range(len(arr)-1, -1, -1):\n            if m in sizes:\n                return i + 1\n            n = arr[i]\n            j = groups.bisect_left([n, n]) \n            if j == len(groups) or j > 0 and groups[j-1][1] >= n:\n                j -= 1\n            h, t = groups.pop(j)\n            sizes[t - h + 1] -= 1\n            if h < n: \n                groups.add([h, n-1])\n                sizes[n-1 - h + 1] += 1 \n            if t > n:    \n                groups.add([n+1, t])\n                sizes[t - n - 1 + 1] += 1 \n        return -1 ", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans\n        \n \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [1] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFindSet(n)\n        b_arr = [0] * n\n        ans = -1\n        for step, num in enumerate(arr):\n            idx = num - 1\n            b_arr[idx] = 1\n            if idx > 0 and b_arr[idx - 1]:\n                p = uf.find(idx - 1)\n                if uf.ranks[p] == m:\n                    ans = step\n                uf.union(idx, idx - 1)\n            if idx < n - 1 and b_arr[idx + 1]:\n                p = uf.find(idx + 1)\n                if uf.ranks[p] == m:\n                    ans = step\n                uf.union(idx, idx + 1)\n            p = uf.find(idx)\n            if uf.ranks[p] == m:\n                ans = step + 1\n                \n        for idx in range(n):\n            p = uf.find(idx)\n            if uf.ranks[p] == m:\n                return n\n            \n        return ans", "from collections import deque\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        pieces = {}\n        goodpieces = {}\n        latest = -1\n        for i in range(1, len(arr) + 1):\n            n = arr[i-1]\n            start, end = 0,0\n            if n+1 in pieces and n-1 in pieces:\n                start = pieces.pop(n-1)\n                end = pieces.pop(n+1)\n            elif n+1 in pieces:\n                start = n\n                end = pieces.pop(n+1)\n            elif n-1 in pieces:\n                start = pieces.pop(n-1)\n                end = n\n            else:\n                start = n\n                end = n\n            if (end - start + 1) == m:\n                goodpieces[start] = end\n            pieces[start] = end\n            pieces[end] = start\n            bad = []\n            for piece in goodpieces:\n                if (piece in pieces) and pieces[piece] == goodpieces[piece]:\n                    latest = i\n                else:\n                    bad.append(piece)\n            for b in bad:\n                del goodpieces[b]\n\n            #print(pieces)\n        return latest\n                    \n", "from collections import Counter\nclass DSU:\n    def __init__(self, n):\n        self.dic = [i for i in range(n)]\n    def find(self, n1):\n        if self.dic[n1] != n1:\n            self.dic[n1] = self.find(self.dic[n1])\n        return self.dic[n1]\n    def union(self, n1, n2):\n        s1 = self.find(n1)\n        s2 = self.find(n2)\n        self.dic[s2] = s1\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        cnt = Counter()        \n        area = Counter()\n        fliped = [False for _ in arr]\n        dsu = DSU(len(arr))        \n        res = []\n        def union_bits(b, bi):\n            if not (0 <= bi < len(arr) and fliped[bi]):\n                return 0\n            s = dsu.find(bi)\n            sa = area[s] \n            cnt[sa] -= 1\n            dsu.union(s, b)     \n            return sa\n        for i, b in enumerate(arr):\n            b -= 1\n            fliped[b] = True             \n            ba = 1\n            ba += union_bits(b, b - 1)\n            ba += union_bits(b, b + 1)\n            s = dsu.find(b)\n            area[s] = ba\n            cnt[ba] += 1\n            if cnt[m] > 0:\n                res.append(i)\n        # print(res)\n        return res[-1] + 1 if res else -1\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        bits = [0] * len(arr)\n        uf = UnionFind(bits)\n        step = 0\n        ans = -1\n        for real_n in arr:\n            step += 1\n            # print(\\\"step\\\", step)\n            n = real_n-1\n            bits[n] = 1\n            uf.father[n] = n\n            uf.cnt[n] = 1\n            uf.cntFreq[1] += 1\n            # print(bits)\n            if n-1 >= 0 and bits[n-1] == 1:\n                uf.union(n, n-1)  \n            if n+1 < len(bits) and bits[n+1] == 1:\n                uf.union(n, n+1) \n            # print(uf.cntFreq)\n            if uf.cntFreq[m] > 0:\n                ans = step\n        return ans\n            \nclass UnionFind:\n    def __init__(self, bits):\n        self.len = len(bits)\n        self.father = [-1] * (self.len)\n        self.cnt = [0] * (self.len)\n        self.cntFreq = collections.Counter()\n\n                    \n    def union(self, p, q):\n        rootP = self.find(p)\n        rootQ = self.find(q)\n        cntP = self.cnt[rootP]\n        cntQ = self.cnt[rootQ]\n        if rootP != rootQ:\n            self.father[rootP] = rootQ\n            self.cntFreq[self.cnt[rootP]] -= 1\n            self.cntFreq[self.cnt[rootQ]] -= 1\n            self.cntFreq[cntP+cntQ] += 1\n            self.cnt[rootQ] = cntP+cntQ\n        \n    def find(self, p):\n        rootP = self.father[p]\n        while rootP != self.father[rootP]:\n            rootP = self.father[rootP]\n        self.father[p] = rootP\n        return rootP\n", "class DSU:\n    def __init__(self, n):\n        self.r = collections.defaultdict(int)\n        self.p = collections.defaultdict(int)\n        self.s = collections.defaultdict(int)\n        self.scount = collections.defaultdict(int)\n    \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        \n        if self.r[px] > self.r[py]:\n            self.p[py] = px\n            self.scount[self.s[py]] -= 1\n            self.scount[self.s[px]] -= 1\n            self.s[px] += self.s[py]\n            self.s[py] = 0\n            self.scount[self.s[px]] += 1\n            \n        if self.r[px] < self.r[py]:\n            self.p[px] = py\n            self.scount[self.s[py]] -= 1\n            self.scount[self.s[px]] -= 1\n            self.s[py] += self.s[px]\n            self.s[px] = 0\n            self.scount[self.s[py]] += 1\n        else:\n            self.p[py] = px\n            self.scount[self.s[py]] -= 1\n            self.scount[self.s[px]] -= 1\n            self.r[px] += 1\n            self.s[px] += self.s[py]\n            self.s[py] = 0\n            self.scount[self.s[px]] += 1\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dsu = DSU(len(arr))\n        seen = set()\n        ret = -1\n        for i in range(len(arr)):\n            dsu.p[arr[i]] = arr[i]\n            dsu.s[arr[i]] = 1\n            dsu.r[arr[i]] = 0\n            dsu.scount[1] += 1\n            if arr[i] + 1 in seen:\n                dsu.union(arr[i], arr[i] + 1)\n            if arr[i] - 1 in seen:\n                dsu.union(arr[i], arr[i] - 1)\n                \n            if dsu.scount[m] > 0:\n                ret = max(ret, i)\n            seen.add(arr[i])\n            \n        return ret + 1 if ret != -1 else -1\n\n        \n        \n        \n        \n        \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = max(arr)\n        dp = [1] * n\n        steps = n\n        if m == n:\n            return steps\n\n        for a in reversed(arr):\n            steps -= 1\n            i = a - 1\n            dp[i] = 0\n            j = i + 1\n            cnt = 0\n            while j < n and dp[j] == 1:\n                cnt += 1\n                if cnt > m:\n                    break\n                j += 1\n            else:\n                if cnt == m:\n                    return steps\n            j = i - 1\n            cnt = 0\n            while j >= 0 and dp[j] == 1:\n                cnt += 1\n                if cnt > m:\n                    break\n                j -= 1\n            else:\n                if cnt == m:\n                    return steps\n        return -1", "from bisect import bisect_left\nclass Solution:\n    def findLatestStep(self, arr, m: int) -> int:\n        n = len(arr)\n        segments = [(1, n)]\n        if m == n:\n            return n\n        for cur_iter, zero in enumerate(arr[::-1]):\n            index = bisect_left(segments, (zero, 9999999999)) - 1\n            #print(segments, zero, index)\n            seg = segments[index]\n            if seg[1] == 1 and seg[0] == zero:\n                del segments[index]\n            elif seg[1] == 1:\n                assert False\n            else:\n                del segments[index]\n                first_length = zero-seg[0]\n                second_length = seg[0]+seg[1]-1-zero\n                if first_length == m or second_length == m:\n                    return n - cur_iter - 1\n                if second_length >= 1:\n                    segments.insert(index, (zero+1, second_length))\n                if first_length >= 1:\n                    segments.insert(index, (seg[0], first_length))\n            # print(segments)\n        return -1\n", "class Solution:\n    def find(self, n):\n        if self.par[n] == n:\n            return n\n        else:\n            self.par[n] = self.find(self.par[n])\n            return self.par[n]\n        \n    def union(self, n1, n2):\n        p1 = self.find(n1)\n        p2 = self.find(n2)\n        if self.rank[p1] < self.rank[p2]:\n            self.par[p1] = p2\n            self.rank[p2] += self.rank[p1]\n        elif self.rank[p1] > self.rank[p2]:\n            self.par[p2] = p1\n            self.rank[p1] += self.rank[p2]    \n        else:\n            self.par[p2] = p1\n            self.rank[p1] += self.rank[p2]\n            \n        \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        self.N = N\n        if m == N:\n            return N\n        \n        self.par = list(range(N+1))\n        self.rank = [0]*(N+1)\n        result = -1\n        s = '0'*(N+1)\n        for i, v in enumerate(arr, 1):\n            self.rank[v] = 1\n            for j in [v-1, v+1]:\n                if 1<=j<=N and self.rank[j]:\n                    if self.rank[self.find(j)] == m:\n                        result = i-1\n                    self.union(j, v)\n\n            \n        for i in range(1, N+1):\n            if self.rank[self.find(i)] == m:\n                return N\n            \n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res,matchGroups=-1,set()\n        uf={}\n        groupSize=defaultdict(lambda: 1)\n        def find(x):\n            uf.setdefault(x,x)\n            if uf[x]!=x:\n                uf[x]=find(uf[x])\n            return uf[x]\n        def union(x,y):\n            nonlocal groupId\n            gx,gy=find(x),find(y)\n            if gx==gy:\n                return\n            if gx in matchGroups:\n                matchGroups.remove(gx)\n            if gy in matchGroups:\n                matchGroups.remove(gy)\n            size=groupSize[find(x)]+groupSize[find(y)]\n            uf[find(x)]=find(y)\n            groupSize[find(x)]=size\n        cur=[0]*(len(arr)+2)\n        for i,num in enumerate(arr):\n            cur[num]=1\n            if cur[num-1]==1:\n                union(num,num-1)\n            if cur[num+1]==1:\n                union(num,num+1)\n            groupId=find(num)\n            if groupSize[find(num)]==m:\n                matchGroups.add(groupId)\n            if matchGroups:\n                res=i+1\n        return res", "class UnionFind:\n    def __init__(self, n):\n        self.roots = [i for i in range(n)]\n        self.sizes = [1 for i in range(n)]\n        \n    def root(self, a):\n        c = a\n        while self.roots[c] != c:\n            c = self.roots[c]\n        self.roots[a] = c                \n        return c\n    \n    def add(self, a, b):\n        a = self.root(a)\n        b = self.root(b)\n        if self.sizes[a] < self.sizes[b]:\n            a, b = b, a\n        self.roots[b] = a            \n        self.sizes[a] += self.sizes[b]\n            \nclass Solution:\n    def findLatestStep(self, arr: List[int], M: int) -> int:\n        uf = UnionFind(len(arr))\n        m = [0 for i in range(len(arr))]\n        good = set()\n        day = 1\n        result = -1            \n        for a in arr:\n            a -= 1\n            m[a] = 1\n            \n            if a > 0 and m[a-1] == 1:\n                if uf.root(a-1) in good:\n                    good.remove(uf.root(a-1))\n                uf.add(a, a-1)\n            if a < len(arr)-1 and m[a+1] == 1:\n                if uf.root(a+1) in good:\n                    good.remove(uf.root(a+1))\n                uf.add(a, a+1)\n            if uf.sizes[uf.root(a)] == M:\n                good.add(uf.root(a))\n            if good:\n                result = day\n            day += 1                \n        return result                \n            \n\n\n", "from sortedcontainers import SortedList\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if m == n:\n            return n\n        sl = SortedList([0, n+1])\n        for i in range(n-1, -1, -1):\n            a = arr[i]\n            up = sl.bisect(a)\n            if up != len(sl) and sl[up] - a - 1 == m:\n                return i\n            lp = up - 1\n            if lp >= 0 and a - sl[lp] - 1 == m:\n                return i\n            sl.add(a)\n        return -1", "from bisect import bisect_left\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -2\n        \n        groups = []\n        n = len(arr)\n        \n        m_cnt = 0\n        for step, x in enumerate(arr):\n            k = groups\n            if not groups:\n                groups.append([x,x])\n                if m == 1:\n                    m_cnt += 1\n            else:\n                gn = len(groups)\n                left = x\n                right = x\n                idx = bisect_left(groups, [x,x])\n                #print(step, x, idx, groups)\n\n                if idx < gn:\n                    if groups[idx][0] == x + 1:\n                        right = groups[idx][1]\n                        if groups[idx][1] - groups[idx][0] + 1 == m:\n                            m_cnt -= 1\n                        groups.pop(idx)\n                        \n\n                if idx - 1 >= 0:\n                    if groups[idx-1][1] == x - 1:\n                        left = groups[idx-1][0]\n                        if groups[idx-1][1] - groups[idx-1][0] + 1 == m:\n                            m_cnt -= 1\n                        groups.pop(idx-1)\n                        idx -= 1\n                \n                groups.insert(idx, [left, right])\n                if right - left + 1 == m:\n                    m_cnt += 1\n                \n            if m_cnt:\n                res = step\n            #print(x, groups)\n        return res + 1\n", "# class UnionFind:\n#     def __init__(self, n):\n#         self.parent = {}\n#         self.rank = [0] * (n+1)\n#         self.group_size = defaultdict(list)\n    \n#     def find(self, x):\n#         if x not in self.parent:\n#             self.parent[x] = x\n#             self.rank[x] = 1\n#             self.group_size[1].append(x)\n\nclass UnionFind:\n        def __init__(self, m, n):\n            self.m = m\n            self.parents = [i for i in range(n+1)]\n            # self.ranks = [1 for _ in range(n)]\n            self.group_size = defaultdict(set)\n            # self.group_size[1] = set([i+1 for i in range(n)])\n            self.sizes = defaultdict(int)\n            # for i in range(n):\n            #     self.sizes[i+1] = 1\n\n        def find(self, x):\n            if self.parents[x]!=x:\n                self.parents[x] = self.find(self.parents[x])\n            return self.parents[x]\n\n        def union(self, x, y):\n            root_x, root_y = self.find(x), self.find(y)\n            # print(\\\"x\\\", x ,\\\"y\\\", y)\n            # print(\\\"root_x\\\", root_x ,\\\"root_y\\\", root_y)\n            self.parents[root_x] = root_y\n            size_root_x = self.sizes[root_x]\n            self.sizes[root_x] = 0\n            self.group_size[size_root_x].remove(root_x)\n\n            size_root_y = self.sizes[root_y]\n            self.group_size[size_root_y].remove(root_y)\n            self.sizes[root_y] = size_root_y + size_root_x\n            self.group_size[self.sizes[root_y]].add(root_y)\n            \n            \n            # print(\\\"len(self.group_size[self.m])\\\", len(self.group_size[self.m]))\n            if len(self.group_size[self.m])>0:\n                return True\n            else:\n                return False\n            \n\nclass Solution:\n    ## my own solution: union find\n    ## mapping between sizes and positions\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(m, n)\n        # print(uf.group_size)\n        # print(uf.sizes)\n        seen = set()\n        res = -1\n        for idx, x in enumerate(arr):\n            seen.add(x)\n            uf.sizes[x] = 1\n            uf.group_size[1].add(x)\n            if x-1 in seen:\n                uf.union(x, x-1)\n                # if len(uf.group_size[m])>0:\n                #     res = idx+1\n            if x+1 in seen:        \n                uf.union(x+1, x)\n                \n            if len(uf.group_size[m])>0:\n                res = idx+1\n            # print(\\\"uf.group_size\\\", uf.group_size)\n            # print(\\\"uf.sizes\\\", uf.sizes)\n        return res\n            \n", "class UF:\n    def __init__(self):\n        self.p = {}\n        self.m = {}\n\n    def find_make_set(self, x):\n        if not x in self.p:\n            self.p[x] = None\n            self.m[x] = 1\n            return x\n        \n        if self.p[x] is None:\n            return x\n        return self.find_make_set(self.p[x])\n    \n    def union(self, a, b):\n        repa = self.find_make_set(a)\n        repb = self.find_make_set(b)\n        if repa != repb:\n            self.p[repb] = repa\n            self.m[repa] += self.m[repb]\n        return repa\n\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n\n        n = len(arr)\n        ones = {}\n        ans = -1\n        uf = UF()\n\n        import collections\n        cnt = collections.defaultdict(int)\n        for i, a in enumerate(arr):\n            ones[a] = 1\n            uf.find_make_set(a)\n            cnt[1] += 1\n\n            if a - 1 >= 1 and a-1 in ones:\n                rep = uf.find_make_set(a-1)\n                cnt[uf.m[rep]] -= 1\n\n                cnt[1] -= 1\n\n                rep = uf.union(a-1, a)\n                cnt[uf.m[rep]] += 1\n\n            if a + 1 <= n and a+1 in ones:\n                rep = uf.find_make_set(a+1)\n                cnt[uf.m[rep]] -= 1\n\n                rep = uf.find_make_set(a)\n                cnt[uf.m[rep]] -= 1\n\n                rep = uf.union(a+1, a)\n                cnt[uf.m[rep]] += 1\n\n            if cnt[m] > 0:\n                ans = i + 1\n\n        return ans\n\n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans\n    \n        d = set([0,len(arr) + 1])\n        if m == len(arr): return m\n        for i in range(len(arr)-1,-1,-1):\n            if arr[i] - m-1 in d:\n                exit = True\n                for j in range(arr[i] -m,arr[i]):\n                    if j in d:\n                        exit = False\n                        break\n                if exit:\n                    return i\n            if arr[i] + m+1 in d:\n                exit = True\n                for j in range(arr[i]+1,arr[i]+m+1):\n                    if j in d:\n                        exit = False\n                        break\n                if exit:\n                    return i\n            d.add(arr[i])\n        \n        return -1\n                \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n\n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n\n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        '''\n        length_dict = {}\n        \n        length_edge = [0]*len(arr)\n        \n        result = -1\n        \n        for i in range(len(arr)):\n            index = arr[i] - 1\n            \n            left_length = 0\n            right_length = 0\n            if index>0:\n                left_length = length_edge[index - 1]\n            if index<len(arr)-1:\n                right_length = length_edge[index + 1]\n            length_edge[index+right_length] = 1 + left_length + right_length\n            length_edge[index-left_length] = 1 + left_length + right_length\n            \n            if left_length in length_dict:\n                length_dict[left_length] -= 1\n            if right_length in length_dict:\n                length_dict[right_length] -= 1\n            if 1 + left_length + right_length not in length_dict:\n                length_dict[1 + left_length + right_length] = 0\n            length_dict[1 + left_length + right_length] += 1\n            \n            if m in length_dict and length_dict[m]>0:\n                result = i + 1\n        return result\n        '''\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        groups = {}\n        groups[0] = len(arr)\n        \n        result = -1\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            \n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    '''\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    '''\n                    groups[uf.ranks[uf.find(j)]] -= 1\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n            \n            if uf.ranks[uf.find(i)] == m:\n                ans = step + 1\n            group = uf.ranks[uf.find(i)]\n            if group not in groups:\n                groups[group] = 0\n            groups[group] += 1\n            if m in groups and groups[m]>0:\n                result = step + 1\n        '''\n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n        return ans\n        '''\n        \n        return result\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dsu = DSU()\n        ans = -1\n        visited = set()\n        previous_index = []\n        for i, num in enumerate(arr):\n            visited.add(num)\n            if num - 1 in visited:\n                dsu.union(num, num - 1)\n            if num + 1 in visited:\n                dsu.union(num, num + 1)\n            \n            current_index = [i for i in previous_index if dsu.getCount(i) == m]\n            previous_index = current_index\n            \n            if dsu.getCount(num) == m:\n                current_index.append(num)\n            \n            if previous_index:\n                ans = i + 1\n                \n        return ans\n            \n\nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = {}\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = _b\n            self.count[_b] += self.count[_a]\n    \n    def getCount(self, a):\n        return self.count[self.find(a)]\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        size = [0] * (n + 2)\n        size_count = [0] * (n + 1)\n        res = -1\n        for step, num in enumerate(arr):\n            left, right = size[num - 1], size[num + 1]\n            size[num] = size[num - left] = size[num + right] = left + right + 1\n            size_count[left] -= 1\n            size_count[right] -= 1\n            size_count[size[num]] += 1\n            if size_count[m]:\n                res = max(res, step + 1)\n        return res", "from sortedcontainers import SortedList\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sizes = Counter((len(arr),))\n        groups = SortedList([[1, len(arr)]])\n        for i in range(len(arr)-1, -1, -1):\n            if m in sizes:\n                return i + 1\n            n = arr[i]\n            j = groups.bisect_left([n, n]) \n            if j == len(groups) or j > 0 and groups[j-1][1] >= n:\n                j -= 1\n            h, t = groups.pop(j)\n            sizes[t - h + 1] -= 1\n            if h < n: \n                groups.add([h, n-1])\n                sizes[n-1 - h + 1] += 1 \n            if t > n:    \n                groups.add([n+1, t])\n                sizes[t - n - 1 + 1] += 1 \n        return -1        ", "class UnionFind:\n    def __init__(self):\n        self.parents = defaultdict(lambda:-1)\n        self.ranks = defaultdict(lambda:1)\n    def join(self, a, b):\n        pa, pb = self.find(a), self.find(b)\n        if pa == pb:\n            return\n        if self.ranks[pa] > self.ranks[pb]:\n            self.parents[pb] = pa\n            self.ranks[pa] += self.ranks[pb]\n        else:\n            self.parents[pa] = pb\n            self.ranks[pb] += self.ranks[pa]\n    def find(self, a):\n        if self.parents[a] == -1:\n            return a\n        self.parents[a] = self.find(self.parents[a])\n        return self.parents[a]\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UnionFind()\n        cnt=0\n        ret=-1\n        lst = [0]*len(arr)\n        for idx,i in enumerate(arr):\n            i-=1\n            lst[i]=1\n            if i-1>=0 and lst[i-1]:\n                if uf.ranks[uf.find(i-1)]==m:\n                    cnt-=1\n                uf.join(i,i-1)\n            if i+1<len(lst) and lst[i+1]:\n                if uf.ranks[uf.find(i+1)]==m:\n                    cnt-=1\n                uf.join(i,i+1)\n            if uf.ranks[uf.find(i)]==m:\n                cnt+=1\n            if cnt>0:\n                ret=idx+1\n        return ret", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans\n                \n                \n                \n                \n                \n", "class Node:\n    def __init__(self, left, right):\n        \n        self.leftvalue = left\n        self.rightvalue = right        \n        self.nextleft = None\n        self.nextright = None\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        n = len(arr)\n        \n        root = Node(1, n)\n        \n        chk = False\n                \n        def dfs(u, node):\n            \n            # nonlocal ans\n            nonlocal chk\n            nonlocal m\n            \n            # print (u, node.leftvalue, node.rightvalue)\n            \n            if chk:\n                return\n            \n            if not node.nextleft and not node.nextright:\n                \n                # print ('x')\n                \n                if u == node.leftvalue:\n                    node.leftvalue += 1\n                    \n                    if node.rightvalue - node.leftvalue + 1 == m:\n                        chk = True\n                    \n                    return\n                \n                if u == node.rightvalue:\n                    node.rightvalue -= 1\n                    \n                    if node.rightvalue - node.leftvalue + 1 == m:\n                        chk = True\n                    \n                    return\n                \n                \n                if u - node.leftvalue == m or node.rightvalue - u == m:\n                    chk = True\n                    return\n                \n                node.nextleft = Node(node.leftvalue, u - 1)\n                node.nextright = Node(u + 1, node.rightvalue)\n\n                \n                return\n            \n            \n            if node.nextleft.leftvalue <= u <= node.nextleft.rightvalue:\n                dfs(u, node.nextleft)\n            elif node.nextright.leftvalue <= u <= node.nextright.rightvalue:\n                dfs(u, node.nextright)\n        \n        \n        if m == len(arr):\n            return n\n        \n        # if arr == sorted(arr):\n        #     return m\n        \n        ans = n\n        for i in range(len(arr) - 1, -1, -1):\n            \n            dfs(arr[i], root)\n            ans -= 1\n            \n            if chk:\n                return ans\n            \n        return -1\n                \n", "from sortedcontainers import SortedSet\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        # 11111 -> 11101\n        # [(start, end)]  , (1,5) => (1,3), 4, (5,5)\n        ans = n\n        if m == n:\n            return ans\n        ss = SortedSet([(1, n)])\n        s0 = set()\n        # print(ss)\n        # 1110 1111\n        \n        for i in range(n-1, -1, -1):\n            v = arr[i]\n            i_itv = ss.bisect_right((v,n)) - 1\n            # print(\\\"idx:\\\", i_itv)\n            start, end = ss[i_itv]\n            # print(start, end, \\\"v:\\\",v)\n            if (v-start == m) or (end-v == m):\n                return i\n            ss.discard((start,end))\n            if v-1 >= start:\n                ss.add((start,v-1))\n            if end >= v+1:\n                ss.add((v+1,end))\n            # print(ss)\n        \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m:\n            return m\n        \n        intervals = [[1, len(arr)]]\n        \n        for i in range(len(arr)-1, -1, -1):\n            remove = arr[i]\n            l, r = 0, len(intervals)-1\n            while l <= r:\n                mid = l + (r - l)//2\n                if intervals[mid][0] > remove:\n                    r = mid - 1\n                else:\n                    l = mid + 1\n            interval = list(intervals[r])\n            if interval[0] == remove:\n                intervals[r][0] = intervals[r][0] + 1\n                if intervals[r][1] - intervals[r][0] + 1 == m:\n                    return i\n            elif interval[1] == remove:\n                intervals[r][1] = intervals[r][1] - 1\n                if intervals[r][1] - intervals[r][0] + 1 == m:\n                    return i\n            else:\n                intervals.insert(r, list(interval))\n                intervals[r][1] = remove - 1\n                intervals[r+1][0] = remove + 1\n                if (intervals[r][1] - intervals[r][0] + 1 == m) or (intervals[r+1][1] - intervals[r+1][0] + 1 == m):\n                    return i\n        return -1\n                \n            \n            \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        if m == n:\n            return m\n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n            if uf.ranks[i] == m == 1 and uf.parents[i] == i:\n                ans = step + 1\n            # print(step, i, uf.ranks, ans)\n        return ans", "class Union_find:\n    def __init__(self, MAX: int,target):\n        self.fa = [i for i in range(MAX)]\n        self.cnt = [1 for _ in range(MAX)]\n        self.exist = 0\n        self.target = target\n        self.root_map = collections.defaultdict(set)\n\n    def find(self, u: int) -> int:\n        if self.fa[u] == u:\n            return u\n\n        self.fa[u] = self.find(self.fa[u])\n        return self.fa[u]\n\n    def union(self, u: int, v: int):\n        u, v = self.find(u), self.find(v)\n        if u == v:\n            return None\n\n        if self.cnt[u] < self.cnt[v]:\n            u, v = v, u\n        vn = int(self.cnt[v])\n        un = int(self.cnt[u])\n        try:\n            self.root_map[vn].remove(v)\n        except:\n            pass\n        self.cnt[u] = vn + un\n        try:\n            self.root_map[un].remove(u)\n        except:\n            pass\n        self.root_map[vn+un].add(u)\n        self.fa[v] = u\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ct = 0\n        l = [0 for i in arr]\n        n = 0\n        res = -1\n        uf = Union_find(len(arr),m)\n        for i in arr:\n            l[i-1] = 1\n            ct += 1\n            flag = False\n            if i-2>-1 and l[i-2] == 1:\n                uf.union(i-1,i-2)\n                flag = True\n            if i<len(arr) and l[i] == 1:\n                uf.union(i-1,i)\n                flag = True\n            if not flag:\n                uf.root_map[1].add(i-1)\n            if len(uf.root_map[m])>0:\n                res = ct\n        return res", "import collections\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dic={}\n        n=len(arr)\n        for i in range(1,n+1):\n            dic[i]=(-1,-1,0)\n        res=-1    \n        memo=collections.defaultdict(int)\n        for i in range(n):\n            left=arr[i]\n            right=arr[i]\n            l=1\n            if arr[i]+1<=n and dic[arr[i]+1][2]!=0:\n                right=dic[arr[i]+1][1]\n                l+=dic[arr[i]+1][2]\n                memo[dic[arr[i]+1][2]]-=1\n                \n            if arr[i]-1>=1 and dic[arr[i]-1][2]!=0:\n                left=dic[arr[i]-1][0]\n                l+=dic[arr[i]-1][2]\n                memo[dic[arr[i]-1][2]]-=1\n                \n            for x in [left, right]:\n                dic[x]=(left, right, l)  \n            memo[l]+=1\n            if memo[m]>0: res=i+1\n            \n        return res\n        \n                \n                \n                \n            \n       \n            \n            \n", "from sortedcontainers import SortedDict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        a = [0] * n\n        for i in arr:\n            a[i-1] = 1\n        last = -1\n        lastcnt = 0\n        parentcnts = SortedDict()\n        for i, val in enumerate(a):\n            if val == 1:\n                if i == 0 or a[i-1] == 0:\n                    last = i\n                    lastcnt = 0\n                    parentcnts[i] = 0\n                lastcnt += 1\n                parentcnts[last] += 1\n        for key in parentcnts:\n            if parentcnts[key] == m:\n                return n\n        \n        for x in range(n-1, -1, -1):\n            # print(parentcnts)\n            ind = arr[x] - 1\n            leftone, rightone = True, True\n            if ind == 0 or a[ind-1] == 0:\n                leftone = False\n            if ind == n-1 or a[ind+1] == 0:\n                rightone = False\n            if not leftone and not rightone:\n                parentcnts.pop(ind)\n                continue\n            if not leftone:\n                parentcnts[ind + 1] = parentcnts[ind] - 1\n                parentcnts.pop(ind)\n                if m == parentcnts[ind + 1]:\n                    return x\n                continue\n            \n            ins_ind = parentcnts.peekitem( parentcnts.bisect_right(ind) - 1 )[0]\n            if not rightone:\n                parentcnts[ins_ind] -= 1\n                if m == parentcnts[ins_ind]:\n                    return x\n                continue\n            \n            parentcnts[ind + 1] = parentcnts[ins_ind] - (ind - ins_ind + 1)\n            parentcnts[ins_ind] = ind - ins_ind\n            if m == parentcnts[ind + 1] or m == parentcnts[ins_ind]:\n                return x\n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        self.m = m\n        n = len(arr)\n        self.parents = [i for i in range(n + 1)]\n        self.grpcounts = {}\n        self.countMgrps = 0\n        \n        last = -1\n        for step, pos in enumerate(arr):\n            self.grpcounts[pos] = 1\n            if m == 1:\n                self.countMgrps += 1\n            \n            if pos + 1 <= n and self.find(pos + 1) in self.grpcounts:\n                self.union(pos, pos + 1)\n            if pos - 1 > 0 and self.find(pos - 1) in self.grpcounts:\n                self.union(pos, pos - 1)\n            \n            # print(self.countMgrps)\n            if self.countMgrps > 0:\n                last = step + 1\n        \n        return last\n        \n        \n    def find(self, pos):\n        path = []\n        while pos != self.parents[pos]:\n            path.append(pos)\n            pos = self.parents[pos]\n        \n        for p in path:\n            self.parents[p] = pos\n        \n        return pos\n    \n    \n    def union(self, a, b):\n        p1 = self.find(a)\n        p2 = self.find(b)\n        if p1 != p2:\n            self.parents[p1] = p2\n            if self.grpcounts[p1] == self.m:\n                self.countMgrps -= 1\n            if self.grpcounts[p2] == self.m:\n                self.countMgrps -= 1\n            \n            self.grpcounts[p2] += self.grpcounts[p1]\n            if self.grpcounts[p2] == self.m:\n                self.countMgrps += 1\n            \n            del self.grpcounts[p1]\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        p = list(range(n))\n        size = [0]*n\n\n        def find(x):\n            if x!=p[x]:\n                p[x] = find(p[x])\n            return p[x]\n\n        def union(x,y):\n            px,py = find(x),find(y)\n            if px == py:\n                return False\n            if size[px]>size[py]:\n                p[py] = px\n                size[px]+=size[py]\n            else:\n                p[px] =py\n                size[py] += size[px]\n            return True\n\n        if m == len(arr):\n            return m\n        ans = -1\n        for step,i in enumerate(arr):\n            i -= 1\n            \n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[find(j)]==m:\n                        ans = step\n            size[i] = 1\n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[j]:\n                        union(i,j)\n        return ans\n    \n    # 4 1 3\n    # 4 5 8\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr): return m\n        groups = {}\n        result = -1\n        for i, a in enumerate(arr):\n            b = a - 1\n            if b in groups:\n                l = groups.pop(b)\n                groups[a] = groups[b - l + 1] = l + 1\n            else:\n                groups[a] = 1\n            if groups[a] - 1 == m:\n                result = i\n            c = a + 1\n            if c in groups:\n                l = groups.pop(a)\n                r = groups.pop(c)\n                groups[c + r - 1] = groups[a - l + 1] = l + r\n                if r == m:\n                    result = i\n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        \n        if m == len(arr):\n            return m\n        \n        def find(vals, index):\n            if vals[index] != -1:\n                vals[index] = find(vals, vals[index])\n                return vals[index]\n            else:\n                return index\n        \n        # def union(vals, a, b):\n        #     root_a = find(vals, a)\n        #     root_b = find(vals, b)\n        #     if root_a < root_b:\n        #         vals[root_b] = root_a\n        #     else:\n        #         vals[root_a] = root_b\n        \n        def unionStart(a, b):\n            root_a = find(start, a)\n            root_b = find(start, b)\n            if root_a < root_b:\n                start[root_b] = root_a\n            else:\n                start[root_a] = root_b\n        \n        def unionEnd(a, b):\n            root_a = find(end, a)\n            root_b = find(end, b)\n            if root_a > root_b:\n                end[root_b] = root_a\n            else:\n                end[root_a] = root_b\n        \n        def getLength(index):\n            start_curr = find(start, index)\n            end_curr = find(end, index)\n            return end_curr - start_curr + 1\n            \n        res = -1\n        nums = [0 for i in range(len(arr))]\n        start = [-1 for i in range(len(arr))]\n        end = [-1 for i in range(len(arr))]\n        mem = dict() # start, length\n        lengths = collections.Counter()\n        for i in range(len(arr)):\n            index = arr[i] - 1\n            # print(index)\n            nums[index] += 1\n            # found group of m\n            # check left\n            if index > 0 and nums[index - 1] == 1:\n                # union find start\n                old_length = getLength(index - 1)\n                lengths[old_length] -= 1\n                unionStart(index - 1, index)\n                unionEnd(index - 1, index)\n                \n            # check right\n            if index < len(arr) - 1 and nums[index + 1] == 1:\n                old_length = getLength(index + 1)\n                lengths[old_length] -= 1\n                unionStart(index, index + 1)\n                unionEnd(index, index + 1)\n                \n            start_curr = find(start, index)\n            end_curr = find(end, index)\n            # print(start)\n            # print(end, start_curr, end_curr)\n            length = getLength(index)\n            # plus 1\n            lengths[length] += 1\n            if lengths[m] > 0:\n                res = i + 1\n            # print(lengths)\n        return res", "from collections import Counter\nclass DSU:\n    def __init__(self, n):\n        self.dic = [i for i in range(n)]\n    def find(self, n1):\n        if self.dic[n1] != n1:\n            self.dic[n1] = self.find(self.dic[n1])\n        return self.dic[n1]\n    def union(self, n1, n2):\n        s1 = self.find(n1)\n        s2 = self.find(n2)\n        self.dic[s2] = s1\n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        cnt = Counter()        \n        area = Counter()\n        fliped = [False for _ in arr]\n        dsu = DSU(len(arr))        \n        res = []\n        for i, b in enumerate(arr):\n            b -= 1\n            fliped[b] = True             \n            bl = 1\n            if b > 0 and fliped[b - 1]:\n                s = dsu.find(b - 1)\n                sa = area[s] \n                cnt[sa] -= 1\n                dsu.union(s, b)\n                bl += sa\n            if b < len(arr) - 1 and fliped[b + 1]:\n                s = dsu.find(b + 1)\n                sa = area[s] \n                cnt[sa] -= 1\n                dsu.union(s, b)\n                bl += sa     \n            s = dsu.find(b)\n            area[s] = bl\n            cnt[bl] += 1\n            if cnt[m] > 0:\n                res.append(i)\n        # print(res)\n        return res[-1] + 1 if res else -1\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        import numpy as np\n        def max_rolling1(a, window,axis =1):\n            shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)\n            strides = a.strides + (a.strides[-1],)\n            rolling = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)\n            return np.max(rolling,axis=axis)\n        \n        n=len(arr)\n        L=[0]*n\n        for i in range(n):\n            L[arr[i]-1]=i\n            \n        A =np.array(L)\n        K = m\n        RM=(max_rolling1(A,K))\n        hh=-1\n        if m==n:\n            return n\n        for i in range(n-m+1):\n            temp =[L[x] for x in [i-1, i+m] if x in range(n)]\n            \n            if min(temp)>RM[i]:\n                hh=max(hh, min(temp))\n        return hh", "class Union_Find():\n    def __init__(self):\n        self.father = {}\n        self.count = collections.defaultdict(int)\n    \n    def find(self, a):\n        if self.father[a] == a:\n            return a\n        self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        father_a = self.find(a)\n        father_b = self.find(b)\n        if father_a != father_b:\n            self.father[father_b] = father_a\n            self.count[father_a] += self.count[father_b]\n\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = Union_Find()\n        result = -1\n        for i in range(len(arr)):\n            uf.father[arr[i]] = arr[i]\n            uf.count[arr[i]] = 1\n            if arr[i] - 1 in uf.father:\n                if uf.count[uf.find(arr[i] - 1)] == m:\n                    result = i\n                uf.union(arr[i], arr[i] - 1)\n            if arr[i] + 1 in uf.father:\n                if uf.count[uf.find(arr[i] + 1)] == m:\n                    result = i\n                uf.union(arr[i], arr[i] + 1)\n        n = len(arr)\n        for i in range(n):\n            if uf.count[uf.find(i + 1)] == m:\n                return n\n        return result\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        a = [x - 1 for x in arr]\n        n = len(a)\n        parent = list(range(n))\n        size = [0] * n\n        count = Counter()\n\n        def find(u):\n            if parent[u] != u:\n                parent[u] = find(parent[u])\n            return parent[u]\n\n        def union(u, v):\n            x, y = find(u), find(v)\n            if x != y:\n                parent[y] = x\n                size[x] += size[y]\n\n        res = -1\n        bits = [0] * n\n\n        for i, u in enumerate(a, 1):\n            bits[u] = 1\n            size[u] = 1\n            count[1] += 1\n            if u > 0 and bits[u - 1]:\n                count[size[find(u - 1)]] -= 1\n                union(u - 1, u)\n            if u + 1 < n and bits[u + 1]:\n                count[size[find(u + 1)]] -= 1\n                union(u, u + 1)\n            if size[find(u)] != 1:\n                count[1] -= 1\n                count[size[find(u)]] += 1\n            if count[m] > 0:\n                res = i\n            # print(i, size)\n            # print(i, count)\n\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        ends, starts = {}, {}\n        last_found = -1\n        \n        for ind, val in enumerate(arr):\n            left = val - 1 if val - 1 in ends else None\n            right = val + 1 if val + 1 in starts else None\n            \n            if left and right:\n                length1, length2 = left - ends[left], starts[right] - right\n                if length1 == m - 1 or length2 == m - 1:\n                    last_found = ind\n                l, r = ends[left], starts[right]\n                starts[l], ends[r] = r, l\n                del ends[left]\n                del starts[right]\n            elif left:\n                length = left - ends[left]\n                if length == m - 1:\n                    last_found = ind\n                ends[val] = ends[left]\n                starts[ends[left]] = val\n                del ends[left]\n            elif right:\n                length = starts[right] - right\n                if length == m - 1:\n                    last_found = ind\n                starts[val] = starts[right]\n                ends[starts[right]] = val\n                del starts[right]\n            else:\n                starts[val] = val\n                ends[val] = val\n        return last_found\n", "from bisect import *\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = len(arr)\n        arr = [i - 1 for i in arr]\n        p = [i for i in range(len(arr))]\n        gsize = [0 for _ in range(len(arr))]\n        \n        def fp(n):\n            nonlocal p\n            if n == p[n]:\n                return p[n]\n            else:\n                p[n] = fp(p[n])\n                return p[n]\n            \n        def gs(n):\n            return gsize[fp(n)]\n        \n        ms = set()\n        def uu(a, b):\n            nonlocal ms\n            pa = fp(a)\n            pb = fp(b)\n            \n            \n            if gs(pa) == m:\n                ms.add(pa)\n            if gs(pb) == m:\n                ms.add(pb)\n                \n            if pa == pb:\n                return\n            try:\n                ms.remove(pa)\n            except:\n                pass\n            try:\n                ms.remove(pb)\n            except:\n                pass\n            \n            gsize[pb] += gsize[pa]\n            p[pa] = p[pb]\n            if gs(pb) == m:\n                ms.add(pb)\n            \n        \n        filled = set()\n        ans = -2\n        for i, n in enumerate(arr):\n            gsize[n] = 1\n            uu(n, n)\n            if n > 0 and n - 1 in filled:\n                uu(n, n - 1)\n                \n                \n            if n < N - 1 and n + 1 in filled:\n                uu(n, n + 1)\n\n            filled.add(n)\n            if len(ms) > 0:\n                ans = i\n        return ans + 1\n                \n        \n", "from collections import defaultdict\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        parent = {}\n        rank = defaultdict(int)\n        size = {}\n        \n        def find(x):\n            if x != parent[x]:\n                parent[x] = find(parent[x])\n            return parent[x]\n    \n        def union(x, y):\n            nx, ny = find(x), find(y)\n            \n            if nx == ny:\n                return False\n            \n            if rank[nx] > rank[ny]:\n                parent[ny] = nx\n                size[nx] += size[ny]\n                return size[nx]\n            elif rank[nx] > rank[ny]:\n                parent[nx] = ny\n                size[ny] += size[nx]\n                return size[ny]\n            else:\n                parent[nx] = ny\n                rank[ny] += 1\n                size[ny] += size[nx]\n                return size[ny]\n        \n        seen = set()\n        last = -1\n        size_counts = Counter()\n        \n        for i, num in enumerate(arr):\n            parent[num] = num\n            size[num] = 1\n            if num - 1 in seen and num + 1 in seen:\n                size_counts[size[find(num - 1)]] -= 1\n                size_counts[size[find(num + 1)]] -= 1\n                union(num - 1, num)\n                res = union(num + 1, num)\n                size_counts[res] += 1\n            elif num - 1 in seen:\n                size_counts[size[find(num - 1)]] -= 1\n                res = union(num - 1, num)\n                size_counts[res] += 1\n            elif num + 1 in seen:\n                size_counts[size[find(num + 1)]] -= 1\n                res = union(num + 1, num)\n                size_counts[res] += 1\n            else:\n                size_counts[size[num]] += 1\n\n            if m in size_counts and size_counts[m] > 0:\n                last = i + 1\n            # for _, l in parent.items():\n            #     if size[find(l)] == m:\n            #         last = i + 1\n\n            seen.add(num)\n        return last\n        \n", "import collections\n\nclass Union:\n    \n    def __init__(self):\n        self.parent = {}\n        self.rank = {}\n        self.rank_count = collections.Counter()\n        self.count = 0\n        \n    def add(self, pos):\n        self.parent[pos] = pos\n        self.rank[pos] = 1\n        self.rank_count[1] += 1\n        self.count += 1\n    \n    def find(self, pos): #recursively find parent\n        if self.parent[pos] != pos:\n            self.parent[pos] = self.find(self.parent[pos])\n        return self.parent[pos]\n    \n    def unite(self, p, q):\n        i, j = self.find(p), self.find(q)\n        if i == j:\n            return\n        if self.rank[i] > self.rank[j]:\n            i, j = j, i\n        self.parent[i] = j # i is smaller tree, attach it to larger tree j with j as parent\n        self.rank_count[self.rank[j]] -= 1\n        self.rank_count[self.rank[i]] -= 1\n        self.rank[j] += self.rank[i]\n        self.rank_count[self.rank[j]] += 1\n        self.count -= 1\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res = -1\n        bi = Union()\n        for step, idx in enumerate(arr, 1):\n            bi.add(idx)\n            for neighbor in (idx + 1), (idx - 1):\n                if neighbor in bi.parent:\n                    bi.unite(idx, neighbor)\n            if bi.rank_count.get(m, 0) > 0:  res = step\n        return res\n", "class DS:\n    def __init__(self):\n        self.intervals = {}\n        self.par = {}\n        self.all_vals = {}\n        \n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def query(self, x):\n        px = self.find(x)\n        x, y = self.intervals[px]\n        return y - x + 1\n    \n    def add(self, x, m):\n        self.par[x] = x\n        self.intervals[x] = [x,x]\n        \n        if 1 not in self.all_vals:\n            self.all_vals[1] = 0\n        self.all_vals[1] += 1\n        \n        if x+1 in self.par:\n            px = self.find(x)\n            py = self.find(x+1)\n            y1,y2 = self.intervals[py]\n            x1,x2 = self.intervals[px]\n            self.par[py] = px\n            x, y = min(x1,y1), max(x2,y2)\n            self.intervals[px] = [x, y]\n            \n            self.all_vals[y2 - y1 + 1] -= 1\n            self.all_vals[x2 - x1 + 1] -= 1\n            if y - x + 1 not in self.all_vals:\n                self.all_vals[y - x + 1] = 0\n            self.all_vals[y - x + 1] += 1\n            \n        if x-1 in self.intervals:\n            px = self.find(x)\n            py = self.find(x-1)\n            y1,y2 = self.intervals[py]\n            x1,x2 = self.intervals[px]\n            self.par[py] = px\n            x, y = min(x1,y1), max(x2,y2)\n            self.intervals[px] = [x, y]\n            \n            self.all_vals[y2 - y1 + 1] -= 1\n            self.all_vals[x2 - x1 + 1] -= 1\n            if y - x + 1 not in self.all_vals:\n                self.all_vals[y - x + 1] = 0\n            self.all_vals[y - x + 1] += 1\n            \n            \n        return m in self.all_vals and self.all_vals[m] > 0\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ds = DS()\n        ans = -1\n        for i,num in enumerate(arr):\n            if ds.add(num, m):\n                ans = i+1\n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UnionFind(n + 1, m)\n        ans = -1\n        for i, a in enumerate(arr):\n            a = arr[i]\n            uf.add(a)\n            if a > 1: uf.union(a, a - 1)\n            if a < n: uf.union(a, a + 1)\n            if uf.cnt > 0:\n                ans = i + 1\n        return ans\n        \n        \nclass UnionFind:\n    def __init__(self, n, m):\n        self.id = [-1 for _ in range(n)]\n        self.size = [0 for _ in range(n)]\n        self.cnt = 0\n        self.m = m\n        \n    def add(self, i):\n        self.id[i] = i\n        self.size[i] = 1\n        if self.get_size(i) == self.m:\n            self.cnt += 1\n        \n    def find(self, i):\n        if self.id[i] == -1:\n            return -1\n        root = i\n        while root != self.id[root]:\n            root = self.id[root]\n        while root != i:\n            j = self.id[i]\n            self.id[i] = root\n            i = j\n        return root\n    \n    def union(self, i, j):\n        root_i = self.find(i)\n        root_j = self.find(j)\n        if root_i < 0 or root_j < 0 or root_i == root_j:\n            return\n        if self.get_size(i) == self.m:\n            self.cnt -= 1\n        if self.get_size(j) == self.m:\n            self.cnt -= 1\n        if self.size[root_i] < self.size[root_j]:\n            self.id[root_i] = root_j\n            self.size[root_j] += self.size[root_i]\n        else:\n            self.id[root_j] = root_i\n            self.size[root_i] += self.size[root_j]\n        if self.get_size(root_i) == self.m:\n            self.cnt += 1\n    \n    def get_size(self, i):\n        return self.size[self.find(i)]", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        counts = [0]*(len(arr)+1)\n        root = [i for i in range(len(arr))]\n        size = [0 for i in range(len(arr))]\n        rank = [1 for i in range(len(arr))]\n        def find(i):\n            if root[i-1] != i-1:\n                root[i-1] = find(root[i-1]+1)\n            return root[i-1]\n        def union(i,j):\n            pi = find(i)\n            pj = find(j)\n            length = size[pi]+size[pj]\n            if pi != pj:\n                if rank[pi] <= rank[pj]:\n                    root[pi] = pj\n                    if rank[pi] == rank[pj]:\n                        rank[pj] += 1\n                else:\n                    root[pj] = pi\n                size[root[pi]] = length\n        step = -1\n        for i in range(len(arr)):\n            size[arr[i]-1] += 1\n            if arr[i] - 1 != 0 and size[find(arr[i]-1)] != 0:\n                counts[size[find(arr[i]-1)]] -= 1\n                union(arr[i]-1, arr[i])\n            if arr[i] + 1 != len(arr)+1 and size[find(arr[i]+1)] != 0:\n                counts[size[find(arr[i]+1)]] -= 1\n                union(arr[i]+1, arr[i])\n            counts[size[find(arr[i])]] += 1\n            if counts[m] != 0:\n                step = i+1\n        return step", "from sortedcontainers import SortedList\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        zeros = SortedList()\n        zeros.add(0)\n        zeros.add(len(arr) + 1)\n        if len(arr) == m:\n            return len(arr)\n        for inverse_step, i in enumerate(arr[::-1], 1):\n            head = zeros.bisect_left(i)\n            # print(zeros, i, zeros.bisect_left(i), zeros.bisect_right(i))\n            if  i - zeros[head - 1] - 1 == m:\n                print((len(arr), inverse_step))\n                return len(arr) - inverse_step\n            \n            tail = zeros.bisect_right(i)\n            if  zeros[tail] - i - 1 == m:\n                # print(len(arr), inverse_step)\n                return len(arr) - inverse_step\n            \n            zeros.add(i)\n        return -1\n                \n        \n        \n#         def is_length_existed(string):\n#             last_zero = -1\n#             for i, bit in string:\n#                 if bit == 1:\n#                     continue\n#                 ones = i - last_zero\n#                 if ones == m:\n#                     return True\n#                 last_zero = i\n#             return False\n        \n#         def build(t):\n#             string = [0] * len(arr)\n#             for i in arr[:t]:\n#                 string[i-1] = 1\n        \n#         p, q = 1, len(arr)\n#         while p < q:\n#             mid = (p + q) >> 1\n#             string = build(mid)\n#             if is_length_existed(string):\n#                 p = mid\n#             else:\n#                 q = mid - 1\n            \n            \n            \n                    \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        \n        res = -1\n        length = [0] * (n + 2)\n        count = [0] * (n + 1)\n        for i in range(n):\n            b = arr[i]\n            \n            left, right = length[b - 1], length[b + 1]\n            \n            length[b] = length[b - left] = length[b + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[b]] += 1\n            \n            if count[m] > 0:\n                res = i + 1\n        \n        return res\n            \n            \n            \n            \n        \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = {}\n        cnt = Counter()\n\n        def find(x):\n            if uf[x][0] != x:\n                uf[x][0] = find(uf[x][0])[0]\n            uf[x][1] = uf[uf[x][0]][1]\n            return uf[x]\n\n        def union(x, y):\n            t1, t2 = find(y)[1], find(x)[1]\n            cnt[t1] -= 1\n            cnt[t2] -= 1\n            uf[find(x)[0]][1] += t1\n            uf[find(y)[0]][1] += t2\n            uf[find(x)[0]][0] = find(y)[0]\n            cnt[find(y)[1]] += 1\n\n        seen = [0] * (len(arr) + 1)\n        n = len(arr)\n        ans = -1\n        for i, a in enumerate(arr, 1):\n            seen[a] = 1\n            uf.setdefault(a, [a, 1])\n            cnt[1] += 1\n            if a > 1 and seen[a - 1]:\n                union(a, a - 1)\n            if a < n and seen[a + 1]:\n                union(a, a + 1)\n            if cnt[m]:\n                ans = i\n        return ans\n                \n                \n                \n                \n                \n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [0] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n, ans = len(arr), -1\n        uf = UnionFindSet(n)\n        \n        for step, i in enumerate(arr):\n            i -= 1\n            uf.ranks[i] = 1\n            for j in (i - 1, i + 1):\n                if 0 <= j < n:\n                    if uf.ranks[uf.find(j)] == m:\n                        ans = step\n                    if uf.ranks[j]:\n                        uf.union(i, j)\n        \n        for i in range(n):\n            if uf.ranks[uf.find(i)] == m:\n                return n\n            \n        return ans\n\n", "import bisect\nimport collections\nfrom typing import List\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        intervals=[]\n        lengths=collections.defaultdict(int)\n        ans=-1\n        for step,x in enumerate(arr):\n            ind=bisect.bisect(intervals,[x,x])\n            intervals.insert(ind,[x,x])\n            lengths[1]+=1\n            merge_left=merge_right=ind\n            if ind-1>=0 and intervals[ind-1][1]==x-1:\n                merge_left=ind-1\n            if ind+1<len(intervals) and intervals[ind+1][0]==x+1:\n                merge_right=ind+1\n            # print(intervals)\n            if merge_right>merge_left:\n                for i in range(merge_left, merge_right + 1):\n                    lengths[intervals[i][1] - intervals[i][0] + 1] -= 1\n                lengths[intervals[merge_right][1]-intervals[merge_left][0]+1]+=1\n                intervals[merge_left:merge_right+1]=[[intervals[merge_left][0],intervals[merge_right][1]]]\n            if lengths[m]>0:\n                ans=step+1\n            # print(step, x)\n            # print(intervals,lengths)\n\n\n        return ans", "class DSU:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.depth = [0 for i in range(n)]\n        self.size = [0 for i in range(n)]\n        self.count = collections.defaultdict(int)\n    \n    def findParent(self, n):\n        if self.parent[n] != n:\n            self.parent[n] = self.findParent(self.parent[n])\n        return self.parent[n]\n\n    def union(self, x, y):\n        x_parent = self.findParent(x)\n        y_parent = self.findParent(y)\n        \n        if x_parent == y_parent:\n            return\n            \n        self.count[self.size[y_parent]] -= 1\n        self.count[self.size[x_parent]] -= 1\n        \n        if self.depth[x_parent] >= self.depth[y_parent]:\n            self.parent[y_parent] = x_parent\n            self.size[x_parent] += self.size[y_parent]\n            self.depth[x_parent] += (self.depth[x_parent] == self.depth[y_parent])\n            \n            self.count[self.size[x_parent]] += 1\n            \n        else:\n            self.parent[x_parent] = y_parent\n            self.size[y_parent] += self.size[x_parent]\n            self.depth[y_parent] += 1\n            \n            self.count[self.size[y_parent]] += 1\n        \n        \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        last_step = -1\n        bits = [0] * len(arr)\n        dsu = DSU(len(arr))\n        \n        for i in range(len(arr)):\n            idx = arr[i] - 1\n            bits[idx] = 1\n            \n            dsu.size[idx] = 1\n            dsu.count[1] += 1\n            \n            cur_size = 1\n            \n            if idx > 0:\n                if bits[idx - 1]:\n                    dsu.union(idx-1, idx)\n            if idx < len(arr) - 1:\n                if bits[idx + 1]:\n                    dsu.union(idx+1, idx)\n            if dsu.count[m] > 0:\n                last_step = i+1\n            \n            # print(dsu.parent)\n            # print(dsu.size)\n            # print(dsu.count)\n            # print()\n        \n        return last_step\n", "class UF:\n    def __init__(self, n):\n        self.p = [i for i in range(n + 1)]\n        self.counts = Counter()\n        self.rank = [0 for i in range(n + 1)]\n    \n    def getParent(self, i):\n        if self.p[i] == i:\n            return i\n        self.p[i] = self.getParent(self.p[i])\n        return self.p[i]\n    \n    def set(self, i):\n        self.counts[1] += 1\n        self.rank[i] = 1\n        \n    def isSet(self, i):\n        return 1 <= i < len(self.p) and self.rank[i] != 0\n    \n    def getCount(self, i):\n        return self.counts[i]\n    \n    def connect(self, i, j):\n        pi = self.getParent(i)\n        pj = self.getParent(j)\n        if pi != pj:\n            self.p[pi] = pj\n            ri, rj = self.rank[pi], self.rank[pj]\n            self.counts[ri] -= 1\n            self.counts[rj] -= 1\n            self.counts[ri + rj] += 1\n            self.rank[pj] = ri + rj\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        uf = UF(n)\n        \n        result = -1\n        for i, e in enumerate(arr, start = 1):\n            uf.set(e)\n            if uf.isSet(e-1):\n                uf.connect(e-1, e)\n            if uf.isSet(e+1):\n                uf.connect(e, e+1)\n            if uf.getCount(m) != 0:\n                result = i\n        \n        return result\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        p = list(range(n))\n        size = [0]*n\n \n        def find(x):\n            if x!=p[x]:\n                p[x] = find(p[x])\n            return p[x]\n \n        def union(x,y):\n            px,py = find(x),find(y)\n            if px == py:\n                return False\n            if size[px]>size[py]:\n                p[py] = px\n                size[px]+=size[py]\n            else:\n                p[px] =py\n                size[py] += size[px]\n            return True\n \n        if m == len(arr):\n            return m\n        ans = -1\n        for step,i in enumerate(arr):\n            i -= 1\n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[find(j)]==m:\n                        ans = step\n            size[i] = 1\n            for j in range(i-1,i+2):\n                if 0<=j<n:\n                    if size[j]:\n                        union(i,j)\n        return ans", "class BinaryIndexedTree:\n    ''' index from 1'''\n    def __init__(self, n):\n        self.n = n\n        self.data = [0]*(n+1)\n        #todo: init all 1\n        for i in range(1, n+1):\n            self.data[i]+=1\n            tmp = i + (i&-i)\n            if tmp <= n:\n                self.data[i+(i&-i)] += self.data[i]\n    def add(self, index, value):\n        while(index<=self.n):\n            self.data[index]+=value\n            index += index & -index\n    def prefix(self, index):\n        res = 0\n        while(index):\n            res += self.data[index]\n            index -= index & -index\n        return res\n    \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], k: int) -> int:\n        n = len(arr)\n        if k == n:\n            return n\n        bit = BinaryIndexedTree(n)\n        for no, p in enumerate(arr[::-1]):\n            bit.add(p, -1)\n            if p-k >= 1:\n                s1 = bit.prefix(p-1)\n                s2 = bit.prefix(p-k-1)\n                if s1 - s2 == k and (p-k-1==0 or bit.prefix(p-k-2)==s2):                    \n                    return n-no-1\n            if p+k <= n:\n                s1 = bit.prefix(p)\n                s2 = bit.prefix(p+k)\n                if s2 - s1 == k and (p+k==n or bit.prefix(p+k+1)==s2):\n                    print('b',p,s1,s2)\n                    return n-no-1\n        return -1", "class UnionFind:\n    def __init__(self, n):\n        self.leaders = {}\n        self.ranks = {}\n        self.size = {}\n        \n    def add(self, x):\n        if x in self.leaders:\n            return\n        self.leaders[x] = x\n        self.ranks[x] = 1\n        self.size[x] = 1\n    \n    def find(self, x):\n        # p = x\n        # while p != self._leaders[p]:\n        #     p = self._leaders[p]\n        # while x != p:\n        #     self._leaders[x], x = p, self._leaders[x]\n        # return p\n        if self.leaders[x] != x:\n            self.leaders[x] = self.find(self.leaders[x])\n        return self.leaders[x]\n    \n    def union(self, x, y):\n        p = self.find(x)\n        q = self.find(y)\n        if p == q: \n            return False\n        if self.ranks[p] < self.ranks[q]:\n            self.leaders[p] = q\n            self.size[q] += self.size[p]\n        elif self.ranks[p] > self.ranks[q]:\n            self.leaders[q] = p\n            self.size[p] += self.size[q]\n        else:        \n            self.leaders[q] = p\n            self.ranks[p] += 1\n            self.size[p] += self.size[q]\n        return True\n    \nclass Solution:\n    def findLatestStep(self, arr, m):\n        n = len(arr)\n        if n == m:\n            return m\n        uf = UnionFind(n)\n        state = 0\n        res = -1\n        for i, x in enumerate(arr):\n            uf.add(x)\n            state ^= (1 << x)\n            if x - 1 >= 1 and state & (1 << (x - 1)) != 0:\n                if uf.size[uf.find(x - 1)] == m:\n                    res = i\n                uf.union(x, x - 1)\n            if x + 1 <= n and state & (1 << (x + 1)) != 0:\n                if uf.size[uf.find(x + 1)] == m:\n                    res = i\n                uf.union(x, x + 1)\n        return res", "\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # limit for array size  \n        N = len(arr)+2;\n\n        # Max size of tree  \n        tree = [0] * (2 * N);  \n\n        # function to build the tree  \n        def build(arr) : \n\n            # insert leaf nodes in tree  \n            for i in range(n) :  \n                tree[n + i] = arr[i];  \n\n            # build the tree by calculating parents  \n            for i in range(n - 1, 0, -1) :  \n                tree[i] = tree[i << 1] + tree[i << 1 | 1];  \n\n        # function to update a tree node  \n        def updateTreeNode(p, value) :  \n\n            # set value at position p  \n            tree[p + n] = value;  \n            p = p + n;  \n\n            # move upward and update parents  \n            i = p; \n\n            while i > 1 : \n\n                tree[i >> 1] = tree[i] + tree[i ^ 1];  \n                i >>= 1;  \n\n        # function to get sum on interval [l, r)  \n        def query(l, r) :  \n\n            res = 0;  \n\n            # loop to find the sum in the range  \n            l += n; \n            r += n; \n\n            while l < r : \n\n                if (l & 1) : \n                    res += tree[l];  \n                    l += 1\n\n                if (r & 1) : \n                    r -= 1; \n                    res += tree[r];  \n\n                l >>= 1; \n                r >>= 1\n\n            return res;\n        \n        if m == len(arr):\n            return len(arr)\n        arr.reverse()\n        n = len(arr)+2\n        init = [0] * (n+1)\n        init[0] = init[n-1] = 1\n        build(init)\n        for i, e in enumerate(arr):\n            if 0 <= e - (m+1) and init[e - (m+1)] == 1 and query(e - m, e) == 0:\n                return len(arr) - i - 1\n            if e + (m+1) <= n-1 and init[e + (m+1)] == 1 and query(e, e + m + 1) == 0:\n                return len(arr) - i - 1\n            updateTreeNode(e, 1)\n            init[e] = 1\n        return -1\n", "from typing import List\nfrom heapq import heappush, heappop, heapify\n\nclass Node:\n    def __init__(self, parent, value):\n        self.parent = parent\n        self.rank = 0\n        self.size = 1\n        self.value = value\n\nclass UnionFind:\n    def __init__(self, nodes):\n        self.subsets = [Node(i, v) for i, v in enumerate(nodes)]\n        self.maxSubsetSize = 1\n\n    def union(self, i, j):\n        irep = self.find(i)\n        jrep = self.find(j)\n        if irep == jrep:\n            return\n        # union by rank\n        if self.subsets[irep].rank > self.subsets[jrep].rank:\n            self.subsets[jrep].parent = irep\n            self.subsets[irep].size += self.subsets[jrep].size\n        elif self.subsets[jrep].rank > self.subsets[irep].rank:\n            self.subsets[irep].parent = jrep\n            self.subsets[jrep].size += self.subsets[irep].size\n        else:\n            self.subsets[irep].parent = jrep\n            self.subsets[jrep].rank += 1\n            self.subsets[jrep].size += self.subsets[irep].size\n        self.maxSubsetSize = max(self.maxSubsetSize, max(self.subsets[irep].size, self.subsets[jrep].size))\n\n    def find(self, i):\n        if self.subsets[i].parent != i:\n            # path compression\n            self.subsets[i].parent = self.find(self.subsets[i].parent)\n        return self.subsets[i].parent\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UnionFind(list(range(len(arr))))\n        lengthMsets = set()\n        last_step = -1\n        if m == 1:\n            lengthMsets.add(arr[0]-1)\n            last_step = 1\n        numsets = set([arr[0]-1])\n        for i in range(1, len(arr), 1):\n            num = arr[i] - 1\n            numsets.add(num)\n            if num - 1 in numsets:\n                if uf.find(num - 1) in lengthMsets:\n                    lengthMsets.remove( uf.find(num - 1))\n                uf.union(num-1, num)\n            if num + 1 in numsets:\n                if  uf.find(num + 1) in lengthMsets:\n                    lengthMsets.remove(uf.find(num + 1))\n                uf.union(num+1, num)\n            if uf.subsets[uf.find(num)].size == m:\n                lengthMsets.add(uf.find(num))\n            if len(lengthMsets) > 0:\n                last_step = i + 1\n        return last_step\n", "from sortedcontainers import SortedList\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        \n        sl = SortedList([0, n+1])\n        for i in range(n)[::-1]:\n            k = arr[i]\n            pos = sl.bisect(k)\n            left, right = sl[pos - 1], sl[pos]\n            if right - k - 1 == m or k - left - 1 == m:\n                return i\n            sl.add(k)\n            \n        return -1", "class DisjointSet:\n    def __init__(self, nums,p='left'):\n        self.parent = {i: i for i in nums}\n        self.height = {i: 0 for i in nums}\n        self.count = len(nums)\n        self.p=p\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        xRoot = self.find(x)\n        yRoot = self.find(y)\n        if xRoot == yRoot:\n            return xRoot\n        if self.p=='left':\n            (lower, higher) = (\n                xRoot, yRoot) if xRoot > yRoot else (yRoot, xRoot)\n        else:\n            (lower, higher) = (\n                xRoot, yRoot) if xRoot < yRoot else (yRoot, xRoot)\n        self.parent[lower] = higher\n        if self.height[higher] == self.height[lower]:\n            self.height[higher] += 1\n        self.count -= 1\n        return higher\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n=len(arr)\n        left=DisjointSet(list(range(len(arr))),'left')\n        right=DisjointSet(list(range(len(arr))),'right')\n        state=[0]*(len(arr))\n        count=collections.defaultdict(int)\n        latest=-1\n        for step,idx in enumerate(arr):\n            idx-=1\n            state[idx]=1\n            l=r=idx\n            if idx>0 and state[idx-1]>0:\n                left.union(idx,idx-1)\n                right.union(idx,idx-1)\n                \n            if idx<n-1 and state[idx+1]>0:\n                right.union(idx,idx+1)\n                left.union(idx,idx+1)\n            l=left.find(idx)\n            r=right.find(idx)\n            count[idx-l]-=1\n            count[r-idx]-=1\n            count[r-l+1]+=1\n            if count[m]>=1:\n                latest=step+1\n            # print(idx,state,count,left.parent,right.parent,l,r)\n        return latest\n", "import collections\nclass Solution:\n    def findLatestStep(self, placed, target):\n        N = len(placed)\n        A = [0] * N\n        dsu = DSU(N)\n        sizes = collections.Counter()\n        ans = -1\n\n        for i, x in enumerate(placed, 1):\n            x -= 1\n            A[x] = 1\n            for y in (x - 1, x + 1):\n                if 0 <= y < N and A[y]:\n                    sizes[dsu.size(y)] -= 1\n                    dsu.union(x, y)\n            \n            sizes[dsu.size(x)] += 1\n            if sizes[target] > 0:\n                ans = i\n        \n        return ans\n\nclass DSU:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.sz = [1] * N\n\n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        if xr == yr:\n            return False\n        if self.sz[xr] < self.sz[yr]:\n            xr, yr = yr, xr\n        self.par[yr] = xr\n        self.sz[xr] += self.sz[yr]\n        self.sz[yr] = self.sz[xr]\n        return True\n\n    def size(self, x):\n        return self.sz[self.find(x)]", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        vals = [0] * (len(arr) + 2)\n        intervals = [0, len(arr) + 1]\n        for idx in reversed(list(range(len(arr)))):\n            bit = arr[idx]\n            lo = 0\n            hi = len(intervals)\n            while lo < hi:\n                mid = lo + (hi - lo) // 2\n                if intervals[mid] >= bit:\n                    hi = mid\n                else:\n                    lo = mid + 1\n                    \n            leftLen = bit - intervals[lo - 1] - 1\n            rightLen = intervals[lo] - bit - 1\n            if leftLen == m or rightLen == m:\n                return idx\n            if intervals[lo] - intervals[lo - 1] - 1 > m:\n                intervals.insert(lo, bit)\n        return -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = {}\n        seen = [0] * (len(arr) + 1)\n\n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n\n        def union(x, y):\n            seen[find(y)] += seen[find(x)]\n            uf[find(x)] = find(y)\n\n        ans, n = -1, len(arr)\n        for i, a in enumerate(arr, 1):\n            seen[a] = 1\n            for b in [a - 1, a + 1]:\n                if 1 <= b <= n and seen[b]:\n                    if seen[find(b)] == m:\n                        ans = i - 1\n                    union(a, b)\n        for i in range(1, n + 1):\n            if seen[find(i)] == m:\n                ans = n\n\n        return ans\n                \n                \n                \n                \n                \n", "class Solution:\n    def findLatestStep(self, A: List[int], m: int) -> int:\n        n = len(A)\n        length = [0] * (n + 2)\n        cnt = [0] * (n + 2)\n        res = -1\n        for i,v in enumerate(A):\n            l = length[v - 1]\n            r = length[v + 1]\n            length[v] = length[v - l] = length[v + r] = l + r + 1\n            cnt[l] -= 1\n            cnt[r] -= 1\n            cnt[l + r + 1] += 1\n            if cnt[m] != 0:\n                res = i + 1\n        return res", "from bisect import bisect\nfrom collections import defaultdict\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        ans = -1\n        count = defaultdict(int)\n        tmp = []\n        \n        for i, a in enumerate(arr):\n            index = bisect(tmp, a)\n            add = 0\n\n            if index != 0 and tmp[index-1] + 1 == a:\n                count[tmp[index-1] - tmp[index-2] + 1] -= 1\n                k = tmp.pop(index-1)\n                tmp.insert(index-1, a)\n                count[a - tmp[index-2] + 1] += 1\n                add += 1\n                # print('<', tmp, count)\n            if index < len(tmp) - 1 and tmp[index] -1 == a:\n                count[tmp[index+1] - tmp[index] + 1] -= 1\n                k = tmp.pop(index)\n                tmp.insert(index, a)\n                count[tmp[index+1] - a + 1] += 1\n                add += 1\n                # print('>', tmp, count)\n                \n            if add == 0:\n                tmp.insert(index, a)\n                tmp.insert(index, a)\n                count[1] += 1\n            elif add == 2:\n                count[a - tmp[index-2] + 1] -= 1\n                count[tmp[index+1] - a + 1] -= 1\n                count[tmp[index+1] - tmp[index-2] + 1] += 1\n                tmp.pop(index)\n                tmp.pop(index-1)\n            \n            # print(tmp, count)\n            if count[m] > 0:\n                ans = i + 1\n        \n        # print('-' * 20)\n        # s = ['0' for _ in range(len(arr))]\n        # def exist(s, m):\n        #     p = ''.join(s).split('0')\n        #     return any(len(x) == m for x in p)\n        # for i, a in enumerate(arr):\n        #     s[a-1] = '1'\n        #     if exist(s, m):\n        #         ans = i + 1\n        return ans", "from collections import Counter\nclass UnionFind():\n    def __init__(self):\n        self.uf, self.rank, self.size = {}, {}, {}\n        self.roots = set()\n        self.size_cnt = Counter()\n        \n    def add(self, x):\n        if x not in self.uf:\n            self.uf[x], self.rank[x], self.size[x] = x, 0, 1\n            self.roots.add(x)\n            self.size_cnt[1] += 1\n        \n    def find(self, x):\n        self.add(x)\n        if x != self.uf[x]:\n            self.uf[x] = self.find(self.uf[x])\n        return self.uf[x]\n\n    def union(self, x, y):  \n        xr, yr = self.find(x), self.find(y)\n        if xr == yr: return\n        self.size_cnt[self.size[xr]] -= 1\n        self.size_cnt[self.size[yr]] -= 1\n        if self.rank[xr] <= self.rank[yr]:\n            self.uf[xr] = yr\n            self.size[yr] += self.size[xr]\n            self.size_cnt[self.size[yr]] += 1\n            self.rank[yr] += (self.rank[xr] == self.rank[yr])\n            self.roots.discard(xr)\n        else:\n            self.uf[yr] = xr\n            self.size[xr] += self.size[yr]\n            self.size_cnt[self.size[xr]] += 1\n            self.roots.discard(yr)\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf, ans = UnionFind(), -1\n        for step, i in enumerate(arr, 1):\n            if i not in uf.uf: uf.add(i)\n            if i - 1 in uf.uf: uf.union(i, i - 1)\n            if i + 1 in uf.uf: uf.union(i, i + 1)\n            if uf.size_cnt[m] > 0: ans = step\n        return ans\n", "from bisect import bisect\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if n == m:\n            return n\n        l = [0,n+1]\n        for i in range(n-1,-1,-1):\n            index = bisect(l,arr[i])\n            front, end = l[index-1], l[index]\n            if end - front <= m:\n                continue\n            if arr[i] - front == m+1 or end-arr[i] == m+1:\n                return i\n            else:\n                l.insert(index,arr[i])\n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        from sortedcontainers import SortedList\n        n = len(arr)\n        if n == m:\n            return n\n        s = SortedList()\n        s.add(0)\n        s.add(n+1)\n        for j in range(n-1, -1, -1):\n            a = arr[j]\n            s.add(a)\n            i = s.bisect_left(a)\n            le, ri = a - s[i-1] - 1, s[i+1] - a - 1\n            if le == m or ri == m:\n                return j\n        return -1", "# union find idea. But no need to implement union find, since only two sides can extend\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        count_m = 0\n        n = len(arr)\n        string = [0]*(n+1)\n        res = -1\n        step = 0\n        for loc in arr:\n            step += 1\n            l,r = loc,loc\n            string[loc] = loc\n            if(loc-1>=0 and string[loc-1]!=0):\n                # merge with left\n                if((loc-1)-string[loc-1]+1==m):  # one sequence with length m disapper\n                    count_m -= 1\n                    \n                string[r]= l = string[loc-1]\n                string[l] = r \n            if(loc+1<=n and string[loc+1]!=0):\n                # merge with right\n                if(string[loc+1]-(loc+1)+1==m):  # one sequence with length m disapper\n                    count_m -= 1\n                \n                string[l] = r = string[loc+1]\n                string[r] = l \n            \n            if(r-l+1==m):\n                count_m += 1\n            if(count_m>0):\n                res = step\n            #print(string)\n        \n        return res", "class DSU:\n    def __init__(self):\n        self.N = 10**5 + 1\n        self.parent = [i for i in range(self.N)]\n        self.rank = [0 for _ in range(self.N)]\n        self.comp = [1 for _ in range(self.N)]\n        \n    def find(self, i):\n        if self.parent[i] == i: return i\n        else: return self.find(self.parent[i])\n        \n    def union(self, i, j):\n        x, y = self.find(i), self.find(j)\n        \n        if self.rank[x] > self.rank[y]:\n            self.parent[y] = x\n            self.comp[x] += self.comp[y]\n            self.comp[y] = 0\n            \n        elif self.rank[x] < self.rank[y]:\n            self.parent[x] = y\n            self.comp[y] += self.comp[x]\n            self.comp[x] = 0\n            \n        else:\n            self.parent[y] = x\n            self.comp[x] += self.comp[y]\n            self.comp[y] = 0\n            self.rank[x] += 1\n        \n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        N = 10**5 + 1\n        nums = [False for _ in range(N+2)]\n        d = DSU()\n        \n        cnt = [0 for _ in range(N+2)]\n        ret = -1\n        \n        for index, a in enumerate(arr):\n            cnt[d.comp[d.find(a)]] += 1\n            \n            if nums[a-1]: \n                cnt[d.comp[d.find(a-1)]] -= 1\n                cnt[d.comp[d.find(a)]] -= 1\n                d.union(a-1, a)\n                cnt[d.comp[d.find(a)]] += 1\n\n                \n                \n            if nums[a+1]:\n                cnt[d.comp[d.find(a+1)]] -= 1\n                cnt[d.comp[d.find(a)]] -= 1\n                d.union(a, a+1)\n                cnt[d.comp[d.find(a)]] += 1\n\n                \n\n            nums[a] = True\n                \n            if cnt[m]: ret = index+1\n                \n            #print(index, a, cnt)\n                \n        return ret\n                \n        \n", "from collections import Counter\nclass UnionFind():\n    def __init__(self):\n        self.uf, self.rank, self.size, self.cnt = {}, {}, {}, Counter()\n    def add(self, x):\n        if x not in self.uf:\n            self.uf[x], self.rank[x], self.size[x] = x, 0, 1\n            self.cnt[1] += 1\n    def find(self, x):\n        self.add(x)\n        if x != self.uf[x]:\n            self.uf[x] = self.find(self.uf[x])\n        return self.uf[x]\n    def union(self, x, y):  \n        xr, yr = self.find(x), self.find(y)\n        if xr == yr: return\n        self.cnt[self.size[xr]] -= 1\n        self.cnt[self.size[yr]] -= 1\n        if self.rank[xr] <= self.rank[yr]:\n            self.uf[xr] = yr\n            self.size[yr] += self.size[xr]\n            self.cnt[self.size[yr]] += 1\n            self.rank[yr] += (self.rank[xr] == self.rank[yr])\n        else:\n            self.uf[yr] = xr\n            self.size[xr] += self.size[yr]\n            self.cnt[self.size[xr]] += 1\n            \nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        uf = UnionFind()\n        ans = -1\n        for s, ind in enumerate(arr):\n            if ind not in uf.uf:\n                uf.add(ind)\n            if ind - 1 in uf.uf:\n                uf.union(ind, ind - 1)\n            if ind + 1 in uf.uf:\n                uf.union(ind, ind + 1)\n            if uf.cnt[m] > 0:\n                ans = s+1\n        return ans", "import bisect\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        s = [0, n + 1]\n        \n        if n == m: return n\n        \n        for i, x in enumerate(reversed(arr)):\n            j = bisect.bisect_right(s, x)\n            s.insert(j, x)\n            if m == x - s[j-1] - 1 or m == s[j + 1] - x - 1:\n                return n - i - 1\n            \n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr): return m;\n        length = [0] * (len(arr) + 2)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr): return m\n        length = [0] * (len(arr) + 2)\n        res = -1\n        for i, a in enumerate(arr):\n            left, right = length[a - 1], length[a + 1]\n            if left==m or right == m: res = i\n            length[a] = length[a - left] = length[a + right] = left + right + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if m == len(arr):\n            return m\n        \n        from bisect import bisect_left\n        zeros = [0,len(arr)+1]\n        ans = -1\n        \n        for i in reversed(list(range(len(arr)))):\n            index = bisect_left(zeros,arr[i])\n            zeros.insert(index,arr[i])\n            if m in (zeros[index+1]-arr[i]-1,arr[i]-zeros[index-1]-1):\n                return i\n        return -1\n", "\n\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # limit for array size  \n        N = len(arr)+2;\n\n        # Max size of tree  \n        tree = [0] * (2 * N);  \n\n        # function to build the tree  \n        def build(arr) : \n\n            # insert leaf nodes in tree  \n            for i in range(n) :  \n                tree[n + i] = arr[i];  \n\n            # build the tree by calculating parents  \n            for i in range(n - 1, 0, -1) :  \n                tree[i] = tree[i << 1] + tree[i << 1 | 1];  \n\n        # function to update a tree node  \n        def updateTreeNode(p, value) :  \n\n            # set value at position p  \n            tree[p + n] = value;  \n            p = p + n;  \n\n            # move upward and update parents  \n            i = p; \n\n            while i > 1 : \n\n                tree[i >> 1] = tree[i] + tree[i ^ 1];  \n                i >>= 1;  \n\n        # function to get sum on interval [l, r)  \n        def query(l, r) :  \n\n            res = 0;  \n\n            # loop to find the sum in the range  \n            l += n; \n            r += n; \n\n            while l < r : \n\n                if (l & 1) : \n                    res += tree[l];  \n                    l += 1\n\n                if (r & 1) : \n                    r -= 1; \n                    res += tree[r];  \n\n                l >>= 1; \n                r >>= 1\n\n            return res;\n        \n        if m == len(arr):\n            return len(arr)\n        \n        n = len(arr)+2\n        init = [0] * (n+1)\n        init[0] = init[n-1] = 1\n        build(init)\n        for i in range(len(arr)-1, -1, -1):\n            e = arr[i]\n            print(e)\n            if 0 <= e - (m+1) and init[e - (m+1)] == 1 and query(e - m, e) == 0:\n                return i\n            if e + (m+1) <= n-1 and init[e + (m+1)] == 1 and query(e, e + m + 1) == 0:\n                return i\n            updateTreeNode(e, 1)\n            init[e] = 1\n        return -1\n", "from bisect import bisect_left\nclass Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        if (m == n):\n            return n\n        r = []\n        r.append(0)\n        r.append(n + 1)\n        \n        for i in range(n - 1, -1, -1):\n            j = bisect_left(r, arr[i])\n            if (r[j] - arr[i] - 1 == m or arr[i] - r[j-1] - 1 == m):\n                return i\n            r.insert(j, arr[i])\n        return -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # expected group len is equal to len(arr)\n        if(m == len(arr)):\n            return m\n        '''\n        group_edge = [0] * (len(arr)+2)\n        ans = 0 \n        for i in range(0, len(arr)):\n            print(arr[i])\n            left=right=arr[i]\n            if group_edge[right+1]>0: \n                right=group_edge[right+1]\n            if group_edge[left-1]>0: \n                left=group_edge[left-1]\n            group_edge[left], group_edge[right] = right, left\n            if (right-arr[i]==m) or (arr[i]-left ==m): \n                ans=i\n            print(group_edge)\n        '''\n        group_len = [0] * (len(arr) + 2)\n        cnt_group_len = [0] * (len(arr) + 1)\n        ans = -1\n        for i in range(0, len(arr)):\n            \n            #print(arr[i])\n            \n            left_most = arr[i] - 1\n            right_most = arr[i] + 1\n            new_len = group_len[left_most] + group_len[right_most] + 1\n            group_len[arr[i]] = new_len\n            \n            cnt_group_len[new_len] += 1\n            cnt_group_len[group_len[left_most]] -= 1\n            cnt_group_len[group_len[right_most]] -= 1\n            \n            #if(group_len[left_most] > 0):\n            group_len[arr[i] - group_len[left_most]] = new_len\n            \n            #if(group_len[right_most] > 0):\n            group_len[arr[i] + group_len[right_most]] = new_len\n            \n            #print(group_len)\n            #print(cnt_group_len)\n            \n            if(cnt_group_len[m] > 0):\n                ans = i + 1\n            \n        return ans\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0 for i in range(len(arr) + 2)]\n        count = [0 for i in range(len(arr) + 1)]\n        res = -1\n        for i, v in enumerate(arr):\n            left, right = length[v-1], length[v+1]\n            length[v] = left + right + 1\n            length[v-left] = left + right + 1\n            length[v+right] = left + right + 1\n            if count[left] > 0:\n                count[left] -= 1\n            if count[right] > 0:\n                count[right] -= 1\n            count[length[v]] += 1\n            if count[m]:\n                res = i + 1\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:   \n        length = [0] * (len(arr)+2)\n        count = [0]*(len(arr)+1)\n        res = -1\n        for i, pos in enumerate(arr):\n            left, right = length[pos-1], length[pos+1]\n            length[pos] = length[pos-left] = length[pos+right] = left+right+1\n            count[left+right+1] += 1 \n            count[left]-=1 \n            count[right]-=1 \n            \n            if count[m]:\n                res = i+1 \n                \n                \n        return res \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        # expected group len is equal to len(arr)\n        if(m == len(arr)):\n            return m\n        '''\n        group_edge = [0] * (len(arr)+2)\n        ans = 0 \n        for i in range(0, len(arr)):\n            print(arr[i])\n            left=right=arr[i]\n            if group_edge[right+1]>0: \n                right=group_edge[right+1]\n            if group_edge[left-1]>0: \n                left=group_edge[left-1]\n            group_edge[left], group_edge[right] = right, left\n            if (right-arr[i]==m) or (arr[i]-left ==m): \n                ans=i\n            print(group_edge)\n        '''\n        group_len = [0] * (len(arr) + 2)\n        cnt_group_len = [0] * (len(arr) + 1)\n        ans = -1\n        for i in range(0, len(arr)):\n            \n            #print(arr[i])\n            \n            left_most = arr[i] - 1\n            right_most = arr[i] + 1\n            new_len = group_len[left_most] + group_len[right_most] + 1\n            group_len[arr[i]] = new_len\n            \n            cnt_group_len[new_len] += 1\n            cnt_group_len[group_len[left_most]] -= 1\n            cnt_group_len[group_len[right_most]] -= 1\n            \n            if(group_len[left_most] > 0):\n                group_len[arr[i] - group_len[left_most]] = new_len\n            \n            if(group_len[right_most] > 0):\n                group_len[arr[i] + group_len[right_most]] = new_len\n            \n            #print(group_len)\n            #print(cnt_group_len)\n            \n            if(cnt_group_len[m] > 0):\n                ans = i + 1\n            \n        return ans\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        lookup = {}\n        lastStep = -1\n        valid = set()\n        for idx, num in enumerate(arr):\n            left = num\n            right = num\n            if num-1 in lookup:\n                left = lookup[num-1][0]\n                if num-1 in valid:\n                    valid.remove(num-1)\n                \n            if num+1 in lookup:\n                right = lookup[num+1][1]\n                if num+1 in valid:\n                    valid.remove(num+1)\n            \n            if left in valid:\n                valid.remove(left)\n            \n            if right in valid:\n                valid.remove(right)\n                \n            lookup[left] = (left, right)\n            lookup[right] = (left, right)\n            \n            if right-left+1 == m:\n                valid.add(left)\n                valid.add(right)\n            \n            if valid:\n                lastStep = idx+1\n        return lastStep", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        index = [-1 for i in range(len(arr))]\n        groups = [0 for i in range(len(arr))]\n        count, lastindex = 0, -1\n        for i, num in enumerate(arr):\n            a = num -1\n            groups[a], index[a], length = 1, a, 1\n            if a-1 >= 0 and groups[a-1] == 1:\n                left = index[a-1] # left index\n                if a - left == m:\n                    count -= 1\n                index[left], index[a] = a, left # left end\n                length += (a - left)\n            if a+1 < len(arr) and groups[a+1] == 1:\n                left, right = index[a], index[a+1]\n                if right - a == m:\n                    count -= 1\n                index[right], index[left] = left, right\n                length += (right - a)\n            if length == m: count += 1\n            if count > 0: lastindex = i+1\n        return lastindex", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        l=len(arr)\n        left=[i for i in range(l+1)]\n        right=[i for i in range(l+2)]\n        count=[0]*(l+1)\n        res=-1\n        step=0\n        for a in arr:\n            step+=1\n            lt=left[a-1]\n            rt=right[a+1]\n            tlen=rt-lt-1\n            \n            templeft=a-lt-1\n            tempright=rt-a-1\n            count[templeft]-=1\n            count[tempright]-=1\n            count[tlen]+=1\n            \n            if count[m]>0:\n                res=step\n            right[lt+1]=rt\n            left[rt-1]=lt\n        return res\n                   \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        sizes = [0] * (len(arr) + 2)\n        res = -1\n        cnt = 0\n        for step, cur in enumerate(arr, start=1):\n            l, r = sizes[cur - 1], sizes[cur + 1]\n            new_sz = l + 1 + r\n            sizes[cur - l] = sizes[cur + r] = new_sz\n            cnt += (new_sz == m) - (l == m) - (r == m)\n            if cnt:\n                res = step\n        return res", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        a = [0] * len(arr) \n        heads = {}\n        ends = {}\n        ans = -1\n        for step, i in enumerate(arr):\n            a[i - 1] = 1\n            if self.mergeOne(a, i - 1, heads, ends, m) == 1:\n                ans = step \n        for i in heads:\n            if heads[i] - i + 1 == m:\n                return len(arr)\n        return ans\n            \n    def mergeOne(self, ls, index, heads, ends, m):\n        left, right = index - 1, index + 1 \n        lefthead = rightend = index\n        ext = -1\n        if left in ends:\n            lefthead = ends[left]\n            if left - lefthead + 1 == m:\n                ext = 1\n            del ends[left]\n        if right in heads:\n            rightend = heads[right]\n            if rightend - right + 1 == m:\n                ext = 1\n            del heads[right]\n        heads[lefthead] = rightend\n        ends[rightend] = lefthead\n        return ext\n            \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        res, n = -1, len(arr)\n        # length of group\n        length = [0] * (n + 2)\n        # count of length\n        count = [0] * (n + 1)\n        \n        for i, v in enumerate(arr):\n            left, right = length[v - 1], length[v + 1]\n            length[v] = length[v - left] = length[v + right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[v]] += 1\n            if count[m]:\n                res = i + 1        \n        return res", "class Solution:\n    def findLatestStep2(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        dic = collections.Counter()\n        cnt = collections.Counter()\n        res = -1\n        for i, a in enumerate(arr):\n            l = dic[a - 1]\n            r = dic[a + 1]\n            dic[a - l] = dic[a + r] = dic[a] = l + r + 1\n            cnt[l + r + 1] += 1\n            cnt[l] -= 1\n            cnt[r] -= 1\n            if cnt[m]:\n                res = i + 1\n        return res\n    \n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        leng = [0]  * (n + 2)\n        cnt = [0] * (n + 1)\n        res = -1\n        for i, a in enumerate(arr):\n            l = leng[a - 1]\n            r = leng[a + 1]\n            leng[max(0, a - l)] = leng[min(n + 1, a + r)] = l + r + 1\n            cnt[l] -= 1\n            cnt[r] -= 1\n            cnt[l + r + 1] += 1\n            if cnt[m]:\n                res = i + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m: return len(arr)\n        days = [0] * len(arr)\n        for i, x in enumerate(arr,1):\n            days[x-1] = i\n        deq = collections.deque()\n        def insert_deq(val,pop):\n            if deq and deq[0] == pop:\n                deq.popleft()\n            while deq and deq[-1] < val:\n                deq.pop()\n            deq.append(val)\n        latest = -1\n        for i, x in enumerate(days):\n            insert_deq(x, days[i-m] if i >= m else None )\n            if i < m - 1:\n                continue\n            left = days[i-m] if(i - m >= 0) else float('inf')\n            right = days[i+1] if(i + 1 < len(days)) else float('inf') \n            max_day_turn1 = deq[0]\n            if left > max_day_turn1 and right > max_day_turn1:\n                latest = max(latest,min(left,right) - 1)\n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        nums = []\n        max_index = -1\n        correct_blocks = 0\n        latest_index = -1\n        for _ in range(len(arr)):\n            nums.append(0)\n        for i in range(len(arr)):\n            index = arr[i]-1\n            \n            if index == 0:\n                try:\n                    nums[index] = 1 + nums[index+1]\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index+1] == m:\n                        correct_blocks += 1\n                    if nums[index+1] != 0:\n                        val = 1 + nums[index+1]\n                        nums[index + nums[index+1]] = val\n                        nums[index+1] = val\n                except:\n                    return 1\n            elif index == len(arr)-1:\n                try:\n                    nums[index] = 1 + nums[index-1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] == m:\n                        correct_blocks += 1\n                    if nums[index-1] != 0:\n                        val = 1 + nums[index - 1]\n                        nums[index - nums[index-1]] = val\n                        nums[index-1] = val\n                except:\n                    return 1\n            else:\n                try:\n                    val = 1 + nums[index-1] + nums[index+1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] + nums[index+1] == m:\n                        correct_blocks += 1\n                    nums[index] = val\n                    if nums[index-1] != 0:\n                        nums[index - nums[index-1]] = val\n                        nums[index-1] = val\n                    if nums[index+1] != 0:\n                        nums[index + nums[index+1]] = val\n                except:\n                    pass\n            if correct_blocks > 0:\n                latest_index = i+1\n        return latest_index", "class Solution:\n    def findLatestStep(self, A, m):\n        if m == len(A): return m\n        length = [0] * (len(A) + 2)\n        res = -1\n        for i, a in enumerate(A):\n            left, right = length[a - 1], length[a + 1]\n            if left == m or right == m:\n                res = i\n            length[a - left] = length[a + right] = left + right + 1\n        return res\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        dic = {}\n        endpoints = {}\n        startpoints = {}\n        latest = -1\n        for i in range(len(arr)):\n            step = arr[i]\n            if step-1 in endpoints:\n                if step+1 not in startpoints:\n                    j = endpoints[step-1]\n                    startpoints[j] = step\n                    endpoints[step] = j\n                    del endpoints[step-1]\n                    l = step-j\n                    dic[l] -= 1\n                    if l+1 in dic:\n                        dic[l+1] += 1\n                    else: dic[l+1] = 1\n                else:\n                    j = endpoints[step-1]\n                    k = startpoints[step+1]\n                    startpoints[j] = k\n                    endpoints[k] = j\n                    del startpoints[step+1]\n                    del endpoints[step-1]\n                    l1 = step-j\n                    l2 = k-step\n                    dic[l1] -= 1\n                    dic[l2] -= 1\n                    if l1+l2+1 in dic:\n                        dic[l1+l2+1] += 1\n                    else: dic[l1+l2+1] = 1\n            elif step+1 in startpoints:\n                k = startpoints[step+1]\n                endpoints[k] = step\n                startpoints[step] = k\n                del startpoints[step+1]\n                l = k-step\n                dic[l] -= 1\n                if l+1 in dic:\n                    dic[l+1] += 1\n                else: dic[l+1] = 1\n            else:\n                endpoints[step] = step\n                startpoints[step] = step\n                if 1 in dic:\n                    dic[1] += 1\n                else: dic[1] = 1\n            if m in dic and dic[m]!=0:\n                latest = i+1\n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        nums = []\n        max_index = -1\n        correct_blocks = 0\n        latest_index = -1\n        for _ in range(len(arr)):\n            nums.append(0)\n        for i in range(len(arr)):\n            index = arr[i]-1\n            \n            if index == 0:\n                try:\n                    nums[index] = 1 + nums[index+1]\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index+1] == m:\n                        correct_blocks += 1\n                    if nums[index+1] != 0:\n                        val = 1 + nums[index+1]\n                        nums[index + nums[index+1]] = val\n                except:\n                    return 1\n            elif index == len(arr)-1:\n                try:\n                    nums[index] = 1 + nums[index-1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] == m:\n                        correct_blocks += 1\n                    if nums[index-1] != 0:\n                        val = 1 + nums[index - 1]\n                        nums[index - nums[index-1]] = val\n                except:\n                    return 1\n            else:\n                try:\n                    val = 1 + nums[index-1] + nums[index+1]\n                    if nums[index-1] == m:\n                        correct_blocks -= 1\n                    if nums[index+1] == m:\n                        correct_blocks -= 1\n                    if 1 + nums[index-1] + nums[index+1] == m:\n                        correct_blocks += 1\n                    nums[index] = val\n                    if nums[index-1] != 0:\n                        nums[index - nums[index-1]] = val\n                        nums[index-1] = val\n                    if nums[index+1] != 0:\n                        nums[index + nums[index+1]] = val\n                except:\n                    pass\n            if correct_blocks > 0:\n                latest_index = i+1\n        return latest_index", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        d = defaultdict(int)\n        ans = 0\n        n = len(arr)\n        l = [-1]*n\n        r = [-1]*n\n        for i in range(n):\n            x = y = arr[i]-1\n            if x and l[x-1] != -1:\n                d[(x-1)-l[x-1]+1] -= 1\n                x = l[x-1]\n            if y < n-1 and r[y+1] != -1:\n                d[r[y+1]-(y+1)+1] -= 1\n                y = r[y+1]\n            d[y-x+1] += 1\n            if d[m]:\n                ans = i+1\n            l[y] = x\n            r[x] = y\n        return ans if ans else -1", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        start = {}\n        end = {}\n        lengths = {}\n        ans = -1\n        for i in range(len(arr)):\n            st = arr[i]\n            ending = st + 1\n            if st in end:\n                tempStart = st\n                st = end[st]\n                end.pop(st,None)\n            else:\n                tempStart = st\n            if ending in start:\n                ed = ending\n                ending = start[ending]\n                start.pop(ed,None)\n            else:\n                ed = ending\n            if st != tempStart:\n                lengths[tempStart-st] -= 1\n            if ed != ending:\n                print('d')\n                lengths[ending - ed] -= 1\n            if ending-st not in lengths:\n                lengths[ending-st] = 1\n            else:\n                lengths[ending-st] = lengths[ending-st]+1\n            start[st] = ending\n            end[ending] = st\n            if m in lengths and lengths[m] > 0:\n                ans = i+1\n        return ans\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        l = len(arr)\n        if l == m:\n            return l\n        \n        x = [0 for x in range(l+2)]\n        last = -1\n        for i in range(l):\n            cur = arr[i]\n            left, right = x[cur-1], x[cur+1]\n            if left == m or right == m:\n                last = i\n            x\n            x[cur-left] = x[cur+right] = left+right+1\n\n        return last", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = len(arr)\n        if length == m:\n            return m\n        if length < m:\n            return -1\n\n        count_m = 0\n        array2 = [0 for _ in range(length + 2)]\n        result = -1\n        for i in range(length):\n            index = arr[i]\n            if array2[index - 1] == m:\n                count_m -= 1\n            if array2[index + 1] == m:\n                count_m -= 1            \n            array2[index] = array2[index - 1] + array2[index + 1] + 1\n            if array2[index - 1] > 0:\n                array2[index - array2[index - 1]] = array2[index]\n            if array2[index + 1] > 0:\n                array2[index + array2[index + 1]] = array2[index]\n            if array2[index] == m:\n                count_m += 1\n            if count_m > 0:\n                result = i + 1\n        return result", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        n = len(arr)\n        mask = [0] * (n + 2)\n        ans = -1\n        \n        i = 1\n        count = 0\n        for index in arr:\n            total_len = 1 + mask[index - 1] + mask[index + 1]\n            change_set = {index + mask[index + 1], index - mask[index - 1]}\n            for ind in change_set:\n                if mask[ind] == m:\n                    count -= 1\n            mask[index - mask[index - 1]] = total_len\n            mask[index + mask[index + 1]] = total_len\n            \n            if total_len == m:\n                count += 1\n            if count > 0:\n                ans = i\n            i += 1\n        return ans\n            \n", "class Solution:\n    def findLatestStep(self, a: List[int], m: int) -> int:\n        if m == len(a): return len(a)\n        index2len, ans = defaultdict(int), -1        \n        for i, p in enumerate(a):    \n            l, r = index2len[p-1], index2len[p+1]      \n            if l == m or r == m: ans = i\n            index2len[p-l] = index2len[p+r] = l + 1 + r            \n        return ans", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        latest = -1\n        \n        if len(arr) == 1:\n            return 1 if arr[0] == m else -1\n        \n        ## (length -> appear times)\n        length_count = [0 for _ in range(len(arr) + 1)]\n        ## store consecutive 1's count ((start, end) -> length)\n        binary_str = [0 for _ in range(len(arr))]\n        for idx in range(len(arr)):\n            num = arr[idx] - 1\n            ## left boundary\n            if num <= 0:\n                if binary_str[num+1] > 0:\n                    right_count = binary_str[num+1]\n                    binary_str[num] = 1 + right_count\n                    binary_str[num+right_count] += 1\n                    length_count[1+right_count] += 1\n                    length_count[right_count] -= 1\n                else:\n                    binary_str[num] = 1\n                    length_count[1] += 1\n            ## right boundary\n            elif num >= len(arr) - 1:\n                if binary_str[num-1] > 0:\n                    left_count = binary_str[num-1]\n                    binary_str[num-left_count] += 1\n                    binary_str[num] = 1 + left_count\n                    length_count[1+left_count] += 1\n                    length_count[left_count] -= 1\n                else:\n                    binary_str[num] = 1\n                    length_count[1] += 1\n            ## in the middle\n            else:\n                if binary_str[num+1] > 0 and binary_str[num-1] > 0:\n                    left_count = binary_str[num-1]\n                    right_count = binary_str[num+1]\n                    binary_str[num-left_count] += (right_count + 1)\n                    binary_str[num+right_count] += (left_count + 1)\n                    length_count[left_count + right_count + 1] += 1\n                    length_count[left_count] -= 1\n                    length_count[right_count] -= 1\n                elif binary_str[num+1] > 0 and binary_str[num-1] <= 0:\n                    right_count = binary_str[num+1]\n                    binary_str[num] = 1 + right_count\n                    binary_str[num+right_count] += 1\n                    length_count[1 + right_count] += 1\n                    length_count[right_count] -= 1\n                elif binary_str[num+1] <= 0 and binary_str[num-1] > 0:\n                    left_count = binary_str[num-1]\n                    binary_str[num-left_count] += 1\n                    binary_str[num] = 1 + left_count\n                    length_count[1 + left_count] += 1\n                    length_count[left_count] -= 1\n                else:\n                    binary_str[num] = 1\n                    length_count[1] += 1\n                    \n            #print(num, binary_str, latest, idx, length_count)\n            if length_count[m] > 0:\n                latest = idx\n                \n        return latest + 1 if latest > -1 else -1\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        if len(arr) == m: return len(arr)\n        days = [0] * len(arr)\n        for i, x in enumerate(arr,1):\n            days[x-1] = i\n        deq = collections.deque()\n        def insert_deq(val,pop):\n            if deq and deq[0] == pop:\n                deq.popleft()\n            while deq and deq[-1] < val:\n                deq.pop()\n            deq.append(val)\n        latest = -1\n        for i, x in enumerate(days):\n            insert_deq(x, days[i-m] if i >= m else None )\n            if i < m - 1 or i == len(arr) - 1:\n                continue\n            left = days[i-m] if(i - m >= 0) else float('inf')\n            right = days[i+1] if(i + 1 < len(days)) else float('inf') \n            max_day_turn1 = deq[0]\n            if i == m-1: #checking just right, sliding window start\n                latest = max(latest,right - 1) if right > max_day_turn1 else latest\n            else: # making sure left and right side turn after sliding window max, and the min will be the latest\n                if left > max_day_turn1 and right > max_day_turn1:\n                    latest = max(latest,min(left,right) - 1)\n        left = days[-1 - m]\n        latest = max(latest,left - 1) if left > deq[0] else latest\n        return latest\n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        slots = [0 for _ in arr]\n        num_m = 0\n        last_m = -1 \n        if len(arr) == 1:\n            if m == 1:\n                return 1\n            else:\n                return -1 \n        for n in range(len(arr)):\n            i = arr[n]\n            idx = i -1 \n            if idx == len(arr) - 1:\n                slots[idx] = slots[idx - 1] + 1\n                if slots[idx] == m:\n                    num_m += 1\n                if slots[idx - 1] == m:\n                    num_m -= 1                    \n                if slots[idx - 1] > 0:\n                    slots[idx - slots[idx - 1]] = slots[idx]\n                \n            elif idx == 0:\n                slots[idx] = slots[idx + 1] + 1\n                if slots[idx] == m:\n                    num_m += 1\n                if slots[idx + 1] == m:\n                    num_m -= 1  \n                if slots[idx + 1] > 0:\n                    slots[idx + slots[idx + 1]] = slots[idx]\n            else:\n                slots[idx] = slots[idx- 1] + slots[idx + 1]+ 1\n                if slots[idx] == m:\n                    num_m += 1\n                if slots[idx + 1] == m:\n                    num_m -= 1\n                if slots[idx - 1] == m:\n                    num_m -= 1    \n                slots[idx - slots[idx - 1]] = slots[idx]\n                slots[idx + slots[idx + 1]] = slots[idx]\n            if num_m > 0:\n                last_m = n + 1\n\n        return last_m\n                \n", "class Solution:\n    def findLatestStep(self, arr: List[int], m: int) -> int:\n        length = [0] * (len(arr)+2)\n        count = [0] * (len(arr)+1)\n        ans = -1\n        for i, a in enumerate(arr):\n            left, right = length[a-1], length[a+1]\n            length[a] = length[a-left] = length[a+right] = left + right + 1\n            count[left] -= 1\n            count[right] -= 1\n            count[length[a]] += 1\n            # print(length, count)\n            if count[m]:\n                ans = i + 1\n        return ans"]