

# -*- coding: utf-8 -*-
# @Time : 2022/11/19 21:30
# @Author : bridgekiller
# @FileName: test20221119.py
# @Software: PyCharm
# @Blog :bridge-killer.blog.csdn.netimport os
import sys
import math
import random
import threading
from copy import deepcopy
from io import BytesIO, IOBase
from types import GeneratorType
from functools import lru_cache, reduce
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from itertools import accumulate, combinations, permutations
from heapq import nsmallest, nlargest, heapify, heappop, heappush
from typing import Generic, Iterable, Iterator, TypeVar, Union, Listdef debug(func):def wrapper(*args, **kwargs):print('----------------')res = func(*args, **kwargs)print('----------------')return resreturn wrapperdef bootstrap(f, stack=[]):def wrappedfunc(*args, **kwargs):if stack:return f(*args, **kwargs)else:to = f(*args, **kwargs)while True:if type(to) is GeneratorType:stack.append(to)to = next(to)else:stack.pop()if not stack:breakto = stack[-1].send(to)return toreturn wrappedfuncclass SegTree:'''支持增量更新,覆盖更新,序列更新,任意RMQ操作基于二叉树实现初始化:O(1)增量更新或覆盖更新的单次操作复杂度:O(log k)序列更新的单次复杂度:O(n)'''def __init__(self, f1, f2, l, r, v=0):'''初始化线段树[left,right)f1,f2示例:线段和:f1=lambda a,b:a+bf2=lambda a,n:a*n线段最大值:f1=lambda a,b:max(a,b)f2=lambda a,n:a线段最小值:f1=lambda a,b:min(a,b)f2=lambda a,n:a'''self.ans = f2(v, r - l)self.f1 = f1self.f2 = f2self.l = l # leftself.r = r # rightself.v = v # init valueself.lazy_tag = 0 # Lazy tagself.left = None # SubTree(left,bottom)self.right = None # SubTree(right,bottom)@propertydef mid_h(self):return (self.l + self.r) // 2def create_subtrees(self):midh = self.mid_hif not self.left and midh > self.l:self.left = SegTree(self.f1, self.f2, self.l, midh)if not self.right:self.right = SegTree(self.f1, self.f2, midh, self.r)def init_seg(self, M):'''将线段树的值初始化为矩阵Matrx输入保证Matrx与线段大小一致'''m0 = M[0]self.lazy_tag = 0for a in M:if a != m0:breakelse:self.v = m0self.ans = self.f2(m0, len(M))return self.ansself.v = '#'midh = self.mid_hself.create_subtrees()self.ans = self.f1(self.left.init_seg(M[:midh - self.l]), self.right.init_seg(M[midh - self.l:]))return self.ansdef cover_seg(self, l, r, v):'''将线段[left,right)覆盖为val'''if self.v == v or l >= self.r or r <= self.l:return self.ansif l <= self.l and r >= self.r:self.v = vself.lazy_tag = 0self.ans = self.f2(v, self.r - self.l)return self.ansself.create_subtrees()if self.v != '#':if self.left:self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)if self.right:self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'# push upself.ans = self.f1(self.left.cover_seg(l, r, v), self.right.cover_seg(l, r, v))return self.ansdef inc_seg(self, l, r, v):'''将线段[left,right)增加val'''if v == 0 or l >= self.r or r <= self.l:return self.ans# self.ans = '?'if l <= self.l and r >= self.r:if self.v == '#':self.lazy_tag += velse:self.v += vself.ans += self.f2(v, self.r - self.l)return self.ansself.create_subtrees()if self.v != '#':self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'self.pushdown()self.ans = self.f1(self.left.inc_seg(l, r, v), self.right.inc_seg(l, r, v))return self.ansdef inc_idx(self, idx, v):'''increase idx by val'''if v == 0 or idx >= self.r or idx < self.l:return self.ansif idx == self.l == self.r - 1:self.v += vself.ans += self.f2(v, 1)return self.ansself.create_subtrees()if self.v != '#':self.left.v = self.vself.left.ans = self.f2(self.v, self.left.r - self.left.l)self.right.v = self.vself.right.ans = self.f2(self.v, self.right.r - self.right.l)self.v = '#'self.pushdown()self.ans = self.f1(self.left.inc_idx(idx, v), self.right.inc_idx(idx, v))return self.ansdef pushdown(self):if self.lazy_tag != 0:if self.left:if self.left.v != '#':self.left.v += self.lazy_tagself.left.lazy_tag = 0else:self.left.lazy_tag += self.lazy_tagself.left.ans += self.f2(self.lazy_tag, self.left.r - self.left.l)if self.right:if self.right.v != '#':self.right.v += self.lazy_tagself.right.lazy_tag = 0else:self.right.lazy_tag += self.lazy_tagself.right.ans += self.f2(self.lazy_tag, self.right.r - self.right.l)self.lazy_tag = 0def query(self, l, r):'''查询线段[right,bottom)的RMQ'''if l >= r: return 0if l <= self.l and r >= self.r:return self.ansif self.v != '#':return self.f2(self.v, min(self.r, r) - max(self.l, l))midh = self.mid_hanss = []if l < midh:anss.append(self.left.query(l, r))if r > midh:anss.append(self.right.query(l, r))return reduce(self.f1, anss)class SortedList:def __init__(self, iterable=[], _load=200):"""Initialize sorted list instance."""values = sorted(iterable)self._len = _len = len(values)self._load = _loadself._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]self._list_lens = [len(_list) for _list in _lists]self._mins = [_list[0] for _list in _lists]self._fen_tree = []self._rebuild = Truedef _fen_build(self):"""Build a fenwick tree instance."""self._fen_tree[:] = self._list_lens_fen_tree = self._fen_treefor i in range(len(_fen_tree)):if i | i + 1 < len(_fen_tree):_fen_tree[i | i + 1] += _fen_tree[i]self._rebuild = Falsedef _fen_update(self, index, value):"""Update `fen_tree[index] += value`."""if not self._rebuild:_fen_tree = self._fen_treewhile index < len(_fen_tree):_fen_tree[index] += valueindex |= index + 1def _fen_query(self, end):"""Return `sum(_fen_tree[:end])`."""if self._rebuild:self._fen_build()_fen_tree = self._fen_treex = 0while end:x += _fen_tree[end - 1]end &= end - 1return xdef _fen_findkth(self, k):"""Return a pair of (the largest `idx` such that `sum(_fen_tree[:idx]) <= k`, `k - sum(_fen_tree[:idx])`)."""_list_lens = self._list_lensif k < _list_lens[0]:return 0, kif k >= self._len - _list_lens[-1]:return len(_list_lens) - 1, k + _list_lens[-1] - self._lenif self._rebuild:self._fen_build()_fen_tree = self._fen_treeidx = -1for d in reversed(range(len(_fen_tree).bit_length())):right_idx = idx + (1 << d)if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:idx = right_idxk -= _fen_tree[idx]return idx + 1, kdef _delete(self, pos, idx):"""Delete value at the given `(pos, idx)`."""_lists = self._lists_mins = self._mins_list_lens = self._list_lensself._len -= 1self._fen_update(pos, -1)del _lists[pos][idx]_list_lens[pos] -= 1if _list_lens[pos]:_mins[pos] = _lists[pos][0]else:del _lists[pos]del _list_lens[pos]del _mins[pos]self._rebuild = Truedef _loc_left(self, value):"""Return an index pair that corresponds to the first position of `value` in the sorted list."""if not self._len:return 0, 0_lists = self._lists_mins = self._minslo, pos = -1, len(_lists) - 1while lo + 1 < pos:mi = (lo + pos) >> 1if value <= _mins[mi]:pos = mielse:lo = miif pos and value <= _lists[pos - 1][-1]:pos -= 1_list = _lists[pos]lo, idx = -1, len(_list)while lo + 1 < idx:mi = (lo + idx) >> 1if value <= _list[mi]:idx = mielse:lo = mireturn pos, idxdef _loc_right(self, value):"""Return an index pair that corresponds to the last position of `value` in the sorted list."""if not self._len:return 0, 0_lists = self._lists_mins = self._minspos, hi = 0, len(_lists)while pos + 1 < hi:mi = (pos + hi) >> 1if value < _mins[mi]:hi = mielse:pos = mi_list = _lists[pos]lo, idx = -1, len(_list)while lo + 1 < idx:mi = (lo + idx) >> 1if value < _list[mi]:idx = mielse:lo = mireturn pos, idxdef add(self, value):"""Add `value` to sorted list."""_load = self._load_lists = self._lists_mins = self._mins_list_lens = self._list_lensself._len += 1if _lists:pos, idx = self._loc_right(value)self._fen_update(pos, 1)_list = _lists[pos]_list.insert(idx, value)_list_lens[pos] += 1_mins[pos] = _list[0]if _load + _load < len(_list):_lists.insert(pos + 1, _list[_load:])_list_lens.insert(pos + 1, len(_list) - _load)_mins.insert(pos + 1, _list[_load])_list_lens[pos] = _loaddel _list[_load:]self._rebuild = Trueelse:_lists.append([value])_mins.append(value)_list_lens.append(1)self._rebuild = Truedef discard(self, value):"""Remove `value` from sorted list if it is a member."""_lists = self._listsif _lists:pos, idx = self._loc_right(value)if idx and _lists[pos][idx - 1] == value:self._delete(pos, idx - 1)def remove(self, value):"""Remove `value` from sorted list; `value` must be a member."""_len = self._lenself.discard(value)if _len == self._len:raise ValueError('{0!r} not in list'.format(value))def pop(self, index=-1):"""Remove and return value at `index` in sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)value = self._lists[pos][idx]self._delete(pos, idx)return valuedef bisect_left(self, value):"""Return the first index to insert `value` in the sorted list."""pos, idx = self._loc_left(value)return self._fen_query(pos) + idxdef bisect_right(self, value):"""Return the last index to insert `value` in the sorted list."""pos, idx = self._loc_right(value)return self._fen_query(pos) + idxdef count(self, value):"""Return number of occurrences of `value` in the sorted list."""return self.bisect_right(value) - self.bisect_left(value)def __len__(self):"""Return the size of the sorted list."""return self._lendef __getitem__(self, index):"""Lookup value at `index` in sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)return self._lists[pos][idx]def __delitem__(self, index):"""Remove value at `index` from sorted list."""pos, idx = self._fen_findkth(self._len + index if index < 0 else index)self._delete(pos, idx)def __contains__(self, value):"""Return true if `value` is an element of the sorted list."""_lists = self._listsif _lists:pos, idx = self._loc_left(value)return idx < len(_lists[pos]) and _lists[pos][idx] == valuereturn Falsedef __iter__(self):"""Return an iterator over the sorted list."""return (value for _list in self._lists for value in _list)def __reversed__(self):"""Return a reverse iterator over the sorted list."""return (value for _list in reversed(self._lists) for value in reversed(_list))def __repr__(self):"""Return string representation of sorted list."""return 'SortedList({0})'.format(list(self))T = TypeVar('T')class SortedSet(Generic[T]):BUCKET_RATIO = 50REBUILD_RATIO = 170def _build(self, a=None) -> None:"Evenly divide `a` into buckets."if a is None: a = list(self)size = self.size = len(a)bucket_size = int(math.ceil(math.sqrt(size / self.BUCKET_RATIO)))self.a = [a[size * i // bucket_size: size * (i + 1) // bucket_size] for i in range(bucket_size)]def __init__(self, a: Iterable[T] = []) -> None:"Make a new SortedSet from iterable. / O(N) if sorted and unique / O(N log N)"a = list(a)if not all(a[i] < a[i + 1] for i in range(len(a) - 1)):a = sorted(set(a))self._build(a)def __iter__(self) -> Iterator[T]:for i in self.a:for j in i: yield jdef __reversed__(self) -> Iterator[T]:for i in reversed(self.a):for j in reversed(i): yield jdef __len__(self) -> int:return self.sizedef __repr__(self) -> str:return "SortedSet" + str(self.a)def __str__(self) -> str:s = str(list(self))return "{" + s[1: len(s) - 1] + "}"def _find_bucket(self, x: T) -> List[T]:"Find the bucket which should contain x. self must not be empty."for a in self.a:if x <= a[-1]: return areturn adef __contains__(self, x: T) -> bool:if self.size == 0: return Falsea = self._find_bucket(x)i = bisect_left(a, x)return i != len(a) and a[i] == xdef add(self, x: T) -> bool:"Add an element and return True if added. / O(√N)"if self.size == 0:self.a = [[x]]self.size = 1return Truea = self._find_bucket(x)i = bisect_left(a, x)if i != len(a) and a[i] == x: return Falsea.insert(i, x)self.size += 1if len(a) > len(self.a) * self.REBUILD_RATIO:self._build()return Truedef discard(self, x: T) -> bool:"Remove an element and return True if removed. / O(√N)"if self.size == 0: return Falsea = self._find_bucket(x)i = bisect_left(a, x)if i == len(a) or a[i] != x: return Falsea.pop(i)self.size -= 1if len(a) == 0: self._build()return Truedef lt(self, x: T) -> Union[T, None]:"Find the largest element < x, or None if it doesn't exist."for a in reversed(self.a):if a[0] < x:return a[bisect_left(a, x) - 1]def le(self, x: T) -> Union[T, None]:"Find the largest element <= x, or None if it doesn't exist."for a in reversed(self.a):if a[0] <= x:return a[bisect_right(a, x) - 1]def gt(self, x: T) -> Union[T, None]:"Find the smallest element > x, or None if it doesn't exist."for a in self.a:if a[-1] > x:return a[bisect_right(a, x)]def ge(self, x: T) -> Union[T, None]:"Find the smallest element >= x, or None if it doesn't exist."for a in self.a:if a[-1] >= x:return a[bisect_left(a, x)]def __getitem__(self, x: int) -> T:"Return the x-th element, or IndexError if it doesn't exist."if x < 0: x += self.sizeif x < 0: raise IndexErrorfor a in self.a:if x < len(a): return a[x]x -= len(a)raise IndexErrordef index(self, x: T) -> int:"Count the number of elements < x."ans = 0for a in self.a:if a[-1] >= x:return ans + bisect_left(a, x)ans += len(a)return ansdef index_right(self, x: T) -> int:"Count the number of elements <= x."ans = 0for a in self.a:if a[-1] > x:return ans + bisect_right(a, x)ans += len(a)return ansBUFSIZE = 4096class FastIO(IOBase):newlines = 0def __init__(self, file):self._fd = file.fileno()self.buffer = BytesIO()self.writable = "x" in file.mode or "r" not in file.modeself.write = self.buffer.write if self.writable else Nonedef read(self):while True:b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))if not b:breakptr = self.buffer.tell()self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)self.newlines = 0return self.buffer.read()def readline(self):while self.newlines == 0:b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))self.newlines = b.count(b"\n") + (not b)ptr = self.buffer.tell()self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)self.newlines -= 1return self.buffer.readline()def flush(self):if self.writable:os.write(self._fd, self.buffer.getvalue())self.buffer.truncate(0), self.buffer.seek(0)class IOWrapper(IOBase):def __init__(self, file):self.buffer = FastIO(file)self.flush = self.buffer.flushself.writable = self.buffer.writableself.write = lambda s: self.buffer.write(s.encode("ascii"))self.read = lambda: self.buffer.read().decode("ascii")self.readline = lambda: self.buffer.readline().decode("ascii")sys.stdin = IOWrapper(sys.stdin)
sys.stdout = IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")def I():return input()def II():return int(input())def MI():return map(int, input().split())def LI():return list(input().split())def LII():return list(map(int, input().split()))def GMI():return map(lambda x: int(x) - 1, input().split())def LGMI():return list(map(lambda x: int(x) - 1, input().split()))def solve():n, p = LII()a = LII()aset = set(a)pivot = a[-1]# 若最后一位之前已经填满了,无需进位flag = Truecur = 0while cur < pivot:if cur not in aset:flag = Falsebreakcur += 1if flag: # 无需进位# 只需要加到最大的不在aset中的位置即可maxn = p - 1while maxn > pivot and maxn in aset:maxn -= 1return print(maxn - pivot)else: # 需要进位used = p - pivotaddset = set() # 由于进位新增的set,比pivot大的都搞定了addset.add(0)flag = True # 是否需要进位for i in range(n - 2, -1, -1):if a[i] + 1 != p:flag = Falseaddset.add(a[i] + 1)break# 第一位还需要进位if flag:addset.add(1)# 更新setaset |= addset# 寻找pivot前最大的不在aset中的nums即可maxn = pivot - 1while maxn > 0 and maxn in aset:maxn -= 1#print(used, maxn, aset)return print(used + maxn)if __name__ == '__main__':for _ in range(II()):solve()