Alice has a hand of cards, given as an array of integers.
Now she wants to rearrange the cards into groups so that each group is size W, and consists of W consecutive cards.
Return true if and only if she can.
 


Example 1:
Input: hand = [1,2,3,6,2,3,4,7,8], W = 3
Output: true
Explanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8].
Example 2:
Input: hand = [1,2,3,4,5], W = 4
Output: false
Explanation: Alice's hand can't be rearranged into groups of 4.

 
Constraints:

1 <= hand.length <= 10000
0 <= hand[i] <= 10^9
1 <= W <= hand.length

Note: This question is the same as 1296: https://leetcode.com/problems/divide-array-in-sets-of-k-consecutive-numbers/

Difficulty: MEDIUM
Starter code: class Solution:
    def isNStraightHand(self, hand: List[int], W: int) -> bool:
        

Solutions:
class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		q = deque()
		opened = 0
		last = 0
		counter = Counter(hand)
		for n in sorted(counter):
			count = counter[n]
			if n > last + 1 and opened > 0:
				return False
			if n == last + 1 and count < opened:
				return False
			q.append(count - opened)
			opened = count
			if len(q) == W:
				opened -= q.popleft()
			last = n
		return not opened


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = collections.Counter(hand)
		for num in hand:
			if counter[num - 1] > 0 or counter[num] == 0:
				continue
			curr = num
			cnt = 0
			while cnt < W:
				if counter[curr] == 0:
					return False
				counter[curr] -= 1
				curr += 1
				cnt += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		heap = [(key, val) for (key, val) in list(Counter(hand).items())]
		heapq.heapify(heap)
		while heap:
			(pre, prec) = (None, None)
			temp = deque()
			for _ in range(W):
				if not heap:
					return False
				(num, count) = heapq.heappop(heap)
				if not pre:
					(pre, prec) = (num, count)
					continue
				if num != pre + 1 or count < prec:
					return False
				pre = num
				if count > prec:
					temp.append((num, count - prec))
			while temp:
				heapq.heappush(heap, temp.pop())
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = Counter(hand)
		while count:
			key = min(count)
			for k in range(key, key + W):
				check = count[k]
				if not check:
					return False
				else:
					count[k] -= 1
				if check == 1:
					del count[k]
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		N = len(hand)
		if N % W != 0:
			return False
		counter = Counter(hand)
		while counter:
			first = min(counter.keys())
			for i in range(first, first + W):
				if i not in counter:
					return False
				counter[i] -= 1
				if counter[i] == 0:
					del counter[i]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		c = Counter(hand)
		while c:
			x = min(c.keys())
			for i in range(x, x + W):
				if i not in c:
					return False
				c[i] -= 1
				if c[i] == 0:
					del c[i]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = collections.Counter(hand)
		while count:
			m = min(count)
			for k in range(m, m + W):
				v = count[k]
				if not v:
					return False
				if v == 1:
					del count[k]
				else:
					count[k] = v - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		dic = defaultdict(int)
		for i in range(len(hand)):
			dic[hand[i]] += 1
		for i in range(0, len(hand), W):
			start = min(dic.keys())
			dic[start] -= 1
			if dic[start] == 0:
				del dic[start]
			for i in range(1, W):
				start += 1
				if start not in dic:
					return False
				dic[start] -= 1
				if dic[start] == 0:
					del dic[start]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		cnt = collections.Counter(hand)
		while cnt:
			m = min(cnt)
			for i in range(m, m + W):
				if i not in cnt:
					return False
				elif cnt[i] == 1:
					del cnt[i]
				else:
					cnt[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		d = collections.defaultdict(lambda : 0)
		for h in hand:
			d[h] += 1
		while d:
			start = min(d.keys())
			for i in range(start, start + W):
				if not d[i]:
					return False
				d[i] -= 1
				if not d[i]:
					del d[i]
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		L = len(hand)
		if L % W != 0:
			return False
		count = Counter(hand)
		Nparts = L // W
		for i in range(Nparts):
			i_min = min(count.keys())
			for j in range(W):
				if i_min + j not in count:
					return False
				count[i_min + j] -= 1
				if count[i_min + j] == 0:
					del count[i_min + j]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		dp = defaultdict(list)
		for e in sorted(hand):
			dp[e].append(dp[e - 1].pop() + 1) if len(dp[e - 1]) != 0 else dp[e].append(1)
			if dp[e] and dp[e][-1] == W:
				dp[e].pop()
		return all((len(e) == 0 for e in list(dp.values())))


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = collections.Counter(hand)
		while counter:
			m = min(counter)
			for k in range(m, m + W):
				if not counter[k]:
					return False
				counter[k] -= 1
				if counter[k] == 0:
					del counter[k]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W:
			return False
		C = Counter(hand)
		for i in range(n // W):
			mn = min(C.keys())
			for j in range(mn, mn + W):
				if j not in C:
					return False
				else:
					C[j] -= 1
					if C[j] == 0:
						del C[j]
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		c = Counter(hand)
		while len(c) > 0:
			curr = min(c)
			v = c[curr]
			del c[curr]
			for i in range(1, W):
				if curr + i not in c or c[curr + i] < v:
					return False
				else:
					c[curr + i] -= v
					if c[curr + i] == 0:
						del c[curr + i]
		return True


from collections import OrderedDict

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		numHash = {}
		for n in hand:
			if n not in numHash:
				numHash[n] = 1
			else:
				numHash[n] += 1
		while numHash:
			num = min(numHash)
			for n in range(W):
				nextNum = num + n
				if nextNum in numHash:
					numHash[nextNum] -= 1
					if numHash[nextNum] == 0:
						del numHash[nextNum]
				else:
					return False
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		count = Counter(hand)
		while count:
			min_v = min(count.keys())
			for i in range(min_v, min_v + W):
				if count[i] == 0:
					return False
				count[i] -= 1
				if count[i] == 0:
					del count[i]
		return True


from collections import defaultdict

class Solution(object):

	def isNStraightHand(self, hand, W):
		dic = dict()
		for val in hand:
			dic[val] = dic.get(val, 0) + 1
		while dic:
			min_val = min(dic.keys())
			for i in range(min_val, min_val + W):
				v = dic.get(i, 0)
				if v == 0:
					return False
				dic[i] -= 1
				if dic[i] == 0:
					dic.pop(i)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if W ** 2 != len(hand):
			return False
		hand.sort()
		for i in range(0, len(hand), W):
			for j in range(1, W):
				if hand[i + j] - hand[i + j - 1] != 1:
					return False
		return True

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		from collections import Counter
		ct = Counter(hand)
		hand = sorted(ct.items())
		i = 0
		while i < len(hand):
			if hand[i][1] == 0:
				i += 1
				continue
			hand[i] = (hand[i][0], hand[i][1] - 1)
			k = hand[i][0]
			for j in range(1, W):
				k += 1
				if i + j < len(hand) and hand[i + j][0] == k:
					hand[i + j] = (hand[i + j][0], hand[i + j][1] - 1)
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		import collections
		count = collections.Counter(hand)
		while count:
			num = min(count.keys())
			val = count[num]
			for j in range(W):
				if count[num + j] < val:
					return False
				elif count[num + j] == val:
					del count[num + j]
				else:
					count[num + j] -= val
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		freq = Counter(hand)
		while freq:
			m = min(freq)
			for i in range(m, m + W):
				v = freq[i]
				if not v:
					return False
				if v == 1:
					del freq[i]
				else:
					freq[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		count = Counter(hand)
		for i in range(len(hand) // W):
			(num, group_count) = (min(count.keys()), 0)
			while group_count < W:
				count[num] -= 1
				if count[num] == 0:
					del count[num]
				elif count[num] < 0:
					return False
				group_count += 1
				num += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = defaultdict(int)
		for elem in hand:
			counter[elem] += 1
		while len(counter) > 0:
			curr = min(counter.keys())
			counter[curr] -= 1
			if counter[curr] == 0:
				del counter[curr]
			for i in range(1, W):
				curr += 1
				if curr in counter:
					counter[curr] -= 1
					if counter[curr] == 0:
						del counter[curr]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = collections.Counter(hand)
		while counter:
			starter = min(counter.keys())
			for i in range(W):
				if starter + i not in counter:
					return False
				else:
					counter[starter + i] -= 1
					if counter[starter + i] == 0:
						del counter[starter + i]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand = sorted(hand)
		failed = False
		while hand and (not failed):
			group = [hand[0]]
			del hand[0]
			idx = 0
			while len(group) < W and idx < len(hand):
				if group[-1] + 1 == hand[idx]:
					group.append(hand[idx])
					del hand[idx]
				else:
					idx += 1
			if len(group) < W:
				failed = True
		return not failed


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		maps = Counter(hand)
		while maps:
			k = min(maps.keys())
			count = maps[k]
			for i in range(k, k + W):
				if i not in maps or maps[i] < count:
					return False
				maps[i] -= count
				if maps[i] == 0:
					maps.pop(i)
		return True


from collections import OrderedDict

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		numHash = {}
		for n in hand:
			if n not in numHash:
				numHash[n] = 1
			else:
				numHash[n] += 1
		numHash = OrderedDict(sorted(numHash.items()))
		while len(numHash) > 0:
			num = list(numHash.keys())[0]
			for n in range(W):
				nextNum = num + n
				if nextNum in numHash:
					numHash[nextNum] -= 1
					if numHash[nextNum] == 0:
						del numHash[nextNum]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W:
			return False
		counter = Counter(hand)
		keys = set(counter.keys())
		while counter:
			key = min(keys)
			while key in keys:
				for w in range(W):
					if key + w not in counter:
						return False
					counter[key + w] -= 1
					if counter[key + w] == 0:
						del counter[key + w]
						keys.remove(key + w)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counted = {}
		for i in hand:
			if i not in counted:
				counted[i] = 0
			counted[i] += 1

		def containStrait(numbers, counted, W):
			if len(counted) == 0:
				return True
			if len(numbers) < W:
				return False
			if numbers[W - 1] - numbers[0] > W:
				return False
			else:
				for i in reversed(range(W)):
					counted[numbers[i]] -= 1
					if counted[numbers[i]] == 0:
						counted.pop(numbers[i])
						numbers.remove(numbers[i])
			return containStrait(numbers, counted, W)
		numbers = sorted(counted.keys())
		return containStrait(numbers, counted, W)


import collections

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if W < 1:
			return False
		if len(hand) % W != 0:
			return False
		counter = collections.Counter(hand)
		sorted(counter.items(), key=lambda i: i[0])
		dic = {}
		dic = collections.OrderedDict(sorted(dict(counter).items()))
		while dic:
			dic_list = list(dic.keys())
			base = dic_list[0]
			for i in range(W):
				if base + i not in dic:
					return False
				dic[base + i] -= 1
				if dic[base + i] == 0:
					dic.pop(base + i, None)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = Counter(hand)
		heap_hands = []
		groups = []
		for (k, v) in counter.items():
			heapq.heappush(heap_hands, (k, v))
		while heap_hands:
			count = 0
			sub_group = []
			remaining_elements = []
			while count < W:
				if not heap_hands:
					return False
				popped_elem = heapq.heappop(heap_hands)
				if popped_elem[1] - 1 > 0:
					remaining_elements.append(popped_elem)
				if not sub_group:
					sub_group.append(popped_elem[0])
				elif popped_elem[0] - 1 == sub_group[-1]:
					sub_group.append(popped_elem[0])
				else:
					return False
				count += 1
			groups += sub_group
			for elem in remaining_elements:
				heapq.heappush(heap_hands, (elem[0], elem[1] - 1))
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) < W or len(hand) % W != 0:
			return False
		count = Counter(hand)
		while count:
			item = min(count)
			if count[item] == 1:
				del count[item]
			else:
				count[item] -= 1
			i = 1
			while i < W:
				item += 1
				i += 1
				if item not in count:
					return False
				if count[item] == 1:
					del count[item]
				else:
					count[item] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		if len(hand) % W != 0:
			return False
		while hand:
			z = min(hand)
			for t in range(z, z + W):
				try:
					hand.remove(t)
				except:
					return False
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		count_dict = Counter(hand)
		while count_dict:
			m = min(count_dict)
			for i in range(m, m + W):
				if i not in count_dict:
					return False
				elif count_dict[i] == 1:
					del count_dict[i]
				else:
					count_dict[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, nums: List[int], W: int) -> bool:
		n = len(nums)
		if n % W != 0:
			return False
		nums.sort()
		dic = OrderedDict()
		for num in nums:
			dic[num] = dic.get(num, 0) + 1
		while dic:
			m = min(dic)
			for i in range(m, m + W):
				val = dic.get(i)
				if not val:
					return False
				if val == 1:
					del dic[i]
				else:
					dic[i] -= 1
		return True


import collections

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		handCounter = Counter()
		for number in hand:
			handCounter[number] += 1
		while len(handCounter) != 0:
			m = min(handCounter.keys())
			for i in range(m, m + W):
				if i not in handCounter:
					return False
				handCounter[i] -= 1
				if handCounter[i] == 0:
					del handCounter[i]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		cardCount = {}
		for card in hand:
			if not card in cardCount:
				cardCount[card] = 0
			cardCount[card] += 1
		k = len(hand) // W
		for i in range(k):
			start = min(cardCount.keys())
			for j in range(W):
				if not start + j in cardCount:
					return False
			for j in range(W):
				cardCount[start + j] -= 1
				if cardCount[start + j] == 0:
					cardCount.pop(start + j)
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = Counter(hand)
		while counter:
			key = min(counter)
			for x in range(key, key + W):
				if counter[x] < 1:
					return False
				counter[x] -= 1
				if counter[x] == 0:
					del counter[x]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()

		def helper(hand):
			if not hand:
				return
			if len(hand) % W != 0:
				self.ans = False
				return
			n = len(hand)
			(i, k) = (0, 0)
			prev = hand[0] - 1
			new_hand = []
			while i < n and k < W:
				if hand[i] == prev:
					new_hand.append(hand[i])
				elif hand[i] != prev + 1:
					self.ans = False
					return
				else:
					prev += 1
					k += 1
				i += 1
			new_hand += hand[i:]
			if not new_hand:
				self.ans = True
				return
			return helper(new_hand)
		helper(hand)
		return self.ans


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = Counter(hand)
		result = []
		while count:
			m = min(count)
			straights = []
			for i in range(m, m + W):
				if i in count:
					straights.append(i)
					count[i] -= 1
					if count[i] == 0:
						del count[i]
				else:
					return False
			result.append(straights)
		print(result)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = collections.Counter(hand)
		while counter:
			smallest = min(counter)
			for j in range(smallest, smallest + W):
				if j not in counter:
					return False
				counter[j] -= 1
				if counter[j] == 0:
					del counter[j]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = collections.Counter(hand)
		dic = collections.OrderedDict(sorted(count.items()))
		while dic:
			m = next(iter(dic))
			for k in range(m, m + W):
				v = dic.get(k)
				print(v, k)
				if not v:
					return False
				if v == 1:
					del dic[k]
				else:
					dic[k] = v - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = collections.Counter(hand)
		s = set(hand)
		while s:
			minv = min(s)
			for i in range(minv, minv + W):
				if i not in counter or counter[i] == 0:
					return False
				counter[i] -= 1
				if counter[i] == 0:
					s.remove(i)
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		c = Counter(hand)
		while c:
			j = min(c)
			for i in range(j, j + W):
				if not c[i]:
					return False
				if c[i] == 1:
					del c[i]
				else:
					c[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = Counter(hand)
		while counter:
			start = min(counter)
			for n in range(start, start + W):
				if n in counter:
					counter[n] -= 1
					if counter[n] == 0:
						del counter[n]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W != 0:
			return False
		hand = sorted(hand)
		counts = collections.Counter(hand)
		print(counts)
		while sum(counts.values()) > 0:
			start_card = min(counts)
			print(start_card)
			for card in range(start_card, start_card + W):
				if card not in counts:
					return False
				counts[card] -= 1
				if counts[card] == 0:
					del counts[card]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand = collections.Counter(hand)
		while True:
			if len(hand) == 0:
				return True
			m = min(hand)
			for c in range(m, m + W):
				if c not in hand:
					return False
				if hand[c] == 1:
					del hand[c]
				else:
					hand[c] -= 1


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W != 0:
			return False
		count = collections.Counter(hand)
		while n > 0:
			a = min(count)
			for i in range(W):
				if count[a + i] <= 0:
					return False
				count[a + i] -= 1
				if count[a + i] == 0:
					del count[a + i]
			n -= W
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = Counter(hand)
		count = W
		while counter:
			if count == W:
				count = 0
				val = min(counter)
			else:
				val += 1
				if not counter[val]:
					return False
			counter[val] -= 1
			if not counter[val]:
				del counter[val]
			count += 1
		return count == W


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand or len(hand) % W != 0:
			return False
		hand_dict = self.get_hand_dict(hand)
		return self.is_n_straigh_hand(hand_dict, W)

	def is_n_straigh_hand(self, hand_dict, W):
		while hand_dict:
			start_hand = min(hand_dict)
			count = hand_dict[start_hand]
			for i in range(start_hand, W + start_hand):
				if i not in hand_dict:
					return False
				else:
					hand_dict[i] -= count
					if hand_dict[i] == 0:
						del hand_dict[i]
					elif hand_dict[i] < 0:
						return False
		return True

	def get_hand_dict(self, hand):
		hand_dict = {}
		for h in hand:
			hand_dict[h] = hand_dict.get(h, 0)
			hand_dict[h] += 1
		return hand_dict


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = collections.Counter(hand)
		while count:
			mins = min(count)
			for i in range(mins, mins + W):
				if not count[i]:
					return False
				if count[i] == 1:
					del count[i]
				else:
					count[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		N = len(hand)
		if N % W != 0:
			return False
		counts = collections.Counter(hand)
		while counts:
			card = min(counts.keys())
			for _ in range(W):
				if card not in counts:
					return False
				counts[card] -= 1
				if counts[card] == 0:
					del counts[card]
				card += 1
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		cs = Counter(hand)
		while cs:
			card = next((card for card in cs if card - 1 not in cs)) - 1
			l = -1
			while (l := (l + 1)) < W and cs[(card := (card + 1))]:
				cs[card] -= 1
				if cs[card] == 0:
					del cs[card]
			if l != W:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W:
			return False
		counter = dict()
		for h in hand:
			temp = counter.get(h, 0)
			temp += 1
			counter[h] = temp
		while counter:
			start = min(counter.keys())
			for k in range(start, start + W):
				v = counter.get(k)
				if not v:
					return False
				if v == 1:
					del counter[k]
				else:
					counter[k] = v - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W != 0:
			return False
		c = collections.Counter(hand)
		while c:
			k = min(c)
			v = c[k]
			del c[k]
			for i in range(1, W):
				if c[k + i] < v:
					return False
				else:
					c[k + i] -= v
					if c[k + i] == 0:
						del c[k + i]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		card_dict = dict()
		for card in hand:
			if card in card_dict:
				card_dict[card] = card_dict[card] + 1
			else:
				card_dict[card] = 1
		while len(card_dict) > 0:
			min_ele = min(card_dict.keys())
			for i in range(W):
				if not min_ele in card_dict:
					return False
				elif card_dict[min_ele] > 1:
					card_dict[min_ele] = card_dict[min_ele] - 1
				else:
					del card_dict[min_ele]
				min_ele = min_ele + 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		flag = 0
		while len(hand) > 0 and flag == 0:
			temp = []
			start = hand[0]
			temp.append(start)
			for i in range(1, W):
				if start + i in hand:
					temp.append(start + i)
				else:
					flag = 1
					break
			for x in temp:
				hand.remove(x)
		if flag == 0:
			return True
		else:
			return False


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = Counter(hand)
		while count:
			init = min(count.keys())
			if count[init] == 1:
				del count[init]
			else:
				count[init] = count[init] - 1
			for i in range(1, W):
				v = count[init + 1]
				if init + 1 in count.keys():
					if v == 1:
						del count[init + 1]
					else:
						count[init + 1] = v - 1
				else:
					return False
				init = init + 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		freq_dict = collections.Counter(hand)
		while freq_dict:
			min_num = min(freq_dict)
			for i in range(min_num, min_num + W):
				freq = freq_dict[i]
				if freq == 0:
					return False
				elif freq == 1:
					del freq_dict[i]
				else:
					freq_dict[i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		dic = collections.Counter(hand)
		while dic:
			m = next(iter(dic))
			for k in range(m, m + W):
				v = dic.get(k)
				if not v:
					return False
				if v == 1:
					del dic[k]
				else:
					dic[k] = v - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = Counter(hand)
		for i in range(len(hand) // W):
			minimum = min(counter.keys())
			for number in range(minimum, minimum + W):
				if number not in counter:
					return False
				counter[number] -= 1
				if counter[number] == 0:
					del counter[number]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		last = -1
		j = 0
		changed = False
		while hand:
			if hand[0] == last + 1 or last == -1:
				changed = False
				last = hand.pop(0)
				j += 1
				if j % W == 0:
					last = -1
			elif not changed:
				for i in range(1, len(hand)):
					if hand[i] <= last + 1:
						(hand[i], hand[0]) = (hand[0], hand[i])
					else:
						break
				changed = True
			else:
				return False
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		parts = len(hand) / W
		cnt = Counter(hand)
		cnt = sorted(cnt.items())
		heapq.heapify(cnt)
		while cnt:
			hand = []
			while len(hand) != W:
				if not cnt:
					return False
				(card, count) = heapq.heappop(cnt)
				if hand:
					(last_card, last_count) = hand[-1]
					if last_card != card - 1:
						return False
				hand.append((card, count))
			for (card, count) in hand:
				count -= 1
				if count:
					heapq.heappush(cnt, (card, count))
		return True


import heapq

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		l = len(hand)
		if l == 0 or l % W != 0:
			return False
		counter = collections.Counter(hand)
		pos = 0
		while pos < l:
			currMin = min(counter.keys())
			counter[currMin] -= 1
			pos += 1
			if counter[currMin] == 0:
				del counter[currMin]
			for i in range(W - 1):
				nextDraw = currMin + i + 1
				if nextDraw in counter and counter[nextDraw] > 0:
					counter[nextDraw] -= 1
					pos += 1
					if counter[nextDraw] == 0:
						del counter[nextDraw]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		l = len(hand)
		if l % W != 0:
			return False
		d = {}
		for i in range(l):
			if hand[i] not in d:
				d[hand[i]] = 1
			else:
				d[hand[i]] += 1
		while d:
			num = min(d)
			j = 1
			while num + 1 in d and j != W:
				j += 1
				num = num + 1
			if j == W:
				num = min(d)
				for k in range(W):
					if d[num] == 1:
						del d[num]
					else:
						d[num] -= 1
					num += 1
			else:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand = sorted(hand)
		for split in range(len(hand) // W):
			min_val = min(hand)
			hand.remove(min_val)
			for i in range(1, W):
				if min_val + 1 not in hand:
					return False
				else:
					min_val += 1
					hand.remove(min_val)
		return True


class Solution:

	def isNStraightHand(self, hand, W):
		if len(hand) % W != 0:
			return False
		hand = sorted(hand)
		cnt = {}
		for card in hand:
			if card not in cnt:
				cnt[card] = 0
			cnt[card] += 1
		cur_len = 0
		last_val = -1
		num_sub_hands = 0
		unique_vals = sorted(set(hand))
		flag = True
		loops = 0
		while len(cnt) and flag and (num_sub_hands < len(hand) // W):
			flag = False
			tmp = sorted(set(unique_vals))
			for element in tmp:
				loops += 1
				if last_val == -1 or element == last_val + 1:
					last_val = element
					cnt[element] -= 1
					cur_len += 1
					flag = True
				if cnt[element] == 0:
					del cnt[element]
					unique_vals.remove(element)
				if cur_len == W:
					last_val = -1
					cur_len = 0
					num_sub_hands += 1
					break
		return len(cnt) == 0 and num_sub_hands == len(hand) // W


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		dic = collections.Counter(hand)
		print((dic, min(dic), dic[10]))
		while dic:
			m = min(dic)
			for num in range(m, m + W):
				if dic[num] == 0:
					return False
				if dic[num] == 1:
					del dic[num]
				else:
					dic[num] = dic[num] - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand = sorted(hand)
		forward = list(range(1, len(hand)))
		forward.append(None)
		backward = [None]
		backward.extend(list(range(0, len(hand) - 1)))
		ptr = 0
		while ptr is not None:
			firstSkipped = None
			for i in range(W):
				if ptr is None:
					return False
				currHand = hand[ptr]
				prev = backward[ptr]
				forw = forward[ptr]
				if prev is not None:
					forward[prev] = forw
				if forw is not None:
					backward[forw] = prev
				forward[ptr] = backward[ptr] = None
				ptr = forw
				while ptr is not None and hand[ptr] == currHand:
					if firstSkipped is None:
						firstSkipped = ptr
					ptr = forward[ptr]
				if ptr is not None and i != W - 1 and (hand[ptr] - 1 != currHand):
					return False
			if firstSkipped is not None:
				ptr = firstSkipped
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		l = len(hand)
		if l % W != 0:
			return False
		cards = Counter(hand)
		keys = sorted(list(cards.keys()))
		start = keys[0]
		start_idx = 0
		for _ in range(l // W):
			cards[start] -= 1
			for i in range(start + 1, start + W):
				if i not in keys or cards[i] == 0:
					return False
				else:
					cards[i] -= 1
			while cards[start] == 0 and start_idx < len(keys) - 1:
				start_idx += 1
				start = keys[start_idx]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counts = defaultdict(int)
		for number in hand:
			counts[number] += 1
		ordered_numbers = sorted(counts.keys())
		while counts:
			group = []
			for number in ordered_numbers:
				if number not in counts:
					continue
				if counts[number] > 0:
					if group:
						if group[-1] != number - 1:
							return False
					group.append(number)
					counts[number] -= 1
				else:
					del counts[number]
				if len(group) == W:
					break
			if group and len(group) != W:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		d = collections.defaultdict(int)
		for i in hand:
			d[i] += 1
		while d:
			l = list(d)
			heapq.heapify(l)
			prev = None
			for i in range(W):
				if len(l) == 0:
					return False
				ele = heapq.heappop(l)
				if prev is not None:
					if ele - prev > 1:
						return False
				prev = ele
				if d[ele] == 1:
					del d[ele]
				else:
					d[ele] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand = sorted(hand)
		indices = {}
		for index in reversed(list(range(len(hand)))):
			num = hand[index]
			if num not in indices:
				indices[num] = [index]
			else:
				indices[num].append(index)
		while len(indices) != 0:
			first = None
			for num in hand:
				if num in indices:
					first = num
					break
			for i in range(W):
				num = first + i
				if num in indices:
					indices[num].pop()
					if len(indices[num]) == 0:
						del indices[num]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand or not W:
			return False
		_map = defaultdict(list)
		for i in range(len(hand)):
			_map[hand[i]] += [i]
		while _map:
			hand = [k for (k, _) in list(_map.items())]
			top = min(hand)
			_map[top].pop()
			if not _map[top]:
				del _map[top]
			i = 1
			while hand and i < W:
				top += 1
				if top not in _map:
					return False
				_map[top].pop()
				if not _map[top]:
					del _map[top]
				i += 1
			if i < W:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		l = len(hand)
		if l % W != 0:
			return False
		if W == 1:
			return True
		ct = Counter(hand)
		lst = sorted(list(ct.keys()))
		for l in lst:
			if l - 1 not in lst and l + 1 not in lst:
				return False
		while lst:
			begin = lst[0]
			ct[begin] -= 1
			if ct[begin] == 0:
				lst.pop(0)
			for i in range(1, W):
				if begin + i not in ct:
					return False
				else:
					ct[begin + i] -= 1
					if ct[begin + i] == 0:
						lst.remove(begin + i)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		if len(hand) == 0:
			return True
		hand = sorted(hand)
		seed = hand[0]
		for i in range(1, W):
			if seed + i not in hand:
				return False
		for i in range(0, W):
			hand.remove(seed + i)
		return self.isNStraightHand(hand, W)


from collections import OrderedDict

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if W == 1:
			return True
		if len(hand) % W:
			return False
		hand.sort()
		od = OrderedDict()
		for h in hand:
			if h in od:
				od[h] += 1
			else:
				od[h] = 1
		k = list(od.keys())[0]
		n = list(od.values())[0]
		while True:
			for i in range(W):
				if k + i in od and od[k + i] >= n:
					od[k + i] -= n
					if od[k + i] == 0:
						del od[k + i]
				else:
					return False
			if len(od) == 0:
				break
			k = list(od.keys())[0]
			n = list(od.values())[0]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = collections.Counter(hand)
		d = collections.OrderedDict(sorted(counter.items()))
		count = 0
		while count < len(d):
			group = []
			for card in d.keys():
				if d[card] == 0:
					continue
				if not group or (len(group) < W and group[-1] + 1 == card):
					group.append(card)
					d[card] -= 1
					if d[card] == 0:
						count += 1
				if len(group) == W:
					break
			else:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		while hand != []:
			minele = min(hand)
			for i in range(0, W):
				try:
					hand.remove(minele + i)
				except:
					return False
		return True


import heapq
import collections

class Solution:

	def isNStraightHand(self, hand, W) -> bool:
		if len(hand) % W != 0:
			return False
		counter_map = collections.Counter(hand)
		counter = 0
		heapq.heapify(hand)
		while hand:
			min_val = heapq.heappop(hand)
			next_val = min_val + 1
			counter += 1
			while counter < W and counter_map.get(next_val, 0) > 0:
				counter_map[next_val] -= 1
				hand.remove(next_val)
				counter += 1
				next_val += 1
			if counter < W:
				return False
			counter = 0
			heapq.heapify(hand)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) < W or len(hand) % W != 0:
			return False
		d = {}
		for i in hand:
			d[i] = d.get(i, 0) + 1
		keys = sorted(list(d.keys()))
		for i in keys:
			if d[i] == 0:
				continue
			while d[i] > 0:
				for j in range(i, i + W):
					if j not in keys or d[j] <= 0:
						return False
					else:
						d[j] = d[j] - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		c = collections.Counter(hand)
		for i in sorted(c):
			if c[i] > 0:
				for j in range(W)[::-1]:
					c[i + j] -= c[i]
					if c[i + j] < 0:
						return False
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W:
			return False
		cnt = Counter(hand)
		cards = sorted(cnt)
		while True:
			first = cards.pop()
			if not cnt[first]:
				continue
			amount = cnt[first]
			del cnt[first]
			for i in range(first - 1, first - W, -1):
				if not cnt[i]:
					return False
				cnt[i] -= amount
				if cnt[i] < 0:
					return False
				elif cnt[i] == 0:
					del cnt[i]
			if not cnt:
				return True
		return False


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W != 0:
			return False
		counter = Counter(hand)
		nums = sorted(counter.keys())
		for num in nums:
			count = counter[num]
			if count == 0:
				continue
			min_count = count
			for i in range(W):
				if count[num + i] < min_count:
					return False
				count[num + i] -= min_count
		return True

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		counter = Counter(hand)
		q = []
		for (num, freq) in list(counter.items()):
			heapq.heappush(q, (num, freq))
		while q and len(q) >= W:
			tmp = []
			for i in range(W):
				x = heapq.heappop(q)
				if tmp and tmp[-1][0] + 1 != x[0]:
					return False
				tmp.append(x)
			for (num, freq) in tmp:
				if freq > 1:
					heapq.heappush(q, (num, freq - 1))
		return 0 == len(q)

	def isNStraightHand4(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		q = []
		for num in hand:
			if q and q[-1][0] == num:
				q[-1][1] += 1
			else:
				q.append([num, 1])
		n = len(hand)
		while n > 0:
			if len(q) < W:
				return False
			for i in range(1, W):
				if q[i][0] != q[i - 1][0] + 1:
					return False
			j = 0
			for i in range(W):
				if q[j][1] == 1:
					q.pop(j)
				else:
					q[j][1] -= 1
					j += 1
			n -= W
		return len(q) == 0

	def isNStraightHand3(self, hand: List[int], W: int) -> bool:
		counter = Counter(hand)
		while counter:
			m = min(counter)
			for k in range(m, m + W):
				v = counter[k]
				if not v:
					return False
				if v == 1:
					del counter[k]
				else:
					counter[k] = v - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		while len(hand) > 0:
			val = hand.pop(0)
			for j in range(W - 1):
				try:
					val += 1
					indx = hand.index(val)
					hand.pop(indx)
				except:
					return False
		return True


from collections import Counter, deque

class Solution:

	def isNStraightHand(self, hand, W):
		cnts = Counter(hand)
		for num in sorted(cnts):
			tmp = cnts[num]
			if tmp > 0:
				for j in range(num, num + W):
					cnts[j] -= tmp
					if cnts[j] < 0:
						return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count_map = Counter()
		for num in hand:
			count_map[num] += 1
		test = sorted(count_map)
		sorted_hand = sorted(dict.fromkeys(hand))
		while len(sorted_hand) > 0:
			while len(sorted_hand) > 0 and count_map[sorted_hand[0]] == 0:
				sorted_hand.pop(0)
			if len(sorted_hand) > 0:
				for key in range(sorted_hand[0], sorted_hand[0] + W):
					if key in count_map:
						count_map[key] -= 1
						if count_map[key] < 0:
							return False
					else:
						return False
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		cards = Counter(hand)
		for card in sorted(hand):
			if cards[card] > 0:
				for i in range(W):
					if card + i not in cards or cards[card + i] == 0:
						return False
					cards[card + i] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) == 0:
			return False
		if len(hand) % W > 0:
			return False
		count = {}
		for n in hand:
			if n not in count:
				count[n] = 1
			else:
				count[n] += 1
		total = sum(count.values())
		for n in sorted(hand):
			if total == 0:
				break
			if count[n] == 0:
				continue
			for i in range(W):
				target = n + i
				if target in count and count[target] > 0:
					count[target] -= 1
					total -= 1
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		while hand:
			curr = hand[0]
			try:
				for i in range(W):
					hand.remove(curr)
					curr += 1
			except:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand = sorted(hand)
		dct = {}
		for x in hand:
			if x not in dct:
				dct[x] = 1
			else:
				dct[x] += 1
		while len(hand) > 0:
			group = [hand[0]]
			check = hand[0]
			hand.remove(check)
			while len(group) < W:
				if check + 1 not in dct or dct[check + 1] < 1:
					return False
				group.append(check + 1)
				hand.remove(check + 1)
				dct[check + 1] -= 1
				check += 1
		return True


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		counter = Counter(hand)
		for key in sorted(counter):
			if counter[key] > 0:
				for i in range(1, W):
					counter[key + i] -= counter[key]
					if counter[key + i] < 0:
						return False
				counter[key] = 0
		return True


class Solution:

	def isNStraightHand(self, hand, W):
		nums = len(hand)
		if nums % W:
			return False
		elif W == 1:
			return True
		else:
			heapify(hand)
			arrange = deque()
			lastOp = [0, -1]
			groups = 0
			while hand:
				h = heappop(hand)
				i = 0
				if h == lastOp[1]:
					i = lastOp[0] + 1
				if len(arrange) < i + 1:
					arrange.append([])
					groups += 1
				if groups > nums // W:
					return False
				if len(arrange[i]) and arrange[i][-1] + 1 != h:
					return False
				else:
					arrange[i].append(h)
					lastOp = [i, h]
				if len(arrange[i]) == W:
					arrange.popleft()
					lastOp = [0, -1]
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand:
			return False
		if len(hand) % W != 0:
			return False
		hand.sort()
		n = len(hand)
		dic = Counter(hand)
		cards = list(dic.keys())
		cards.sort()
		for c in cards:
			num = dic[c]
			if num == 0:
				continue
			for i in range(1, W):
				if c + i in dic and dic[c + i] >= num:
					dic[c + i] -= num
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		heapq.heapify(hand)
		while hand:
			last_item = heapq.heappop(hand)
			leftover = []
			for _ in range(W - 1):
				if not hand:
					return False
				next_item = heapq.heappop(hand)
				while next_item == last_item:
					leftover.append(next_item)
					if not hand:
						return False
					next_item = heapq.heappop(hand)
				if next_item > last_item + 1:
					return False
				last_item = next_item
			for item in leftover:
				heapq.heappush(hand, item)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W:
			return False
		if W == 1:
			return True
		counts = collections.Counter(hand)
		for num in sorted(hand):
			if not counts[num]:
				continue
			for next in range(num, num + W):
				if next not in counts or not counts[next]:
					return False
				counts[next] -= 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		dic = {}
		for num in hand:
			if num not in dic:
				dic[num] = 1
			else:
				dic[num] += 1
		hand.sort()
		while len(hand) > 0:
			smallest = hand[0]
			dic[smallest] -= 1
			for i in range(1, W):
				check = smallest + i
				if check not in dic:
					return False
				elif dic[check] <= 0:
					return False
				else:
					dic[check] -= 1
					hand.remove(check)
			hand.remove(smallest)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		count = {}
		for h in hand:
			if h not in count:
				count[h] = 1
			else:
				count[h] += 1
		key = list(count.keys())
		print(count)
		head = 0
		while head < len(key):
			this_key = key[head]
			if count[this_key] == 0:
				head += 1
				continue
			tail = head + 1
			while tail < len(key) and tail < head + W:
				if count[key[tail]] >= count[this_key] and key[tail] == key[tail - 1] + 1:
					count[key[tail]] -= count[this_key]
				else:
					return False
				tail += 1
			if tail < head + W:
				return False
			count[this_key] = 0
			head += 1
		return True


class Solution:

	def isNStraightHand(self, hand, W):
		nums = len(hand)
		if nums % W:
			return False
		elif W == 1:
			return True
		else:
			heapify(hand)
			arrange = [[] for _ in range(nums // W)]
			start = 0
			while hand:
				h = heappop(hand)
				i = start
				while True:
					if len(arrange[i]) == W:
						i += 1
						start = i
					if len(arrange[i]) == 0 or (arrange[i] and arrange[i][-1] != h):
						arrange[i].append(h)
					elif arrange[i] and arrange[i][-1] == h:
						if i + 1 == len(arrange):
							return False
						i += 1
						continue
					if len(arrange[i]) > 1 and arrange[i][-2] + 1 != arrange[i][-1]:
						return False
					else:
						break
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		(straights, pq) = ([], [])
		for h in hand:
			heapq.heappush(pq, h)
		while len(pq) > 0:
			(straight, dump) = ([], [])
			while len(pq) > 0 and len(straight) < W:
				pop = heapq.heappop(pq)
				if len(straight) == 0 or pop == straight[-1] + 1:
					straight.append(pop)
				else:
					dump.append(pop)
			straights.append(straight)
			if len(straight) < W:
				return []
			else:
				for d in dump:
					heapq.heappush(pq, d)
		return len(straights) > 0


class Solution:

	def isNStraightHand(self, h, W):
		l = len(h)
		if l % W != 0:
			return False
		heapify(h)
		c = Counter(h)
		for _ in range(l // W):
			x = heappop(h)
			while c[x] == 0:
				x = heappop(h)
			for _ in range(W):
				if c[x] == 0:
					return False
				c[x] -= 1
				x += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		i = 0
		hand.sort()
		while hand:
			for j in range(1, W):
				if hand[i] + j not in hand:
					return False
				hand.pop(hand.index(hand[i] + j))
			hand.pop(i)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		while hand:
			start = hand[0]
			hand.remove(start)
			for i in range(W - 1):
				start += 1
				if start in hand:
					hand.remove(start)
				else:
					return False
		return len(hand) == 0


import collections
import heapq

class Solution:

	def checkConsecutives(self, nums):
		pos = 0
		while pos < len(nums) - 1:
			if nums[pos][0] + 1 != nums[pos + 1][0]:
				return False
			pos += 1
		return True

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		min_heap = []
		heapq.heapify(min_heap)
		num_dict = collections.Counter(hand)
		for (key, val) in list(num_dict.items()):
			heapq.heappush(min_heap, (key, val))
		while min_heap:
			consec = []
			for _ in range(W):
				if not min_heap:
					return False
				consec.append(list(heapq.heappop(min_heap)))
			if self.checkConsecutives(consec):
				pos = 0
				while pos < len(consec):
					if consec[pos][1] - 1 <= 0:
						consec.pop(pos)
						continue
					else:
						consec[pos][1] -= 1
					pos += 1
				pos = 0
				while pos < len(consec):
					heapq.heappush(min_heap, tuple(consec[pos]))
					pos += 1
			else:
				return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W:
			return False
		C = Counter(hand)
		keys = sorted(C.keys())
		output = []
		for i in range(n // W):
			mn = keys[0]
			straight = []
			for j in range(mn, mn + W):
				if j not in keys:
					return False
				else:
					C[j] -= 1
					straight.append(j)
					if C[j] == 0:
						del C[j]
						keys.remove(j)
			output.append(straight)
		print(output)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand or len(hand) % W != 0:
			return False
		counter = Counter(hand)
		for c in sorted(counter):
			if counter[c] > 0:
				for i in range(W)[::-1]:
					counter[c + i] -= counter[c]
					if counter[c + i] < 0:
						return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand.sort()
		if len(hand) % W != 0:
			return False
		else:
			for i in range(len(hand) // W):
				tmp = hand.pop(0)
				for j in range(W - 1):
					if tmp + j + 1 in hand:
						hand.pop(hand.index(tmp + j + 1))
					else:
						return False
			print(hand)
			if len(hand) == 0:
				return True
			else:
				return False


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand:
			return W == 0
		if len(hand) % W != 0:
			return False
		hand.sort()

		def isnstraighthand(li):
			if not li:
				return True
			start = li[0]
			for i in range(start, start + W):
				if i not in li:
					return False
				else:
					li.remove(i)
			return isnstraighthand(li)
		return isnstraighthand(hand)


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		length = len(hand)
		count = 0
		group = []
		while 1:
			for i in range(W - 1):
				if hand[0] + i + 1 in hand:
					count += 1
					hand.pop(hand.index(hand[0] + i + 1))
				else:
					return False
			hand.pop(0)
			if len(hand) == 0:
				return True


class Solution:
	import heapq

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if W == 1:
			return True
		if len(hand) % W:
			return False
		hand.sort()
		heap = []
		for n in hand:
			if not heap:
				heapq.heappush(heap, (n, 1))
			else:
				(curr, size) = heap[0]
				if n == curr:
					heapq.heappush(heap, (curr, 1))
				elif n == curr + 1:
					heapq.heappop(heap)
					size += 1
					if size < W:
						heapq.heappush(heap, (n, size))
				else:
					return False
		return bool(not heap)


from collections import OrderedDict

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		card_counts = OrderedDict()
		for i in range(len(hand)):
			card_counts[hand[i]] = card_counts.get(hand[i], 0) + 1
		keys = sorted(card_counts.keys())
		while card_counts:
			min_val = keys[0]
			for hand in range(min_val, min_val + W):
				if hand not in card_counts:
					return False
				count = card_counts[hand]
				if count == 1:
					keys.pop(0)
					del card_counts[hand]
				else:
					card_counts[hand] -= 1
		return True


class Solution:
	import heapq

	def isNStraightHand(self, hand, W):
		heapq.heapify(hand)
		while len(hand) > 0:
			put_back = []
			count = 0
			prev = hand[0] - 1
			while count < W:
				if len(hand) == 0:
					return False
				v = heapq.heappop(hand)
				if v != prev + 1:
					put_back.append(v)
				else:
					prev = v
					count += 1
			for element in put_back:
				heapq.heappush(hand, element)
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hmap = {}
		for h in hand:
			if h not in hmap:
				hmap[h] = 0
			hmap[h] += 1
		cards = sorted(list(hmap.keys()))
		for card in cards:
			while card in hmap:
				for n in range(card, card + W):
					if n not in hmap:
						return False
					else:
						hmap[n] -= 1
						if hmap[n] == 0:
							del hmap[n]
		if hmap:
			return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if not hand:
			return False
		hand = sorted(hand)
		(queue, rs, group) = ([], [], [])
		while hand:
			card = hand.pop(0)
			if not group or group[-1] == card - 1:
				group.append(card)
				if len(group) == W:
					hand = queue + hand
					rs.append(group)
					(group, queue) = ([], [])
			else:
				queue.append(card)
		if not group and (not queue):
			return True
		else:
			return False


from collections import Counter

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		n = len(hand)
		if n % W != 0:
			return False
		occurmap = Counter(hand)
		tots = 0
		hand.sort()
		for i in range(n):
			v = hand[i]
			if occurmap[v - 1] > 0 or occurmap[v] <= 0:
				continue
			count = 1
			occurmap[v] -= 1
			while count < W and occurmap[v + 1] > 0:
				count += 1
				occurmap[v + 1] -= 1
				v = v + 1
			if count == W:
				tots += 1
		if tots * W == n:
			return True
		return False


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		sorted_hand = hand
		sorted_hand.sort()
		num_groups = int(len(hand) / W)
		for i in range(num_groups):
			num = sorted_hand[0]
			sorted_hand.remove(num)
			for j in range(W - 1):
				num += 1
				if num in sorted_hand:
					sorted_hand.remove(num)
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		(counter, smallest) = self.counter(hand)
		for _ in range(len(hand) // W):
			if smallest is None:
				smallest = min(counter)
			curr = smallest
			counter[curr] -= 1
			if counter[curr] == 0:
				del counter[curr]
				smallest = None
			for _ in range(W - 1):
				curr = curr + 1
				if curr not in counter:
					return False
				else:
					counter[curr] -= 1
					if counter[curr] == 0:
						del counter[curr]
					elif smallest is None:
						smallest = curr
		return True

	def counter(self, array):
		smallest = None
		counter = {}
		for el in array:
			if el in counter:
				counter[el] += 1
			else:
				counter[el] = 1
				if smallest is None or el < smallest:
					smallest = el
		return (counter, smallest)


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if W == 1:
			return True
		sorted_indexes = []
		frequency_map = {}
		for h in hand:
			if h not in list(frequency_map.keys()):
				frequency_map[h] = 1
				self.addToSortedList(h, sorted_indexes)
			else:
				frequency_map[h] += 1
		print((sorted_indexes, frequency_map))
		index = 0
		while index < len(sorted_indexes):
			for ele in range(sorted_indexes[index], sorted_indexes[index] + W):
				if ele not in list(frequency_map.keys()) or frequency_map[ele] == 0:
					return False
				frequency_map[ele] -= 1
			while index < len(sorted_indexes) and frequency_map[sorted_indexes[index]] == 0:
				frequency_map.pop(sorted_indexes[index])
				index += 1
		return len(list(frequency_map.keys())) == 0

	def addToSortedList(self, value: int, sorted_list: List[int]):
		if len(sorted_list) == 0:
			sorted_list.append(value)
			return
		low = 0
		high = len(sorted_list) - 1
		while low < high:
			mid = math.floor((low + high) / 2)
			if value < sorted_list[mid]:
				high = mid - 1
			elif value > sorted_list[mid]:
				low = mid + 1
		if high < 0:
			sorted_list.insert(0, value)
		elif value > sorted_list[high]:
			sorted_list.insert(high + 1, value)
		else:
			sorted_list.insert(high, value)


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		ogLen = len(hand)
		if W == 1:
			return True
		counter = Counter(hand)
		counted = [(key, counter[key]) for key in counter]
		counted.sort()
		print(counted)
		heapify(counted)
		groups = []
		group = []
		group.append(heappop(counted))
		tempStorage = set()
		while counted:
			n0 = group[-1]
			if n0[0] + 1 == counted[0][0]:
				n1 = heappop(counted)
			elif counted[0][0] > n0[0] + 1:
				group = []
				group.append(heappop(counted))
				continue
			group.append(n1)
			if len(group) == W:
				groups.append(group)
				for (val, count) in group:
					count -= 1
					if count != 0:
						heappush(counted, (val, count))
				group = []
				if counted:
					group.append(heappop(counted))
		print((len(groups) * W, ogLen))
		return len(groups) * W == ogLen


from collections import defaultdict

class Solution:

	def isNStraightHand(self, hand: List[int], k: int) -> bool:
		if len(hand) < k or len(hand) % k != 0:
			return False
		if k == 1:
			return True
		hand.sort()
		queue = deque(hand)
		q2 = deque()
		currVal = -1
		currNum = 0
		for i in range(len(hand) // k):
			while currNum < k:
				if not queue:
					return False
				if currVal == -1:
					currVal = queue.popleft()
					currNum += 1
					continue
				val = queue.popleft()
				if val == currVal + 1:
					currVal = val
					currNum += 1
				elif val > currVal + 1:
					return False
				elif val == currVal:
					q2.append(val)
			queue = q2 + queue
			q2 = deque()
			currVal = -1
			currNum = 0
		return True


from collections import defaultdict

class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		if W == 1:
			return True
		hand.sort()
		freq = defaultdict(int)
		for c in hand:
			freq[c] += 1
		while len(freq) != 0:
			keys = list(freq.keys())
			if len(keys) < W:
				return False
			for i in range(W - 1):
				if keys[i] + 1 != keys[i + 1]:
					return False
				freq[keys[i]] -= 1
				if freq[keys[i]] == 0:
					freq.pop(keys[i])
				if i == W - 2:
					freq[keys[i + 1]] -= 1
					if freq[keys[i + 1]] == 0:
						freq.pop(keys[i + 1])
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		c = Counter(hand)
		for i in range(len(hand) // W):
			if len(hand) < W:
				return False
			keys = list(c.keys())
			key = keys[0]
			for j in range(W):
				if key not in c:
					return False
				if c[key] == 1:
					del c[key]
					key += 1
				else:
					c[key] -= 1
					key += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], w: int) -> bool:
		d = {}
		for i in hand:
			if i not in d:
				d[i] = 1
			else:
				d[i] += 1
		d = sorted(list(d.items()), key=lambda x: x[0])
		d1 = {}
		for i in d:
			d1[i[0]] = i[1]
		while len(d1) > 0:
			r = list(d1.keys())[0]
			for i in range(r, r + w):
				if i not in d1:
					return False
				count = d1[i]
				if count == 1:
					d1.pop(i)
				else:
					d1[i] = d1[i] - 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		d = {}
		for i in hand:
			if i in d:
				d[i] += 1
			else:
				d[i] = 1
		sd = {k: v for (k, v) in sorted(list(d.items()), key=lambda item: item[0])}
		while sd:
			keys = list(sd.keys())
			i = keys[0]
			sd[i] -= 1
			if sd[i] == 0:
				del sd[i]
			count = 1
			while count < W:
				if i + count not in sd:
					return False
				else:
					sd[i + count] -= 1
					if sd[i + count] == 0:
						del sd[i + count]
				count += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand.sort()
		count = collections.Counter(hand)
		while count:
			key = list(count.keys())[0]
			for i in range(W):
				if count[key + i] > 0:
					count[key + i] -= 1
					if count[key + i] == 0:
						del count[key + i]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		from collections import Counter
		i = 0
		hand.sort()
		hand_count = Counter(hand)
		while i < len(hand):
			if hand[i] not in hand_count:
				i += 1
			else:
				cur = hand[i]
				for j in range(W):
					if not hand_count[cur + j]:
						return False
					hand_count[cur + j] -= 1
					if hand_count[cur + j] == 0:
						del hand_count[cur + j]
				i += 1
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		hand = sorted(hand)
		counter = collections.Counter(hand)
		while counter:
			m = min(counter)
			for i in range(W):
				num = m + i
				if num in counter:
					counter[num] -= 1
					if counter[num] == 0:
						del counter[num]
				else:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		hand_count = {}
		for x in hand:
			if x not in hand_count:
				hand_count[x] = 1
			else:
				hand_count[x] += 1
		while len(hand_count) > 0:
			min_key = min(hand_count.keys())
			min_key_count = hand_count[min_key]
			for i in range(W):
				key = min_key + i
				if key not in hand_count:
					return False
				hand_count[key] -= min_key_count
				if hand_count[key] == 0:
					del hand_count[key]
				elif hand_count[key] < 0:
					return False
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		count = collections.Counter(hand)
		while count:
			n = min(count.keys())
			n_count = count[n]
			for x in range(n + 1, n + W):
				if count[x] < n_count:
					return False
				count[x] -= n_count
				if count[x] == 0:
					count.pop(x)
			count.pop(n)
		return True


class Solution(object):

	def isNStraightHand(self, hand, W):
		if len(hand) % W != 0:
			return False
		count = collections.Counter(hand)
		while count:
			m = min(count.keys())
			num = count[m]
			for k in range(m, m + W):
				v = count[k]
				if v < num:
					return False
				if v == num:
					del count[k]
				else:
					count[k] = v - num
		return True


class Solution:

	def isNStraightHand(self, hand: List[int], W: int) -> bool:
		if len(hand) % W != 0:
			return False
		dicts = {}
		for n in hand:
			dicts[n] = dicts.get(n, 0) + 1
		while dicts:
			m = min(dicts)
			for k in range(m, m + W):
				if k not in dicts:
					return False
				elif dicts[k] == 1:
					del dicts[k]
				else:
					dicts[k] -= 1
		return True


class Solution:

	def isNStraightHand(self, nums: List[int], k: int) -> bool:
		n = len(nums)
		if n % k != 0:
			return False
		cnt = Counter(nums)
		no = min(cnt.keys())
		while cnt:
			for j in range(k):
				if cnt[no] == 0:
					return False
				cnt[no] -= 1
				if cnt[no] == 0:
					cnt.pop(no)
				no += 1
			if cnt:
				no = min(cnt.keys())
		return True