You are playing a game similar to Sokoban on an infinite number line. The game is discrete, so you only consider integer positions on the line.

You start on a position $0$. There are $n$ boxes, the $i$-th box is on a position $a_i$. All positions of the boxes are distinct. There are also $m$ special positions, the $j$-th position is $b_j$. All the special positions are also distinct.

In one move you can go one position to the left or to the right. If there is a box in the direction of your move, then you push the box to the next position in that direction. If the next position is taken by another box, then that box is also pushed to the next position, and so on. You can't go through the boxes. You can't pull the boxes towards you.

You are allowed to perform any number of moves (possibly, zero). Your goal is to place as many boxes on special positions as possible. Note that some boxes can be initially placed on special positions.


-----Input-----

The first line contains a single integer $t$ ($1 \le t \le 1000$) — the number of testcases.

Then descriptions of $t$ testcases follow.

The first line of each testcase contains two integers $n$ and $m$ ($1 \le n, m \le 2 \cdot 10^5$) — the number of boxes and the number of special positions, respectively.

The second line of each testcase contains $n$ distinct integers in the increasing order $a_1, a_2, \dots, a_n$ ($-10^9 \le a_1 < a_2 < \dots < a_n \le 10^9$; $a_i \neq 0$) — the initial positions of the boxes.

The third line of each testcase contains $m$ distinct integers in the increasing order $b_1, b_2, \dots, b_m$ ($-10^9 \le b_1 < b_2 < \dots < b_m \le 10^9$; $b_i \neq 0$) — the special positions.

The sum of $n$ over all testcases doesn't exceed $2 \cdot 10^5$. The sum of $m$ over all testcases doesn't exceed $2 \cdot 10^5$.


-----Output-----

For each testcase print a single integer — the maximum number of boxes that can be placed on special positions.


-----Examples-----

Input
5
5 6
-1 1 5 11 15
-4 -3 -2 6 7 15
2 2
-1 1
-1000000000 1000000000
2 2
-1000000000 1000000000
-1 1
3 5
-1 1 2
-2 -1 1 2 5
2 1
1 2
10
Output
4
2
0
3
1


-----Note-----

In the first testcase you can go $5$ to the right: the box on position $1$ gets pushed to position $6$ and the box on position $5$ gets pushed to position $7$. Then you can go $6$ to the left to end up on position $-1$ and push a box to $-2$. At the end, the boxes are on positions $[-2, 6, 7, 11, 15]$, respectively. Among them positions $[-2, 6, 7, 15]$ are special, thus, the answer is $4$.

In the second testcase you can push the box from $-1$ to $-10^9$, then the box from $1$ to $10^9$ and obtain the answer $2$.

The third testcase showcases that you are not allowed to pull the boxes, thus, you can't bring them closer to special positions.

In the fourth testcase all the boxes are already on special positions, so you can do nothing and still obtain the answer $3$.

In the fifth testcase there are fewer special positions than boxes. You can move either $8$ or $9$ to the right to have some box on position $10$.

Source: codeforces | Difficulty: HARD
Tags: Sorting

Amortized analysis

Implementation

Greedy algorithms

Dynamic programming


Solutions:
import sys, os, io
from sys import stdin
from math import log, gcd, ceil
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import math
alphabets = list('abcdefghijklmnopqrstuvwxyz')

def isPrime(x):
	for i in range(2, x):
		if i * i > x:
			break
		if x % i == 0:
			return False
	return True

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def si():
	return input()

def prefix_sum(arr):
	r = [0] * (len(arr) + 1)
	for (i, el) in enumerate(arr):
		r[i + 1] = r[i] + el
	return r

def divideCeil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')

def power_set(L):
	cardinality = len(L)
	n = 2 ** cardinality
	powerset = []
	for i in range(n):
		a = bin(i)[2:]
		subset = []
		for j in range(len(a)):
			if a[-j - 1] == '1':
				subset.append(L[j])
		powerset.append(subset)
	powerset_orderred = []
	for k in range(cardinality + 1):
		for w in powerset:
			if len(w) == k:
				powerset_orderred.append(w)
	return powerset_orderred

def fastPlrintNextLines(a):
	print('\n'.join(map(str, a)))

def sortByFirstAndSecond(A):
	A = sorted(A, key=lambda x: x[0])
	A = sorted(A, key=lambda x: x[1])
	return list(A)
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
else:
	input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def fun(a, b, m, n):
	m = len(b)
	d = defaultdict(lambda : 0)
	for i in a:
		d[i] += 1
	pre = [0] * m
	for i in range(m - 1, -1, -1):
		if d[b[i]] > 0:
			pre[i] += 1
		if i != m - 1:
			pre[i] += pre[i + 1]
	m = 0
	j = 0
	for i in range(len(b)):
		while j < len(a) and a[j] <= b[i]:
			j += 1
		j = min(bisect_left(a, b[i]) + 1, n)
		if a[j - 1] > b[i]:
			j -= 1
		if i < len(b) - 1:
			temp = i - bisect_left(b, b[i] - j + 1) + pre[i + 1] + 1
		else:
			temp = i - bisect_left(b, b[i] - j + 1) + 1
		m = max(m, temp)
	return m

def solve():
	(n, m) = li()
	A = li()
	b = li()
	a = []
	for i in A:
		if i > 0:
			a.append(i)
	n = len(a)
	ans = 0
	bb = []
	for i in b:
		if i > 0:
			bb.append(i)
	bb.sort()
	m = len(bb)
	if a != []:
		ans = fun(a, bb, m, len(a))
	a = []
	for i in A:
		if i < 0:
			a.append(-i)
	n = len(a)
	a.sort()
	b.reverse()
	bb = []
	for i in b:
		if i < 0:
			bb.append(-i)
	bb.sort()
	b = bb[:]
	if n > 0:
		ans += fun(a, b, m, len(a))
	print(ans)
t = 1
t = int(input())
for _ in range(t):
	solve()


from sys import stdin, stdout
t = int(stdin.readline())

def calculate(a, b):
	if len(a) == 0 or len(b) == 0:
		return 0
	if b[-1] < a[0]:
		return 0
	b_already = [0] * len(b)
	b_isin = [i + 1 for i in range(len(b))]
	b_map = [0] * len(b)
	a_pointer = 0
	b_pointer = 0
	while b[b_pointer] < a[0]:
		b_pointer += 1
	while a_pointer + 1 < len(a) and a[a_pointer + 1] <= b[b_pointer]:
		a_pointer += 1
	isin_pointer = 0
	while True:
		while b[isin_pointer] < b[b_pointer] - a_pointer:
			isin_pointer += 1
		b_isin[b_pointer] = isin_pointer
		if b[b_pointer] == a[a_pointer]:
			b_already[b_pointer] = 1
		b_map[b_pointer] = a_pointer + 1
		if b_pointer + 1 == len(b):
			break
		b_pointer += 1
		while a_pointer + 1 < len(a) and a[a_pointer + 1] <= b[b_pointer]:
			a_pointer += 1
	already_matched = sum(b_already)
	answer = 0
	for i in range(len(b)):
		if b_already[i] == 1:
			already_matched -= 1
		answer = max(answer, i - b_isin[i] + 1 + already_matched)
	return answer
for _ in range(t):
	(n, m) = [int(x) for x in stdin.readline().split()]
	a_negative = []
	a_positive = []
	a = [int(x) for x in stdin.readline().split()]
	if a[0] > 0:
		a_positive = a
	elif a[-1] < 0:
		a_negative = [a[n - 1 - i] * -1 for i in range(n)]
	else:
		front = 0
		back = n - 1
		while back - front > 1:
			if a[(front + back) // 2] > 0:
				back = (front + back) // 2
			else:
				front = (front + back) // 2
		a_negative = [a[front - i] * -1 for i in range(front + 1)]
		a_positive = a[back:]
	b_negative = []
	b_positive = []
	b = [int(x) for x in stdin.readline().split()]
	if b[0] > 0:
		b_positive = b
	elif b[-1] < 0:
		b_negative = [b[m - 1 - i] * -1 for i in range(m)]
	else:
		front = 0
		back = m - 1
		while back - front > 1:
			if b[(front + back) // 2] > 0:
				back = (front + back) // 2
			else:
				front = (front + back) // 2
		b_negative = [b[front - i] * -1 for i in range(front + 1)]
		b_positive = b[back:]
	stdout.write(str(calculate(a_positive, b_positive) + calculate(a_negative, b_negative)) + '\n')


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def prod(a, mod=10 ** 9 + 7):
	ans = 1
	for each in a:
		ans = ans * each % mod
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
from bisect import bisect_left, bisect_right

class Result:

	def __init__(self, index, value):
		self.index = index
		self.value = value

class BinarySearch:

	def __init__(self):
		pass

	@staticmethod
	def greater_than(num: int, func, size: int=1):
		if isinstance(func, list):
			index = bisect_right(func, num)
			if index == len(func):
				return Result(None, None)
			else:
				return Result(index, func[index])
		else:
			(alpha, omega) = (0, size - 1)
			if func(omega) <= num:
				return Result(None, None)
			while alpha < omega:
				if func(alpha) > num:
					return Result(alpha, func(alpha))
				if omega == alpha + 1:
					return Result(omega, func(omega))
				mid = (alpha + omega) // 2
				if func(mid) > num:
					omega = mid
				else:
					alpha = mid

	@staticmethod
	def less_than(num: int, func, size: int=1):
		if isinstance(func, list):
			index = bisect_left(func, num) - 1
			if index == -1:
				return Result(None, None)
			else:
				return Result(index, func[index])
		else:
			(alpha, omega) = (0, size - 1)
			if func(alpha) >= num:
				return Result(None, None)
			while alpha < omega:
				if func(omega) < num:
					return Result(omega, func(omega))
				if omega == alpha + 1:
					return Result(alpha, func(alpha))
				mid = (alpha + omega) // 2
				if func(mid) < num:
					alpha = mid
				else:
					omega = mid
bs = BinarySearch()
for _ in range(int(input()) if True else 1):
	(n, m) = map(int, input().split())
	a = sorted(list(map(int, input().split())))
	b = sorted(list(map(int, input().split())))
	sb = set(b)
	cur_right = cur_left = 0
	ok1 = []
	ok2 = []
	for i in a:
		if i > 0 and i in sb:
			cur_right += 1
			ok1 += [i]
		if i < 0 and i in sb:
			cur_left += 1
			ok2 += [i]
	ind = bs.greater_than(0, a).index
	if ind is not None:
		j = bs.greater_than(a[ind], b).index
		if j is not None:
			while j < m:
				extra = 0
				diff = 0
				curind = ind
				while True:
					target = b[j] + diff
					nx = bs.less_than(target + 1, a).index
					if nx != curind:
						diff += nx - curind
						curind = nx
					else:
						break
				indok1 = bs.greater_than(b[j] + diff, ok1).index
				ans1 = ans2 = 0
				if indok1 is not None:
					ans1 += len(ok1) - indok1
				x1 = bs.less_than(b[j] + diff + 1, b).index
				ans2 = x1 - j + 1
				cur_right = max(cur_right, ans1 + ans2)
				j += 1
	ind = bs.less_than(0, a).index
	if ind is not None:
		j = bs.less_than(a[ind], b).index
		if j is not None:
			while j >= 0:
				extra = 0
				diff = 0
				curind = ind
				while True:
					target = b[j] - diff
					nx = bs.greater_than(target - 1, a).index
					if nx != curind:
						diff += curind - nx
						curind = nx
					else:
						break
				indok1 = bs.less_than(b[j] - diff, ok2).index
				ans1 = ans2 = 0
				if indok1 is not None:
					ans1 += indok1 + 1
				x1 = bs.greater_than(b[j] - diff - 1, b).index
				ans2 = j - x1 + 1
				cur_left = max(cur_left, ans1 + ans2)
				j -= 1
	print(cur_right + cur_left)


def read_list_of_input():
	return [x for x in input().split()]

def read_list_of_int():
	return [int(x) for x in read_list_of_input()]

def optimal_num(boxes, postions):
	ans = 0
	(n, m) = (len(boxes), len(postions))
	after_nth_box_best = [0 for _ in range(n + 1)]
	b = m - 1
	for x in range(n - 1, -1, -1):
		after_nth_box_best[x] = after_nth_box_best[x + 1]
		while b >= 0 and boxes[x] < postions[b]:
			b -= 1
		if b >= 0 and boxes[x] == postions[b]:
			after_nth_box_best[x] += 1
	j = 0
	r = 0
	for x in range(m):
		while j < n and postions[x] + j >= boxes[j]:
			j += 1
		while r < m and postions[r] < j + postions[x]:
			r += 1
		ans = max(ans, after_nth_box_best[j] + r - x)
	return ans

def solve():
	(n, m) = read_list_of_int()
	box_pos = read_list_of_int()
	special_pos = read_list_of_int()
	box_left = [-1 * x for x in box_pos if x < 0]
	box_left.reverse()
	box_right = [x for x in box_pos if x >= 0]
	special_left = [-1 * x for x in special_pos if x < 0]
	special_left.reverse()
	special_right = [x for x in special_pos if x >= 0]
	print(optimal_num(box_left, special_left) + optimal_num(box_right, special_right))
test = int(input())
for x in range(test):
	solve()


from bisect import *
l = bisect_left
r = range

def s(A, B):
	S = set(A)
	b = len(B)
	C = [0] * (b + 1)
	for i in r(b - 1, -1, -1):
		if B[i] in S:
			C[i] += 1
		C[i] += C[i + 1]
	a = C[0]
	X = 0
	for i in r(b):
		while X < len(A) and A[X] <= B[i]:
			X += 1
		if X > 0:
			a = max(a, l(B, B[i]) - l(B, B[i] - X + 1) + 1 + C[i + 1])
	return a
p = lambda : map(int, input().split())
for t in r(*p()):
	p()
	A = []
	X = []
	B = []
	Y = []
	for v in p():
		if v < 0:
			A += (-v,)
		else:
			B += (v,)
	for w in p():
		if w < 0:
			X += (-w,)
		else:
			Y += (w,)
	print(s(A[::-1], X[::-1]) + s(B, Y))


import sys, bisect
ints = (int(x) for x in sys.stdin.read().split())
sys.setrecursionlimit(3000)
ub = bisect.bisect_right
lb = bisect.bisect_left

def solve(a, b):
	if len(a) == 0 or len(b) == 0:
		return 0

	def aux(i):
		prev = -1
		c = 0
		while c != prev:
			prev = c
			c = ub(a, b[i] + c)
		return c
	n = len(b)
	sa = set(a)
	b_in_a = [b[i] in sa for i in range(n)]
	b_acum_a = b_in_a.copy()
	for i in range(n - 2, -1, -1):
		b_acum_a[i] += b_acum_a[i + 1]
	c = [aux(i) for i in range(n)]
	d = [ub(b, b[i] + c[i] - 1) - i for i in range(n)]
	g = [i + d[i] < n and b_acum_a[i + d[i]] for i in range(n)]
	h = [d[i] + g[i] for i in range(n)]
	return max(h)

def main():
	ntc = next(ints)
	for tc in range(1, ntc + 1):
		(n, m) = (next(ints) for i in range(2))
		a = [next(ints) for i in range(n)]
		b = [next(ints) for i in range(m)]
		ans = solve([x for x in a if x > 0], [x for x in b if x > 0])
		ans += solve([-x for x in a if x < 0][::-1], [-x for x in b if x < 0][::-1])
		print(ans)
	return
main()


import math, sys
from collections import defaultdict, deque
import bisect as bi

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

def Sn():
	return sys.stdin.readline().strip()

def Pr(x):
	sys.stdout.write(str(x) + '\n')

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gte(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return len(a)

def find_gt(a, x):
	i = bi.bisect_right(a, x)
	if i != len(a):
		return i
	else:
		return len(a)

def find_le(a, x):
	i = bi.bisect_right(a, x)
	if i:
		return i - 1
	else:
		return -1

def find_ge(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	return len(a)

def check(a, b):
	(n, m) = (len(a), len(b))
	suf = [0] * (n + 1)
	for x in range(n):
		pos = find_gte(b, a[x])
		if pos < m and b[pos] == a[x]:
			suf[x] = 1
	for i in range(n - 1, -1, -1):
		suf[i] += suf[i + 1]
	for i in range(n):
		a[i] -= i
	ans = 0
	for x in range(m):
		pos = find_ge(a, b[x])
		if pos < 0:
			continue
		le = bi.bisect_left(b, b[x] + pos) - x + suf[pos]
		ans = max(ans, le)
	return ans

def main():
	try:
		(n, m) = In()
		a = list(In())
		b = list(In())
		(a_pos, a_neg, b_pos, b_neg) = ([], [], [], [])
		for i in range(n):
			a_pos.append(a[i]) if a[i] > 0 else a_neg.append(abs(a[i]))
		for i in range(m):
			b_pos.append(b[i]) if b[i] > 0 else b_neg.append(abs(b[i]))
		a_neg.sort()
		b_neg.sort()
		Pr(check(a_pos, b_pos) + check(a_neg, b_neg))
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(I()):
	main()


import bisect
T = int(input())
r = 1

def getnum(boxesright, positionright):
	dicright = {}
	for e in positionright:
		dicright[e] = 1
	k = len(boxesright)
	already = [0] * (k + 1)
	for i in range(k - 1, -1, -1):
		if boxesright[i] in dicright:
			already[i] = already[i + 1] + 1
		else:
			already[i] = already[i + 1]
	p = len(positionright)
	output = 0
	for j in range(p):
		accuboxes = bisect.bisect(boxesright, positionright[j])
		loc2 = bisect.bisect_left(positionright, positionright[j] - accuboxes + 1)
		tot = j + 1 - loc2 + already[accuboxes]
		output = max(output, tot)
	return output
while r <= T:
	(m, n) = map(int, input().split())
	boxes = list(map(int, input().split()))
	positions = list(map(int, input().split()))
	loc1 = bisect.bisect(boxes, 0)
	loc2 = bisect.bisect(positions, 0)
	boxesright = boxes[loc1:]
	positionright = positions[loc2:]
	boxesleft = boxes[:loc1]
	positionleft = positions[:loc2]
	num1 = getnum(boxesright, positionright)
	boxesleft = boxesleft[::-1]
	positionleft = positionleft[::-1]
	for i in range(len(boxesleft)):
		boxesleft[i] = -boxesleft[i]
	for i in range(len(positionleft)):
		positionleft[i] = -positionleft[i]
	num2 = getnum(boxesleft, positionleft)
	print(num1 + num2)
	r += 1


import bisect as b
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	c = list(map(int, input().split()))
	d = list(map(int, input().split()))
	p = [[], []]
	q = [[], []]
	for i in range(n):
		if c[i] > 0:
			p[0].append(c[i])
		else:
			p[1].append(abs(c[i]))
	for i in range(m):
		if d[i] > 0:
			q[0].append(d[i])
		else:
			q[1].append(abs(d[i]))
	p[1] = p[1][::-1]
	q[1] = q[1][::-1]
	an = 0
	for j in range(2):
		x = p[j]
		y = q[j]
		n = len(x)
		m = len(y)
		if m == 0:
			continue
		l1 = [0 for _ in range(m)]
		l2 = [0 for _ in range(m)]
		a1 = b.bisect(x, y[0])
		a2 = b.bisect_left(x, y[0])
		if a1 != a2:
			l1[0] = 1
		l2[0] = 1 - b.bisect(y, y[0] - a1)
		for i in range(1, m):
			a1 = b.bisect(x, y[i])
			a2 = b.bisect_left(x, y[i])
			if a1 != a2:
				l1[i] = l1[i - 1] + 1
			else:
				l1[i] = l1[i - 1]
			l2[i] = i + 1 - b.bisect(y, y[i] - a1)
		ans = 0
		for i in range(m):
			ans = max(ans, l2[i] + l1[-1] - l1[i])
		an += ans
	print(an)


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
inp = lambda : list(map(int, sys.stdin.readline().rstrip('\r\n').split()))
mod = 10 ** 9 + 7
Mod = 998244353
INF = float('inf')
from heapq import *
tc = 1
(tc,) = inp()
for _ in range(tc):
	(n, m) = inp()
	leftn = []
	rightn = []
	leftm = []
	rightm = []
	for i in input().split():
		x = int(i)
		if x > 0:
			rightn.append(x)
		else:
			leftn.append(-x)
	for i in input().split():
		x = int(i)
		if x > 0:
			rightm.append(x)
		else:
			leftm.append(-x)
	leftm.reverse()
	leftn.reverse()

	def solve(a, b):
		n = len(a)
		m = len(b)
		if m == 0 or n == 0:
			return 0
		h = []
		c = sorted([[i, 0] for i in a] + [[i, 1] for i in b], key=lambda x: (x[0], x[1]))
		sp = 0
		count = 0
		ans = 0
		val = {}
		i = n - 1
		j = m - 1
		lol = 0
		while i >= 0 and j >= 0:
			if a[i] == b[j]:
				val[b[j]] = lol
				i -= 1
				j -= 1
				lol += 1
			elif a[i] < b[j]:
				val[b[j]] = lol
				j -= 1
			else:
				i -= 1
		while j >= 0:
			val[b[j]] = lol
			j -= 1
		ans = lol
		for (i, j) in c:
			if j == 1:
				heappush(h, (i, j))
				sp += 1
			else:
				count += 1
			while j == 1 and h and (h[0][0] <= i - count):
				(ii, jj) = heappop(h)
				if jj == 1:
					sp -= 1
			if j == 1:
				ans = max(ans, sp + val[i])
		return ans
	ans = solve(leftn, leftm) + solve(rightn, rightm)
	print(ans)


import sys
input = sys.stdin.buffer.readline
from bisect import *

def solve(A, B):
	S = set(A)
	b = len(B)
	C = [0] * (b + 1)
	for i in range(b - 1, -1, -1):
		if B[i] in S:
			C[i] += 1
		C[i] += C[i + 1]
	ANS = C[0]
	X = 0
	for i in range(b):
		while X < len(A) and A[X] <= B[i]:
			X += 1
		if X == 0:
			continue
		ANS = max(ANS, bisect_left(B, B[i]) - bisect_left(B, B[i] - X + 1) + 1 + C[i + 1])
	return ANS
p = lambda : map(int, input().split())
for t in range(*p()):
	(N, M) = p()
	V = (*p(),)
	W = (*p(),)
	A = []
	X = []
	B = []
	Y = []
	for i in range(N):
		if V[i] < 0:
			A.append(-V[i])
		else:
			B.append(V[i])
	for i in range(M):
		if W[i] < 0:
			X.append(-W[i])
		else:
			Y.append(W[i])
	A = A[::-1]
	X = X[::-1]
	print(solve(A, X) + solve(B, Y))


from sys import stdin
input = stdin.readline

def A707():
	from collections import defaultdict
	CAP = 2500001
	n = int(input())
	a = list(map(int, input().split()))
	d = [0] * (CAP * 2)
	i = n - 2
	j = n - 1
	found = False
	while i >= 0:
		j = i + 1
		while j < n:
			if d[a[i] + a[j]] != 0:
				ID = i * n + j
				for k in d[a[i] + a[j]]:
					if not (k % n == i or k % n == j or k // n == i or (k // n == j)):
						print('YES')
						print(i + 1, j + 1, k % n + 1, k // n + 1)
						found = True
						break
				d[a[i] + a[j]].append(ID)
			else:
				d[a[i] + a[j]] = [i * n + j]
			j += 1
			if found:
				break
		i -= 1
		if found:
			break
	if not found:
		print('NO')

def CEdu105():
	from collections import defaultdict

	def bestMatch(boxes, specials):
		if len(boxes) == 0 or len(specials) == 0:
			return 0
		dp = [0] * len(specials)
		i = 0
		j = 0
		while i < len(specials):
			if j < len(boxes) and boxes[j] <= specials[i]:
				j += 1
			else:
				dp[i] = j
				i += 1
		matches = sorted(set(boxes).intersection(specials), reverse=True)
		totalMatches = 0
		currMatchIndex = 0
		j = len(specials) - 1
		i = j
		scores = [0] * len(specials)
		while j >= 0:
			while i >= 0 and specials[j] - specials[i] < dp[j]:
				i -= 1
			scores[j] = j - i + totalMatches
			while currMatchIndex < len(matches) and specials[j] < matches[currMatchIndex]:
				currMatchIndex += 1
			if currMatchIndex < len(matches) and specials[j] == matches[currMatchIndex]:
				totalMatches += 1
			j -= 1
		return max(scores)
	t = int(input())
	for _ in range(t):
		(n, m) = map(int, input().split())
		a = list(map(int, input().split()))
		b = list(map(int, input().split()))
		(i, j) = (0, 0)
		while i < n:
			if a[i] > 0:
				break
			a[i] *= -1
			i += 1
		while j < m:
			if b[j] > 0:
				break
			b[j] *= -1
			j += 1
		lefta = sorted(a[:i])
		righta = a[i:]
		leftb = sorted(b[:j])
		rightb = b[j:]
		print(bestMatch(lefta, leftb) + bestMatch(righta, rightb))
CEdu105()


from sys import stdin, stdout
from bisect import bisect_left, bisect_right
t = int(stdin.readline().rstrip())
for k in range(t):
	(n, m) = list(map(int, stdin.readline().rstrip().split()))
	boxes = list(map(int, stdin.readline().rstrip().split()))
	box_set = set(boxes)
	zero_idx = bisect_left(boxes, 0)
	neg_box = [abs(boxes[i]) for i in range(zero_idx - 1, -1, -1)]
	pos_box = boxes[zero_idx:]
	special = list(map(int, stdin.readline().rstrip().split()))
	zero_idx = bisect_left(special, 0)
	neg_special = [abs(special[i]) for i in range(zero_idx - 1, -1, -1)]
	pos_special = special[zero_idx:]
	alr_special_pos = [i for i in pos_special if i in box_set]
	alr_special_neg = [i for i in neg_special if -i in box_set]
	max_pos_box = 0
	for i in range(len(pos_special)):
		special = pos_special[i]
		idx = bisect_left(pos_box, special)
		prev = None
		while idx != prev:
			prev = idx
			idx = bisect_left(pos_box, special + idx, idx)
		num_special_boxes = bisect_left(pos_special, special + idx) - i + len(alr_special_pos) - bisect_left(alr_special_pos, special + idx)
		if max_pos_box < num_special_boxes:
			max_pos_box = num_special_boxes
	max_neg_box = 0
	for i in range(len(neg_special)):
		special = neg_special[i]
		idx = bisect_left(neg_box, special)
		prev = None
		while idx != prev:
			prev = idx
			idx = bisect_left(neg_box, special + idx, idx)
		num_special_boxes = bisect_left(neg_special, special + idx) - i + len(alr_special_neg) - bisect_left(alr_special_neg, special + idx)
		if max_neg_box < num_special_boxes:
			max_neg_box = num_special_boxes
	print(max_pos_box + max_neg_box)


import math

def bs(x, l, r, v):
	if l == r:
		return l if v == x[l] else l - 1
	md = math.floor((l + r) / 2)
	return bs(x, l, md, v) if v <= x[md] else bs(x, md + 1, r, v)

def solve(a, b):
	n = len(a)
	m = len(b)
	join = [a[i] for i in range(n) if b[bs(b, 0, m - 1, a[i])] == a[i]]
	gaps = [a[i] for i in range(n)]
	for i in range(1, n, 1):
		gaps[i] = gaps[i - 1] + (a[i] - a[i - 1] - 1)
	ans = len(join) - 2
	for i in range(1, m - 1, 1):
		c = bs(a, 0, n, b[i])
		d = bs(gaps, 0, n, gaps[c] + (b[i] - a[c]) + c)
		if gaps[d] == gaps[c] + (b[i] - a[c]) + c:
			d = d - 1
		x1 = bs(b, 0, m, b[i] + d - 1) - i + 1
		x2 = len(join) - bs(join, 0, len(join), b[i] + d) - 2
		ans = max(ans, x1 + x2)
	return ans
t = int(input())
for tt in range(t):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	apos = [-3 * 10 ** 9] + [a[i] for i in range(n) if a[i] > 0] + [3 * 10 ** 9]
	bpos = [-3 * 10 ** 9] + [b[i] for i in range(m) if b[i] > 0] + [3 * 10 ** 9]
	aneg = [-3 * 10 ** 9] + [-a[i] for i in range(n - 1, -1, -1) if a[i] < 0] + [3 * 10 ** 9]
	bneg = [-3 * 10 ** 9] + [-b[i] for i in range(m - 1, -1, -1) if b[i] < 0] + [3 * 10 ** 9]
	print(solve(apos, bpos) + solve(aneg, bneg))


import sys
input = sys.stdin.readline
from itertools import product
import bisect
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	for (i, a) in enumerate(A):
		if a > 0:
			start = i
			break
	else:
		start = n
	(i, j) = (n - 1, m - 1)
	right = 0
	pre = 0
	if start < n:
		while i >= 0 and A[i] > 0 and (j >= 0):
			if A[i] > B[j]:
				i -= 1
				continue
			cnt = i - start + 1
			(l, r) = (0, j)
			while l < r:
				mid = l + (r - l) // 2
				if B[mid] >= B[j] - cnt + 1:
					r = mid
				else:
					l = mid + 1
			cnt2 = j - l + 1
			right = max(right, pre + min(cnt, cnt2))
			if A[i] == B[j]:
				pre += 1
			j -= 1
	left = 0
	if start > 0:
		start -= 1
		(i, j) = (0, 0)
		left = 0
		pre = 0
		while i < n and A[i] < 0 and (j < m):
			if A[i] < B[j]:
				i += 1
				continue
			cnt = start - i + 1
			(l, r) = (j, m - 1)
			while l < r:
				mid = r - (r - l) // 2
				if B[mid] <= B[j] + cnt - 1:
					l = mid
				else:
					r = mid - 1
			cnt2 = l - j + 1
			left = max(left, pre + min(cnt, cnt2))
			if A[i] == B[j]:
				pre += 1
			j += 1
	ans = left + right
	print(ans)


import sys
from collections import deque, defaultdict, Counter
from bisect import bisect_left

def debug(*args):
	print(*args, file=sys.stderr)

def read_str():
	return sys.stdin.readline().strip()

def read_int():
	return int(sys.stdin.readline().strip())

def read_ints():
	return map(int, sys.stdin.readline().strip().split())

def read_str_split():
	return list(sys.stdin.readline().strip())

def read_int_list():
	return list(map(int, sys.stdin.readline().strip().split()))

def solve(a: list, b: list):
	position = set(b)
	tmp = len(set(a) & position)
	que = deque()
	(res, ptr) = (tmp, 0)
	for x in b:
		que.append(x)
		while a and a[-1] <= x:
			y = a.pop()
			if y in position:
				tmp -= 1
			ptr += 1
		while que and que[0] <= x - ptr:
			que.popleft()
		res = max(res, tmp + len(que))
	return res

def Main():
	t = read_int()
	for _ in range(t):
		(n, m) = read_ints()
		a = read_int_list()
		b = read_int_list()
		a_i = bisect_left(a, 0)
		b_i = bisect_left(b, 0)
		(a_plus, b_plus) = (a[a_i:], b[b_i:])
		(a_minus, b_minus) = ([-x for x in a[:a_i]], [-x for x in b[:b_i]])
		a_plus.sort(reverse=True)
		a_minus.sort(reverse=True)
		b_plus.sort()
		b_minus.sort()
		print(solve(a_plus, b_plus) + solve(a_minus, b_minus))
Main()


import sys
import bisect
input = sys.stdin.readline
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	boxes = list(map(int, input().split()))
	marks = list(map(int, input().split()))
	bidx = bisect.bisect(boxes, 0)
	midx = bisect.bisect(marks, 0)

	def countbox(boxes, marks):
		(res, already) = (0, 0)
		(i, j) = (len(boxes) - 1, len(marks) - 1)
		while i >= 0 and j >= 0:
			if boxes[i] > marks[j]:
				i -= 1
				continue
			box_num = i + 1
			mark_num = j - bisect.bisect_left(marks, marks[j] - box_num + 1) + 1
			res = max(res, mark_num + already)
			if boxes[i] == marks[j]:
				already += 1
			j -= 1
		return res
	print(countbox(boxes[bidx:], marks[midx:]) + countbox([-i for i in boxes[:bidx][::-1]], [-i for i in marks[:midx][::-1]]))


import sys
input = sys.stdin.readline
from bisect import bisect_left

def solve(p, q):
	(n, m) = (len(p), len(q))
	res = 0
	idx = 0
	t = [0] * m
	li = []
	for i in range(n):
		while idx < m and q[idx] < p[i]:
			idx += 1
		if idx < m and p[i] == q[idx]:
			res += 1
			li.append(p[i])
	for i in range(m):
		(l, r) = (0, n + 1)
		while r - l > 1:
			md = (l + r) // 2
			if md <= bisect_left(p, q[i] + md):
				l = md
			else:
				r = md
		t[i] = l
	ans = res
	for i in range(m):
		ans = max(ans, res - bisect_left(li, q[i] + t[i]) + bisect_left(q, q[i] + t[i]) - i)
	return ans
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	for i in range(n):
		if a[i] > 0:
			c = [-x for x in a[:i]]
			c.reverse()
			a = a[i:]
			break
	else:
		c = [-x for x in a[:n]]
		c.reverse()
		a = []
	for i in range(m):
		if b[i] > 0:
			d = [-x for x in b[:i]]
			d.reverse()
			b = b[i:]
			break
	else:
		d = [-x for x in b[:m]]
		d.reverse()
		b = []
	print(solve(a, b) + solve(c, d))


def read_int_array():
	return list(map(int, input().split()))

def split_array(arr):
	(left, right) = ([], [])
	for el in arr:
		if el < 0:
			left.append(-el)
		else:
			right.append(el)
	left.reverse()
	return (left, right)

def solve_for_test(a, b):
	b = [0] + b + [int(2000000000.0)]
	a = a + [int(3000000000.0)]
	suffix = [0 for i in range(len(b) + 1)]
	(a_idx, b_idx) = (len(a) - 1, len(b) - 2)
	while b_idx >= 0:
		suffix[b_idx] = suffix[b_idx + 1]
		while a_idx >= 0 and a[a_idx] > b[b_idx]:
			a_idx -= 1
		if a[a_idx] == b[b_idx]:
			suffix[b_idx] += 1
		b_idx -= 1
	(a_idx, b_idx, opt_answer, cur_l) = (0, 0, 0, 0)
	while b_idx < len(b) - 1:
		while a_idx < len(a) - 1 and a[a_idx] <= b[b_idx]:
			a_idx += 1
		while cur_l < len(b) - 1 and b[cur_l] <= b[b_idx] - a_idx:
			cur_l += 1
		opt_answer = max(opt_answer, min(b_idx - cur_l + 1, a_idx) + suffix[b_idx + 1])
		b_idx += 1
	return opt_answer

def solve():
	(n, m) = read_int_array()
	(a, b) = (read_int_array(), read_int_array())
	(a_l, a_r) = split_array(a)
	(b_l, b_r) = split_array(b)
	print(solve_for_test(a_l, b_l) + solve_for_test(a_r, b_r))
t = read_int_array()[0]
while t > 0:
	solve()
	t -= 1


import bisect
import collections
import copy
import functools
import heapq
import itertools
import math
import random
import re
import sys
import time
import string
from typing import List
sys.setrecursionlimit(99999)

def f(ta, tb):
	if not ta or not tb:
		return 0
	sa = set(ta)
	sb = set(tb)
	m1 = 0
	d = [0] * (len(tb) + 5)
	d[len(tb) - 1] += tb[-1] in sa
	for i in range(len(tb) - 2, -1, -1):
		d[i] = d[i + 1] + (tb[i] in sa)
	j = 0
	j2 = 0
	for (i, c) in enumerate(tb):
		while j < len(ta) and ta[j] <= c:
			j += 1
		lo = c - j + 1
		while j2 < len(tb) and tb[j2] < lo:
			j2 += 1
		m1 = max(m1, i - j2 + 1 + d[i + 1])
	return m1

def solve():
	(n, m) = map(int, input().split())
	a1 = []
	a2 = []
	b1 = []
	b2 = []
	for c in map(int, input().split()):
		if c < 0:
			a1.append(-c)
		else:
			a2.append(c)
	for c in map(int, input().split()):
		if c < 0:
			b1.append(-c)
		else:
			b2.append(c)
	m1 = f(a2, b2)
	m2 = f(a1[::-1], b1[::-1])
	print(m1 + m2)
for _ in range(int(input())):
	solve()


import os
import sys
from io import BytesIO, IOBase

def fans(A, B):
	if len(A) == 0:
		return 0
	n = len(A)
	m = len(B)
	ans = 0
	pref = [0 for i in range(n + 1)]
	G = set(B)
	for i in range(n - 1, -1, -1):
		pref[i] = pref[i + 1]
		if A[i] in G:
			pref[i] = pref[i + 1] + 1
	beg = 0
	end = 0
	cnt = 0
	for i in range(m):
		if A[0] > B[i]:
			continue
		while beg < n and A[beg] <= B[i] + cnt:
			beg = beg + 1
			cnt = cnt + 1
		while end < m and B[end] < B[i] + cnt:
			end = end + 1
		ans = max(ans, end - i + pref[beg])
	return ans

def main():
	T = int(input())
	for _ in range(T):
		(n, m) = map(int, input().split())
		A = list(map(int, input().split()))
		B = list(map(int, input().split()))
		C1 = []
		D1 = []
		C2 = []
		D2 = []
		for i in range(n):
			if A[i] < 0:
				C1.append(-1 * A[i])
			else:
				D1.append(A[i])
		for i in range(m):
			if B[i] < 0:
				C2.append(-1 * B[i])
			else:
				D2.append(B[i])
		C1.reverse()
		C2.reverse()
		ans = fans(C1, C2) + fans(D1, D2)
		print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, data, default=-10 ** 6, func=lambda a, b: max(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree1:

	def __init__(self, data, default=10 ** 6, func=lambda a, b: min(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)
MOD = 10 ** 9 + 7

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
mod = 10 ** 9 + 7
omod = 998244353
prime = [True for i in range(200001)]
pp = [0] * 200001

def SieveOfEratosthenes(n=200000):
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1

def binarySearch(arr, n, key):
	left = 0
	right = n - 1
	mid = 0
	res = 0
	while left <= right:
		mid = (right + left) // 2
		if arr[mid] > key:
			right = mid - 1
		else:
			res = mid + 1
			left = mid + 1
	return res
for _ in range(int(input())):
	(n1, k) = map(int, input().split())
	aa = list(map(int, input().split()))
	bb = list(map(int, input().split()))
	(a1, a2, b1, b2) = ([], [], [], [])
	for i in aa:
		if i > 0:
			a1.append(i)
		else:
			a2.append(-i)
	for i in bb:
		if i > 0:
			b1.append(i)
		else:
			b2.append(-i)
	a1.sort()
	a2.sort()
	b1.sort()
	b2.sort()

	def solution(a, b):
		s = set(a)
		n = len(a)
		m = len(b)
		pre = [0] * (m + 1)
		mx = 0
		for i in range(m - 1, -1, -1):
			pre[i] = pre[i + 1]
			if b[i] in s:
				pre[i] += 1
		for i in range(m):
			r = binarySearch(a, n, b[i])
			count = binarySearch(b, m, b[i]) - binarySearch(b, m, b[i] - r)
			mx = max(mx, min(count, r) + pre[i + 1])
		return mx
	res = solution(a1, b1) + solution(a2, b2)
	print(res)


from bisect import bisect_left, bisect_right

def solve(a, b):
	maxm = 0
	preplaced = [0 for _ in b]
	for i in range(len(b) - 1, 0, -1):
		j = bisect_left(a, b[i])
		if j != len(a) and a[j] == b[i]:
			preplaced[i - 1] = preplaced[i] + 1
		else:
			preplaced[i - 1] = preplaced[i]
	for i in range(0, len(b)):
		boxcount = bisect_right(a, b[i])
		spcount = i - bisect_right(b, b[i] - boxcount) + 1 + preplaced[i]
		maxm = max(maxm, spcount)
	return maxm
qq = int(input())
for _ in range(qq):
	(n, m) = tuple(map(int, input().split()))
	arr = list(map(int, input().split()))
	lefta = list(reversed([-i for i in arr[:bisect_left(arr, 0)]]))
	righta = arr[bisect_left(arr, 0):]
	brr = list(map(int, input().split()))
	leftb = list(reversed([-i for i in brr[:bisect_left(brr, 0)]]))
	rightb = brr[bisect_left(brr, 0):]
	print(solve(righta, rightb) + solve(lefta, leftb))


import sys
input = sys.stdin.readline
t = int(input())
for tests in range(t):
	(n, m) = map(int, input().split())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	PA = []
	MA = []
	PB = []
	MB = []
	for a in A:
		if a > 0:
			PA.append(a)
		else:
			MA.append(-a)
	for b in B:
		if b > 0:
			PB.append(b)
		else:
			MB.append(-b)
	MA.reverse()
	MB.reverse()
	SETA = set(PA)
	OK = [0] * (len(PB) + 1)
	for i in range(len(PB) - 1, -1, -1):
		if PB[i] in SETA:
			OK[i] = OK[i + 1] + 1
		else:
			OK[i] = OK[i + 1]
	PA.append(1 << 60)
	PB.append(1 << 59)
	ANS = OK[0]
	inda = 0
	indend = 0
	for i in range(len(PB) - 1):
		if PB[i] < PA[0]:
			continue
		while PA[inda] <= PB[i] + inda - 1:
			inda += 1
		while PB[indend] <= PB[i] + inda - 1:
			indend += 1
		ANS = max(ANS, indend - i + OK[indend])
	ANS0 = ANS
	PA = MA
	PB = MB
	SETA = set(PA)
	OK = [0] * (len(PB) + 1)
	for i in range(len(PB) - 1, -1, -1):
		if PB[i] in SETA:
			OK[i] = OK[i + 1] + 1
		else:
			OK[i] = OK[i + 1]
	PA.append(1 << 60)
	PB.append(1 << 59)
	ANS = OK[0]
	inda = 0
	indend = 0
	for i in range(len(PB) - 1):
		if PB[i] < PA[0]:
			continue
		while PA[inda] <= PB[i] + inda - 1:
			inda += 1
		while PB[indend] <= PB[i] + inda - 1:
			indend += 1
		ANS = max(ANS, indend - i + OK[indend])
	print(ANS + ANS0)


import sys
input = sys.stdin.readline

def solve(x, y):
	(n, m, ans) = (len(x), len(y), 0)
	(already, i, j) = ([0 for _ in range(n + 1)], 0, m - 1)
	for i in range(n - 1, -1, -1):
		already[i] = already[i + 1]
		while j >= 0 and y[j] > x[i]:
			j -= 1
		if j >= 0 and y[j] == x[i]:
			already[i] += 1
	j = 0
	for k in range(m):
		while j < n and x[j] <= y[k] + j:
			j += 1
		while i < m and y[i] - y[k] < j:
			i += 1
		ans = max(ans, i - k + already[j])
	return ans
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	(initial, special) = ([int(i) for i in input().split()], [int(i) for i in input().split()])
	(initial_left, initial_right) = ([-initial[i] for i in range(n) if initial[i] < 0][::-1], [initial[i] for i in range(n) if initial[i] > 0])
	(special_left, special_right) = ([-special[i] for i in range(m) if special[i] < 0][::-1], [special[i] for i in range(m) if special[i] > 0])
	print(solve(initial_left, special_left) + solve(initial_right, special_right))


def solve(a, b):
	n = len(a)
	m = len(b)
	bSuffixMatchCounts = [0 for _ in range(m)]
	i = n - 1
	cnts = 0
	for j in range(m - 1, -1, -1):
		while i >= 0 and a[i] > b[j]:
			i -= 1
		if i >= 0 and a[i] == b[j]:
			cnts += 1
		bSuffixMatchCounts[j] = cnts
	bSuffixMatchCounts.append(0)
	maxMatches = bSuffixMatchCounts[0]
	i = -1
	for j in range(m):
		while i + 1 < n and a[i + 1] <= b[j]:
			i += 1
		if i == -1:
			continue
		aCnts = i + 1
		left = b[j] - aCnts + 1
		bLeft = -1
		zz = m
		while zz > 0:
			while bLeft + zz < m and b[bLeft + zz] < left:
				bLeft += zz
			zz //= 2
		bLeft += 1
		matches = j - bLeft + 1 + bSuffixMatchCounts[j + 1]
		maxMatches = max(maxMatches, matches)
	return maxMatches

def main():
	t = int(input())
	allans = []
	for _ in range(t):
		(n, m) = readIntArr()
		a = readIntArr()
		b = readIntArr()
		aleft = []
		bleft = []
		aright = []
		bright = []
		for x in a:
			if x < 0:
				aleft.append(x)
			else:
				aright.append(x)
		for x in b:
			if x < 0:
				bleft.append(x)
			else:
				bright.append(x)
		aleft.reverse()
		bleft.reverse()
		for i in range(len(aleft)):
			aleft[i] *= -1
		for i in range(len(bleft)):
			bleft[i] *= -1
		allans.append(solve(aleft, bleft) + solve(aright, bright))
	multiLineArrayPrint(allans)
	return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
	return [int(x) for x in input().split()]
inf = float('inf')
MOD = 10 ** 9 + 7
main()


from math import ceil, log2
import os
import sys
from io import BytesIO, IOBase
from collections import defaultdict
from bisect import bisect_right
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	cnt1 = 0
	cnt2 = 0
	vis = defaultdict(lambda : 0)
	for j in b:
		vis[j] = 1
	i = 0
	while i < n:
		if a[i] > 0 and vis[a[i]]:
			cnt1 += 1
		elif a[i] < 0 and vis[a[i]]:
			cnt2 += 1
		i += 1
	i = 0
	tot1 = cnt1
	j = 0
	r = 0
	res = []
	l = 0
	u = 0
	cnt = 0
	while i < n and j < m:
		if a[i] < 0:
			i += 1
		else:
			r += 1
			if vis[a[i]]:
				cnt1 += -1
			if i == n - 1:
				while j < m:
					cnt += 0
					if b[j] > 0 and b[j] >= a[i]:
						res.append(b[j])
						l += 1
					j += 1
			else:
				while j < m and b[j] < a[i]:
					cnt += 1
					j += 1
				while j < m and b[j] < a[i + 1]:
					cnt += 1
					res.append(b[j])
					l += 1
					j += 1
			ans = 0
			while u < l:
				k = res[u] - r
				ind = bisect_right(res, k)
				ans = max(ans, u - ind + 1)
				u += 1
			tot1 = max(tot1, ans + cnt1)
			i += 1
	tot2 = cnt2
	i = n - 1
	j = m - 1
	r = 0
	res = []
	u = 0
	l = 0
	while i >= 0 and j >= 0:
		cnt += 1
		if a[i] > 0:
			i += -1
		else:
			r += 1
			if vis[a[i]]:
				cnt2 += -1
			if i == 0:
				while j >= 0:
					if b[j] < 0 and b[j] <= a[i]:
						res.append(-b[j])
						l += 1
					j += -1
			else:
				while j >= 0 and b[j] > a[i]:
					j += -1
				while j >= 0 and b[j] > a[i - 1]:
					res.append(-b[j])
					l += 1
					j += -1
			ans = 0
			while u < l:
				k = res[u] - r
				ind = bisect_right(res, k)
				ans = max(ans, u - ind + 1)
				u += 1
			tot2 = max(tot2, cnt2 + ans)
			i += -1
	print(tot1 + tot2)


import sys
from bisect import *
import bisect as bi
import collections as cc
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
for tc in range(int(input())):
	(n, m) = I()
	a = I()
	b = I()

	def ch(a, b):
		given = sorted(set(a) & set(b))
		best = len(given)
		for i in b:
			boxes = bisect_right(a, i)
			if boxes:
				sol = bisect_right(b, i) - bisect_right(b, i - boxes)
				sol += len(given) - bisect_right(given, i)
				best = max(sol, best)
		return best
	i = bi.bisect(a, 0)
	j = bi.bisect(b, 0)
	pa = a[i:]
	pb = b[j:]
	na = [abs(i) for i in a[:i]][::-1]
	nb = [abs(i) for i in b[:j]][::-1]
	print(ch(pa, pb) + ch(na, nb))


import sys
input = sys.stdin.readline
import bisect
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	for (i, a) in enumerate(A):
		if a > 0:
			start = i
			break
	else:
		start = n
	right = 0
	if start < n:
		(i, j) = (n - 1, m - 1)
		pre = 0
		while i >= start and j >= 0:
			if A[i] > B[j]:
				i -= 1
				continue
			cnt = i - start + 1
			idx = bisect.bisect_left(B, B[j] - cnt + 1)
			cnt2 = j - idx + 1
			right = max(right, pre + cnt2)
			if A[i] == B[j]:
				pre += 1
			j -= 1
	left = 0
	if start > 0:
		start -= 1
		(i, j) = (0, 0)
		pre = 0
		while i <= start and j < m:
			if A[i] < B[j]:
				i += 1
				continue
			cnt = start - i + 1
			idx = bisect.bisect(B, B[j] + cnt - 1) - 1
			cnt2 = idx - j + 1
			left = max(left, pre + cnt2)
			if A[i] == B[j]:
				pre += 1
			j += 1
	ans = left + right
	print(ans)


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
import bisect

def gift():
	for _ in range(t):
		(n, m) = list(map(int, input().split()))
		boxs = list(map(int, input().split()))
		poss = list(map(int, input().split()))
		ap = []
		bp = []
		am = []
		bm = []
		for i in boxs:
			if i > 0:
				ap.append(i)
			else:
				am.append(-1 * i)
		for i in poss:
			if i > 0:
				bp.append(i)
			else:
				bm.append(-1 * i)
		am.reverse()
		bm.reverse()
		rembox = len(ap)
		setbox = 0
		pans = 0
		for i in range(len(bp) - 1, -1, -1):
			nb = bp[i]
			while len(ap) > 0 and ap[-1] > nb:
				rembox -= 1
				ap.pop()
			pans = max(pans, setbox + i - bisect.bisect_right(bp, nb - rembox) + 1)
			if len(ap) > 0 and nb == ap[-1]:
				rembox -= 1
				setbox += 1
				ap.pop()
		mans = 0
		ap = am
		bp = bm
		rembox = len(ap)
		setbox = 0
		for i in range(len(bp) - 1, -1, -1):
			nb = bp[i]
			while len(ap) > 0 and ap[-1] > nb:
				rembox -= 1
				ap.pop()
			mans = max(mans, setbox + i - bisect.bisect_right(bp, nb - rembox) + 1)
			if len(ap) > 0 and nb == ap[-1]:
				rembox -= 1
				setbox += 1
				ap.pop()
		yield (pans + mans)
t = int(input())
ans = gift()
print(*ans, sep='\n')


import sys
import bisect
import itertools
input = sys.stdin.readline

def cnt(C, D):
	score = [0] * len(C)
	set_d = set(D)
	for i in range(len(C)):
		if C[i] in set_d:
			score[i] = 1
	score = list(itertools.accumulate(score[::-1]))
	score = score[::-1]
	score += [0]
	ma = score[0]
	hako_len = 0
	for d in D:
		for i in range(hako_len, len(C)):
			if C[i] <= hako_len + d - 1:
				hako_len += 1
			else:
				break
		if hako_len == 0:
			continue
		ma = max(ma, bisect.bisect_right(D, d - 1 + hako_len) - bisect.bisect_right(D, d - 1) + score[hako_len])
	return ma

def main():
	t = int(input())
	for _ in range(t):
		(N, M) = [int(x) for x in input().split()]
		A = [int(x) for x in input().split()]
		B = [int(x) for x in input().split()]
		A_plus = [x for x in A if x > 0]
		B_plus = [x for x in B if x > 0]
		A_minus = [-x for x in A if x < 0]
		B_minus = [-x for x in B if x < 0]
		x = cnt(A_plus, B_plus)
		y = cnt(A_minus[::-1], B_minus[::-1])
		print(x + y)
main()


import os
import sys
from io import BytesIO, IOBase
import math
from collections import Counter
import bisect

def func1(array_a, array_b):
	if not array_a or not array_b:
		return 0
	max_count = 0
	curr = 0
	b_start = 0
	b_end = 0
	good_pos = set(array_a).intersection(set(array_b))
	good_len = len(good_pos)
	while b_end < len(array_b):
		while curr < len(array_a) and array_a[curr] <= array_b[b_end]:
			if array_a[curr] in good_pos:
				good_len -= 1
			curr += 1
		while b_start < b_end and array_b[b_start] + curr <= array_b[b_end]:
			b_start += 1
		max_count = max(max_count, min(b_end - b_start + 1, curr) + good_len)
		b_end += 1
	return max_count

def func(array_a, array_b):
	a_0 = bisect.bisect_left(array_a, 0)
	b_0 = bisect.bisect_left(array_b, 0)
	return func1(array_a[a_0:], array_b[b_0:]) + func1([-i for i in array_a[:a_0][::-1]], [-i for i in array_b[:b_0][::-1]])

def main():
	num_test = int(parse_input())
	for _ in range(num_test):
		(n, m) = [int(i) for i in parse_input().split()]
		array_a = [int(i) for i in parse_input().split()]
		array_b = [int(i) for i in parse_input().split()]
		print(func(array_a, array_b))
parse_input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from sys import stdin, stdout
from bisect import bisect_left, bisect_right

def get_ans(arr, arr_m):
	m = len(arr_m)
	n = len(arr)
	dp = [0 for _ in range(m)]
	j = n - 1
	for i in range(m - 1, -1, -1):
		while j >= 0 and arr_m[i] < arr[j]:
			j -= 1
		if i != m - 1:
			dp[i] = dp[i + 1]
		if j >= 0 and arr[j] == arr_m[i]:
			dp[i] += 1
	mx = 0
	for i in range(m):
		cnt_n = bisect_right(arr, arr_m[i])
		left_m = arr_m[i] - cnt_n + 1
		left_pos = bisect_left(arr_m, left_m)
		cnt_m = i - left_pos + 1
		if i < m - 1:
			cnt_m += dp[i + 1]
		mx = max(mx, cnt_m)
	return mx

def main():
	t = int(stdin.readline())
	for _ in range(t):
		(n, m) = list(map(int, stdin.readline().split()))
		arr = list(map(int, stdin.readline().split()))
		arr_m = list(map(int, stdin.readline().split()))
		(posi_b, posi_m) = ([], [])
		(neg_b, neg_m) = ([], [])
		for i in range(n):
			if arr[i] > 0:
				posi_b.append(arr[i])
			else:
				neg_b.append(arr[i])
		tmp_b = []
		for i in range(len(neg_b) - 1, -1, -1):
			tmp_b.append(neg_b[i] * -1)
		neg_b = tmp_b
		for i in range(m):
			if arr_m[i] > 0:
				posi_m.append(arr_m[i])
			else:
				neg_m.append(arr_m[i])
		tmp_b = []
		for i in range(len(neg_m) - 1, -1, -1):
			tmp_b.append(neg_m[i] * -1)
		neg_m = tmp_b
		l = get_ans(posi_b, posi_m)
		r = get_ans(neg_b, neg_m)
		ans = l + r
		stdout.write(str(ans) + '\n')
main()


from bisect import *
from sys import *
input = stdin.readline

def pref(b, a):
	switch = [0] * len(b)
	till = [0] * len(b)
	j = 0
	for i in range(len(b)):
		for idx in range(j, len(a)):
			if a[idx] > b[i]:
				break
			j = idx
		switch[i] = int(a[j] == b[i])
		till[i] = j + 1 if a[j] <= b[i] else 0
	return (switch, till)

def calc(b, a):
	(eq, currTill) = pref(b, a)
	s = sum(eq)
	ans = 0
	for i in range(len(b)):
		idx = bisect_right(b, b[i] - currTill[i])
		s -= eq[i]
		ans = max(ans, i - idx + 1 + s)
	return ans
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	idx = bisect_left(a, 0)
	neg_a = [-a[i] for i in range(idx - 1, -1, -1)]
	a = a[idx:]
	b = list(map(int, input().split()))
	idx = bisect_left(b, 0)
	neg_b = [-b[i] for i in range(idx - 1, -1, -1)]
	b = b[idx:]
	(c1, c2) = (0, 0)
	if a and b:
		c1 += calc(b, a)
	if neg_b and neg_a:
		c2 += calc(neg_b, neg_a)
	print(c1 + c2)


from bisect import bisect_left

def ggwp(pos, neg):
	if len(pos) == 0 or len(neg) == 0:
		return 0
	a = len(pos) - 1
	b = len(neg) - 1
	ans = 0
	already_in_position = 0
	while a >= 0 and b >= 0:
		if pos[a] > neg[b]:
			a -= 1
			continue
		tot_boxes_behind = a + 1
		index_of_boxes_available = bisect_left(neg, neg[b] - tot_boxes_behind + 1)
		boxes_finally_filled = b - index_of_boxes_available + 1
		ans = max(ans, already_in_position + boxes_finally_filled)
		if pos[a] == neg[b]:
			already_in_position += 1
		b -= 1
	return ans
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	apos = [i for i in a if i > 0]
	aneg = [-i for i in a if i < 0]
	aneg.reverse()
	bpos = [i for i in b if i > 0]
	bneg = [-i for i in b if i < 0]
	bneg.reverse()
	ans = 0
	ans += ggwp(apos, bpos)
	ans += ggwp(aneg, bneg)
	print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()
from bisect import bisect_right as bsl
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	bd_a = bsl(A, 0)
	bd_b = bsl(B, 0)
	(A1, B1) = (A[bd_a:], B[bd_b:])
	(A2, B2) = (A[:bd_a], B[:bd_b])
	(A0, B0) = ([-a for a in A2[::-1]], [-b for b in B2[::-1]])
	ans0 = 0
	if A0 and B0:
		L0 = []
		Same0 = [0] * bd_b
		for k in range(bd_b):
			b = B0[k]
			bi = bsl(A0, b)
			L0.append([b, bi])
			if bi < bd_a + 1 and A0[bi - 1] == b:
				Same0[k] = Same0[k - 1] + 1
			else:
				Same0[k] = Same0[k - 1]
		for i in range(bd_b):
			if L0[i][1]:
				(u, l) = (bd_b, i)
				while u > l + 1:
					mid = (u + l) // 2
					if L0[mid][1] > B0[mid] - B0[i]:
						l = mid
					else:
						u = mid
				bans = l
				ans = bans - i + Same0[-1] - Same0[bans] + 1
				if ans > ans0:
					ans0 = ans
	ans1 = 0
	if A1 and B1:
		L1 = []
		Same1 = [0] * (m - bd_b)
		for k in range(m - bd_b):
			b = B1[k]
			bi = bsl(A1, b)
			L1.append([b, bi])
			if bi < n - bd_a + 1 and A1[bi - 1] == b:
				Same1[k] = Same1[k - 1] + 1
			else:
				Same1[k] = Same1[k - 1]
		for i in range(m - bd_b):
			if L1[i][1]:
				(u, l) = (m - bd_b, i)
				while u > l + 1:
					mid = (u + l) // 2
					if L1[mid][1] > B1[mid] - B1[i]:
						l = mid
					else:
						u = mid
				bans = l
				ans = bans - i + Same1[-1] - Same1[bans] + 1
				if ans > ans1:
					ans1 = ans
	print(ans0 + ans1)


import sys
from bisect import bisect_left as l
r = range

def s(A, B):
	S = set(A)
	b = len(B)
	C = [0] * (b + 1)
	for i in r(b - 1, -1, -1):
		if B[i] in S:
			C[i] += 1
		C[i] += C[i + 1]
	a = C[0]
	X = 0
	for i in r(b):
		while X < len(A) and A[X] <= B[i]:
			X += 1
		if X > 0:
			a = max(a, l(B, B[i]) - l(B, B[i] - X + 1) + 1 + C[i + 1])
	return a
o = [*open(0)]
i = 2
p = lambda i: map(int, o[i].split())
while i < len(o):
	A = []
	X = []
	B = []
	Y = []
	for v in p(i):
		if v < 0:
			A += [-v]
		else:
			B += [v]
	for w in p(i + 1):
		if w < 0:
			X += [-w]
		else:
			Y += [w]
	print(s(A[::-1], X[::-1]) + s(B, Y))
	i += 3


import sys
import math
import bisect
from sys import stdin, stdout
from math import gcd, floor, sqrt, log2, ceil
from collections import defaultdict as dd
from bisect import bisect_left as bl, bisect_right as br
from bisect import insort
from collections import Counter
from collections import deque
from heapq import heappush, heappop, heapify
from itertools import permutations, combinations
from itertools import accumulate as ac
mod = int(1000000000.0) + 7
ip = lambda : int(stdin.readline())
inp = lambda : map(int, stdin.readline().split())
ips = lambda : stdin.readline().rstrip()
out = lambda x: stdout.write(str(x) + '\n')
t = ip()
for _ in range(t):
	(n, m) = inp()
	a = list(inp())
	b = list(inp())
	posa = []
	posb = []
	nega = []
	negb = []
	for i in a:
		if i > 0:
			posa.append(i)
		else:
			nega.append(abs(i))
	for i in b:
		if i > 0:
			posb.append(i)
		else:
			negb.append(abs(i))
	nega.sort()
	negb.sort()
	posa = list(posa)
	posb = list(posb)
	ans1 = []
	mark = dd(bool)
	for i in posa:
		mark[i] = True
	cur = 0
	for i in posb:
		if mark[i]:
			cur += 1
	suff = dd(int)
	cur = 0
	for i in range(len(posb) - 1, -1, -1):
		if mark[posb[i]]:
			cur += 1
		suff[posb[i]] = cur
	ans1.append(cur)
	ct = 0
	for i in range(len(posb)):
		cur = 0
		ele = posb[i]
		placea = bl(posa, ele + 1)
		if placea == 0:
			pass
		else:
			great1 = bl(posb, ele + 1)
			great2 = bl(posb, ele - placea + 1)
			cur += great1 - great2
		if i == len(posb) - 1:
			pass
		else:
			nex = posb[i + 1]
			cur += suff[nex]
		ans1.append(cur)
	a1 = max(ans1)
	posa = list(nega)
	posb = list(negb)
	posa.sort()
	posb.sort()
	ans1 = []
	mark = dd(bool)
	for i in posa:
		mark[i] = True
	cur = 0
	for i in posb:
		if mark[i]:
			cur += 1
	suff = dd(int)
	cur = 0
	for i in range(len(posb) - 1, -1, -1):
		if mark[posb[i]]:
			cur += 1
		suff[posb[i]] = cur
	ans1.append(cur)
	ct = 0
	for i in range(len(posb)):
		cur = 0
		ele = posb[i]
		placea = bl(posa, ele + 1)
		if placea == 0:
			pass
		else:
			great1 = bl(posb, ele + 1)
			great2 = bl(posb, ele - placea + 1)
			cur += great1 - great2
		if i == len(posb) - 1:
			pass
		else:
			nex = posb[i + 1]
			cur += suff[nex]
		ans1.append(cur)
	a2 = max(ans1)
	ans = a1 + a2
	print(ans)


from bisect import bisect_left

def calc(a, b):
	if len(a) == 0 or len(b) == 0:
		return 0
	(n, m) = (len(a) - 1, len(b) - 1)
	ans = 0
	p = 0
	while n >= 0 and m >= 0:
		if a[n] > b[m]:
			n -= 1
			continue
		c = n + 1
		ind = bisect_left(b, b[m] - c + 1)
		c2 = m - ind + 1
		ans = max(ans, p + c2)
		if a[n] == b[m]:
			p += 1
		m -= 1
	return ans
for nt in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	ans = calc([i for i in a if i > 0], [i for i in b if i > 0])
	ans += calc([-i for i in a if i < 0][::-1], [-i for i in b if i < 0][::-1])
	print(ans)


def putin():
	return map(int, input().split())

def solve(A, B):
	A.append(float('inf'))
	B.append(float('inf'))
	stand = set(A).intersection(set(B))
	stand_answer = len(stand)
	a_cnt = 0
	b_cnt = 0
	dyn_answer = []
	d_cnt = 0
	answer = stand_answer
	while a_cnt + b_cnt < len(A) + len(B) - 2:
		if B[b_cnt] < A[a_cnt]:
			dyn_answer.append(B[b_cnt])
			for i in range(d_cnt, len(dyn_answer)):
				if dyn_answer[i] < B[b_cnt] - a_cnt + 1:
					d_cnt += 1
				else:
					break
			answer = max(answer, len(dyn_answer) - d_cnt + stand_answer)
			b_cnt += 1
		elif B[b_cnt] > A[a_cnt]:
			for i in range(d_cnt, len(dyn_answer)):
				if dyn_answer[i] < A[a_cnt] - a_cnt:
					d_cnt += 1
				else:
					break
			answer = max(answer, len(dyn_answer) - d_cnt + stand_answer)
			a_cnt += 1
		else:
			dyn_answer.append(B[b_cnt])
			stand_answer -= 1
			for i in range(d_cnt, len(dyn_answer)):
				if dyn_answer[i] < A[a_cnt] - a_cnt:
					d_cnt += 1
				else:
					break
			b_cnt += 1
			a_cnt += 1
			answer = max(answer, len(dyn_answer) - d_cnt + stand_answer)
	return answer - 1

def sol():
	(n, m) = putin()
	A = list(putin())
	B = list(putin())
	A1 = []
	A2 = []
	for i in range(len(A)):
		if A[i] < 0:
			A1.append(-A[i])
		if A[i] > 0:
			A2 = A[i:]
			break
	B1 = []
	B2 = []
	for i in range(len(B)):
		if B[i] < 0:
			B1.append(-B[i])
		if B[i] > 0:
			B2 = B[i:]
			break
	A1.reverse()
	B1.reverse()
	print(solve(A1, B1) + solve(A2, B2))
for iter in range(int(input())):
	sol()


from bisect import bisect_left
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	ai = bisect_left(a, 0)
	bi = bisect_left(b, 0)

	def solve(a, b):
		n = len(a)
		m = len(b)
		pp = [0 for _ in range(len(a) + 1)]
		latest = len(b) - 1
		for i in reversed(range(len(a))):
			prev = pp[i + 1]
			while latest >= 0 and a[i] < b[latest]:
				latest -= 1
			if latest >= 0 and a[i] == b[latest]:
				prev += 1
				latest -= 1
			pp[i] = prev
		size = 0
		(l1, r1) = (0, 0)
		latest = 0
		res = 0
		for i in range(m):
			while size < n and b[i] + size > a[size]:
				size += 1
			while latest < m and b[latest] < b[i] + size:
				latest += 1
			res = max(res, latest - i + pp[size])
		return res
	print(solve(a[ai:], b[bi:]) + solve([-x for x in a[:ai]][::-1], [-x for x in b[:bi]][::-1]))


from bisect import bisect
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	set11 = set()
	set12 = set()
	set21 = set()
	set22 = set()
	arr1 = []
	arr2 = []
	for i in a:
		if i < 0:
			set11.add(-1 * i)
			arr1.append(-1 * i)
		else:
			set21.add(i)
			arr2.append(i)
	arr1 = arr1[::-1]
	brr1 = []
	brr2 = []
	for i in b:
		if i < 0:
			set12.add(-1 * i)
			brr1.append(-1 * i)
		else:
			set22.add(i)
			brr2.append(i)
	brr1 = brr1[::-1]
	ans = 0
	clist1 = list(set11 & set12)
	clist2 = list(set21 & set22)
	clist1.sort()
	clist2.sort()
	l2 = len(clist2)
	l1 = len(clist1)
	for i in range(len(brr2)):
		x = brr2[i]
		index = bisect(arr2, x)
		val = x - index
		r = bisect(brr2, val)
		i2 = bisect(clist2, x)
		total = l2 - i2
		cnt = i - r + 1 + total
		ans = max(ans, cnt)
	ans1 = 0
	for i in range(len(brr1)):
		x = brr1[i]
		index = bisect(arr1, x)
		val = x - index
		r = bisect(brr1, val)
		i2 = bisect(clist1, x)
		total = l1 - i2
		cnt = i - r + 1 + total
		ans1 = max(ans1, cnt)
	print(ans + ans1)


import sys, math, itertools, random
from collections import defaultdict
from bisect import bisect_left, bisect_right
INF = sys.maxsize

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def input():
	return sys.stdin.readline().strip()
mod = 10 ** 9 + 7

def calc(a, b):
	(n, m) = (len(a), len(b))
	suff = [0] * (n + 1)
	r = m - 1
	for i in range(n - 1, -1, -1):
		suff[i] = suff[i + 1]
		while r >= 0 and b[r] > a[i]:
			r -= 1
		if r >= 0 and b[r] == a[i]:
			suff[i] += 1
	ans = 0
	(j, r) = (0, 0)
	for l in range(m):
		while j < n and a[j] <= b[l] + j:
			j += 1
		while r < m and b[r] - b[l] < j:
			r += 1
		ans = max(ans, r - l + suff[j])
	return ans
for _ in range(int(input())):
	(n, m) = get_ints()
	a = get_array()
	b = get_array()
	(al, bl, ar, br) = ([], [], [], [])
	for i in a:
		if i < 0:
			al.append(-i)
		else:
			ar.append(i)
	for i in b:
		if i < 0:
			bl.append(-i)
		else:
			br.append(i)
	al.reverse()
	bl.reverse()
	ans = calc(al, bl) + calc(ar, br)
	print(ans)


from sys import stdin, stdout
import bisect
input = stdin.readline

def solve(a, b):
	n = len(a)
	m = len(b)
	if not n or not m:
		return 0
	ans = 0
	good_vals = set(b)
	pre = []
	s = 0
	for i in range(n):
		if a[i] in good_vals:
			s += 1
		pre.append(s)
	for i in range(m):
		ind = bisect.bisect(a, b[i])
		temp = pre[-1]
		before = ind
		if ind:
			temp -= pre[ind - 1]
		start = b[i] - before + 1
		ind2 = bisect.bisect_left(b, start)
		temp += i - ind2 + 1
		ans = max(ans, temp)
	return ans
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = [int(x) for x in input().split()]
	b = [int(x) for x in input().split()]
	neg_a = []
	pos_a = []
	for i in a:
		if i < 0:
			neg_a.append(abs(i))
		else:
			pos_a.append(i)
	neg_b = []
	pos_b = []
	for i in b:
		if i < 0:
			neg_b.append(abs(i))
		else:
			pos_b.append(i)
	neg_a = neg_a[::-1]
	neg_b = neg_b[::-1]
	ans = solve(neg_a, neg_b) + solve(pos_a, pos_b)
	print(ans)


import os, sys, heapq as h, time
from io import BytesIO, IOBase
from types import GeneratorType
from bisect import bisect_left, bisect_right
from collections import defaultdict as dd, deque as dq, Counter as dc
import math, string
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.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 -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def getInt():
	return int(input())

def getStrs():
	return input().split()

def getInts():
	return list(map(int, input().split()))

def getStr():
	return input()

def listStr():
	return list(input())

def getMat(n):
	return [getInts() for _ in range(n)]

def isInt(s):
	return '0' <= s[0] <= '9'
MOD = 10 ** 9 + 7

def solve():
	(N, M) = getInts()
	A = getInts()
	B = getInts()
	B_set = set(B)
	A_left = [-a for a in A if a < 0][::-1]
	A_right = [a for a in A if a > 0]
	B_left = [-b for b in B if b < 0][::-1]
	B_right = [b for b in B if b > 0]
	L_pref = [0]
	curr = 0
	for a in reversed(A_left):
		if -a in B_set:
			curr += 1
		L_pref.append(curr)
	L = curr
	R_pref = [0]
	curr = 0
	for a in reversed(A_right):
		if a in B_set:
			curr += 1
		R_pref.append(curr)
	R = curr

	def get_(X, AA, BB, PREF):
		pos = 0
		boxes = 0
		specials = 0
		shift = 0
		while specials < len(BB):
			next_pos = BB[specials]
			if boxes < len(AA):
				next_box = AA[boxes]
			else:
				next_box = 10 ** 9 + 1
			pos = min(next_pos, next_box)
			if next_box == pos:
				boxes += 1
			if next_pos == pos:
				specials += 1
				if boxes > 0:
					while BB[specials - 1] - BB[shift] > boxes - 1:
						shift += 1
					X = max(X, PREF[boxes] + specials - shift)
		return X
	ans_left = get_(L, A_left, B_left, L_pref[::-1])
	ans_right = get_(R, A_right, B_right, R_pref[::-1])
	return ans_left + ans_right
for _ in range(getInt()):
	print(solve())


import sys
input = sys.stdin.readline

def solve2(a, b):
	n = len(a)
	m = len(b)
	if n <= 0 or m <= 0:
		return 0
	z = max(a[-1], b[-1]) + 3
	need = [0] * z
	for i in b:
		need[i] = 1
	r = 0
	for i in range(0, z - 1):
		have = [0] * z
		for j in a:
			if j <= i:
				have[i + 1] += 1
			else:
				have[j] += 1
		for j in range(z):
			if have[j] > 1:
				if j + 1 < z:
					have[j + 1] += have[j] - 1
				have[j] = 1
		c = 0
		for j in range(z):
			if have[j] == 1 and need[j] == 1:
				c += 1
		r = max(r, c)
	return r

def solve1(a, b):
	n = len(a)
	m = len(b)
	if n <= 0 or m <= 0:
		return 0
	c = [0] * (n + 1)
	bi = m - 1
	h = 0
	for i in range(n - 1, -1, -1):
		p = a[i]
		while bi >= 0 and b[bi] > p:
			bi -= 1
		if bi >= 0 and p == b[bi]:
			bi -= 1
			h += 1
		c[i] = h
	h = 1
	p = a[0]
	g = 0
	ai = 1
	bi = 0
	bj = 0
	while bi < m and b[bi] < p:
		bi += 1
	bj = bi
	if bi < m and b[bi] == p:
		g += 1
		bi += 1
	r = g + c[ai]
	while True:
		if ai < n:
			x = a[ai] - p - h
			if x == 0:
				ai += 1
				if bi < m and b[bi] == p + h:
					bi += 1
					g += 1
				h += 1
			elif bi < m:
				y = b[bi] - p - h + 1
				if y == 0:
					g += 1
					bi += 1
				else:
					p += min(x, y)
			else:
				p += x
		elif bi < m:
			y = b[bi] - p - h + 1
			if y == 0:
				g += 1
				bi += 1
			else:
				p += y
		else:
			break
		while bj < m and b[bj] < p:
			g -= 1
			bj += 1
		r = max(r, g + c[ai])
	return r

def solve():
	(n, m) = map(int, input().split())
	al = []
	ar = []
	for i in map(int, input().split()):
		if i < 0:
			al.append(-i)
		else:
			ar.append(i)
	bl = []
	br = []
	for i in map(int, input().split()):
		if i < 0:
			bl.append(-i)
		else:
			br.append(i)
	al.reverse()
	bl.reverse()
	s1 = solve1(al, bl)
	s2 = solve1(ar, br)
	print(s1 + s2)
for i in range(int(input())):
	solve()


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcdefghijklmnopqrstuvwxyz'
M = 998244353
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def Ans(a, s):
	a.sort()
	s.sort()
	sp = set(s)
	correct = [0]
	base = 0
	for i in a:
		if i in sp:
			base += 1
		correct.append(base)
	ans = base
	outer_bound = 0
	for r in s:
		box = bisect_right(a, r)
		l = r - box + 1
		here = base - correct[box]
		outer_bound += 1
		here += outer_bound - bisect_left(s, l)
		ans = max(here, ans)
	return ans
for _ in range(Int()):
	(n, m) = value()
	a = array()
	s = array()
	a1 = [i for i in a if i >= 0]
	a2 = [abs(i) for i in a if i < 0]
	s1 = [i for i in s if i >= 0]
	s2 = [abs(i) for i in s if i < 0]
	print(Ans(a1, s1) + Ans(a2, s2))


import os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	aset = set()
	for i in range(n):
		aset.add(a[i])
	apos = []
	aneg = []
	bpos = []
	bneg = []
	for i in range(n):
		if a[i] > 0:
			apos.append(a[i])
		else:
			aneg.append(-a[i])
	posdup = []
	negdup = []
	for i in b:
		if i in aset:
			if i > 0:
				posdup.append(i)
			else:
				negdup.append(-i)
	posdup.sort()
	posdup.reverse()
	negdup.sort()
	negdup.reverse()
	for i in range(m):
		if b[i] > 0:
			bpos.append(b[i])
		else:
			bneg.append(-b[i])
	aneg.reverse()
	bneg.reverse()
	currbox = 0
	currend = 0
	ans1 = len(posdup)
	for i in range(len(bpos)):
		while currbox < len(apos) and currbox + bpos[i] >= apos[currbox]:
			currbox += 1
		while currend < len(bpos) and bpos[currend] <= currbox - 1 + bpos[i]:
			currend += 1
		while posdup and posdup[-1] <= currbox + bpos[i]:
			posdup.pop()
		ans1 = max(ans1, currend - i + len(posdup))
	ans2 = len(negdup)
	currbox = 0
	currend = 0
	for i in range(len(bneg)):
		while currbox < len(aneg) and currbox + bneg[i] >= aneg[currbox]:
			currbox += 1
		while currend < len(bneg) and bneg[currend] <= currbox - 1 + bneg[i]:
			currend += 1
		while negdup and negdup[-1] <= currbox + bneg[i]:
			negdup.pop()
		ans2 = max(ans2, currend - i + len(negdup))
	print(ans1 + ans2)


from bisect import bisect
from sys import stdin, gettrace
if gettrace():

	def inputi():
		return input()
else:

	def input():
		return next(stdin)[:-1]

	def inputi():
		return stdin.buffer.readline()
INF = 10000000000

def solve():
	(n, m) = map(int, input().split())
	aa = [int(a) for a in input().split()]
	bb = [int(a) for a in input().split()]
	az = bisect(aa, 0)
	bz = bisect(bb, 0)
	al = [-a for a in aa[:az][::-1]]
	bl = [-b for b in bb[:bz][::-1]]
	ar = aa[az:]
	br = bb[bz:]
	print(oneside(al, bl) + oneside(ar, br))

def oneside(aa, bb):
	if len(aa) == 0 or len(bb) == 0:
		return 0
	bf = [0]
	ap = len(aa) - 1
	for b in bb[::-1]:
		while ap >= 0 and aa[ap] > b:
			ap -= 1
		if aa[ap] == b:
			bf.append(bf[-1] + 1)
		else:
			bf.append(bf[-1])
	bf = bf[::-1]
	ap = 0
	bs = [0]
	bc = 0
	for i in range(len(bb)):
		while ap < len(aa) and aa[ap] < bb[i]:
			ap += 1
		while bc >= 0 and bb[i - bc] <= bb[i] - ap:
			bc -= 1
		bc += 1
		bs.append(bc)
	return max((f + s for (f, s) in zip(bf, bs)))

def main():
	t = int(input())
	for _ in range(t):
		solve()
main()


import bisect

def solve(a, b):
	n = len(a)
	m = len(b)
	cnts = [0] * m
	sums = [0] * m
	j = n - 1
	for i in range(m - 1, -1, -1):
		while j >= 0 and b[i] < a[j]:
			j -= 1
		cnts[i] += j + 1
		if j >= 0 and b[i] == a[j]:
			sums[i] += 1
			j -= 1
		if i + 1 < m:
			sums[i] += sums[i + 1]
	ans = 0
	for i in range(m):
		if not cnts[i]:
			continue
		left = bisect.bisect_left(b, b[i] - cnts[i] + 1)
		range_ = i - left + 1
		s = sums[i + 1] if i + 1 < m else 0
		ans = max(range_ + s, ans)
	return ans

def main():
	t = int(input())
	result = []
	for _ in range(t):
		(n, m) = map(int, input().split())
		a = list(map(int, input().split()))
		b = list(map(int, input().split()))
		(la, ra) = ([], [])
		(lb, rb) = ([], [])
		for i in range(max(n, m)):
			if i < n:
				if a[i] < 0:
					la.append(-a[i])
				else:
					ra.append(a[i])
			if i < m:
				if b[i] < 0:
					lb.append(-b[i])
				else:
					rb.append(b[i])
		la.reverse()
		lb.reverse()
		ans = solve(la, lb) + solve(ra, rb)
		result.append(ans)
	print('\n'.join(map(str, result)))
main()


import bisect
import sys
from sys import stdin
tt = int(stdin.readline())
ans = []
for loop in range(tt):
	(n, m) = map(int, stdin.readline().split())
	a = list(map(int, stdin.readline().split()))
	b = list(map(int, stdin.readline().split()))
	ap = []
	bp = []
	am = []
	bm = []
	for i in a:
		if i > 0:
			ap.append(i)
		else:
			am.append(-1 * i)
	for i in b:
		if i > 0:
			bp.append(i)
		else:
			bm.append(-1 * i)
	am.reverse()
	bm.reverse()
	rembox = len(ap)
	setbox = 0
	pans = 0
	for i in range(len(bp) - 1, -1, -1):
		nb = bp[i]
		while len(ap) > 0 and ap[-1] > nb:
			rembox -= 1
			del ap[-1]
		pans = max(pans, setbox + i - bisect.bisect_right(bp, nb - rembox) + 1)
		if len(ap) > 0 and nb == ap[-1]:
			rembox -= 1
			setbox += 1
			del ap[-1]
	mans = 0
	ap = am
	bp = bm
	rembox = len(ap)
	setbox = 0
	for i in range(len(bp) - 1, -1, -1):
		nb = bp[i]
		while len(ap) > 0 and ap[-1] > nb:
			rembox -= 1
			del ap[-1]
		mans = max(mans, setbox + i - bisect.bisect_right(bp, nb - rembox) + 1)
		if len(ap) > 0 and nb == ap[-1]:
			rembox -= 1
			setbox += 1
			del ap[-1]
	ans.append(str(pans + mans))
print('\n'.join(ans))


import collections
import string
import math
import copy
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')
mo = 998244353

def exgcd(a, b):
	if not b:
		return (1, 0)
	(y, x) = exgcd(b, a % b)
	y -= a // b * x
	return (x, y)

def getinv(a, m):
	(x, y) = exgcd(a, m)
	return -1 if x == 1 else x % m

def comb(n, b):
	res = 1
	b = min(b, n - b)
	for i in range(b):
		res = res * (n - i) * getinv(i + 1, mo) % mo
	return res % mo

def quickpower(a, n):
	res = 1
	while n:
		if n & 1:
			res = res * a % mo
		n >>= 1
		a = a * a % mo
	return res

def dis(a, b):
	return abs(a[0] - b[0]) + abs(a[1] - b[1])

def getpref(x):
	if x > 1:
		return x * (x - 1) >> 1
	else:
		return 0

def orafli(upp):
	primes = []
	marked = [False for i in range(upp + 3)]
	for i in range(2, upp):
		if not marked[i]:
			primes.append(i)
		for j in primes:
			if i * j >= upp:
				break
			marked[i * j] = True
			if i % j == 0:
				break
	return primes

def read_list():
	return [int(i) for i in input().split()]

def read_int():
	s = input().split()
	if len(s) == 1:
		return int(s)
	else:
		return map(int, s)

def ask(s):
	print(f'? {s}', flush=True)

def answer(s):
	print(f'! {s}', flush=True)

def chk(la: list, lb: list):
	l = 0
	bu = 0
	ans = 0
	sa = set(la)
	sc = sa.intersection(lb)
	for (p, itr) in enumerate(list(lb)[::-1]):
		while la and la[-1] <= itr:
			la.pop()
			l += 1
		while lb and itr - l >= lb[-1]:
			lb.pop()
			bu += 1
		sc.discard(itr)
		ans = max(p + 1 - bu + len(sc), ans)
	return ans

def solve():
	(n, m) = read_int()
	ai = read_list()
	bi = read_list()
	a1 = []
	a2 = []
	b1 = []
	b2 = []
	for i in ai:
		if i < 0:
			a1.append(-i)
		else:
			a2.append(i)
	for i in bi:
		if i < 0:
			b1.append(-i)
		else:
			b2.append(i)
	a2.reverse()
	b2.reverse()
	print(chk(a1, b1) + chk(a2, b2))
t = int(input())
for ti in range(t):
	solve()


def main():
	import sys
	import bisect
	input = sys.stdin.buffer.readline
	t = int(input())
	ANS = []
	for _ in range(t):
		(n, m) = map(int, input().split())
		a = list(map(int, input().split()))
		b = list(map(int, input().split()))
		a1 = [-a[i] for i in range(n) if a[i] < 0]
		a1.sort()
		a2 = [a[i] for i in range(n) if a[i] > 0]
		b1 = [-b[i] for i in range(m) if b[i] < 0]
		b1.sort()
		b2 = [b[i] for i in range(m) if b[i] > 0]
		c = 0
		ans1 = 0
		if len(a1) and len(b1):
			P = [0] * (len(a1) + 1)
			j = len(b1) - 1
			for i in range(len(a1) - 1, -1, -1):
				P[i] = P[i + 1]
				while j > 0 and b1[j] > a1[i]:
					j -= 1
				if b1[j] == a1[i]:
					P[i] += 1
			for (i, x) in enumerate(a1):
				c += 1
				r = x
				j = bisect.bisect_left(b1, x - c + 1)
				while j < len(b1) and (i == len(a1) - 1 or b1[j] + c - 1 < a1[i + 1]):
					r = b1[j] + c - 1
					j2 = bisect.bisect_right(b1, r)
					if ans1 < j2 - j + P[i + 1]:
						ans1 = j2 - j + P[i + 1]
					j += 1
		ans2 = 0
		if len(a2) and len(b2):
			P = [0] * (len(a2) + 1)
			j = len(b2) - 1
			for i in range(len(a2) - 1, -1, -1):
				P[i] = P[i + 1]
				while j > 0 and b2[j] > a2[i]:
					j -= 1
				if b2[j] == a2[i]:
					P[i] += 1
			c = 0
			for (i, x) in enumerate(a2):
				c += 1
				r = x
				j = bisect.bisect_left(b2, x - c + 1)
				while j < len(b2) and (i == len(a2) - 1 or b2[j] + c - 1 < a2[i + 1]):
					r = b2[j] + c - 1
					j2 = bisect.bisect_right(b2, r)
					if ans2 < j2 - j + P[i + 1]:
						ans2 = j2 - j + P[i + 1]
					j += 1
		ANS.append(str(ans1 + ans2))
	print('\n'.join(ANS))
main()


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
from bisect import bisect_left, bisect_right
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = [int(x) for x in input().split()]
	b = [int(x) for x in input().split()]
	a_right = [int(x) for x in a if x > 0]
	b_right = [int(x) for x in b if x > 0]
	a_right.sort()
	b_right.sort()
	b_set_right = set(b_right)
	initial_special_right = [int(x) for x in a_right if x in b_set_right]
	cum_sum = [0]
	for i in range(len(b_right)):
		cum_sum.append(cum_sum[-1] + 1)
	ans_right = 0
	for i in range(len(b_right)):
		cnt = 0
		x = bisect_right(a_right, b_right[i])
		y = b_right[i] - x + 1
		y_idx = bisect_left(b_right, y)
		cnt = cum_sum[i + 1] - cum_sum[y_idx]
		cnt += len(initial_special_right) - bisect_right(initial_special_right, b_right[i])
		ans_right = max(ans_right, cnt)
	a_right = [-int(x) for x in a if x < 0]
	b_right = [-int(x) for x in b if x < 0]
	a_right.sort()
	b_right.sort()
	b_set_right = set(b_right)
	initial_special_right = [int(x) for x in a_right if x in b_set_right]
	cum_sum = [0]
	for i in range(len(b_right)):
		cum_sum.append(cum_sum[-1] + 1)
	ans_left = 0
	for i in range(len(b_right)):
		cnt = 0
		x = bisect_right(a_right, b_right[i])
		y = b_right[i] - x + 1
		y_idx = bisect_left(b_right, y)
		cnt = cum_sum[i + 1] - cum_sum[y_idx]
		cnt += len(initial_special_right) - bisect_right(initial_special_right, b_right[i])
		ans_left = max(ans_left, cnt)
	print(ans_left + ans_right)


import os
import sys
from io import BytesIO, IOBase

def solve(x, s):
	suf = [0] * (len(x) + 1)
	b = set(s)
	for i in range(len(x) - 1, -1, -1):
		if x[i] in b:
			suf[i] = 1
		suf[i] += suf[i + 1]
	(ma, j, box) = (0, 0, 0)
	for i in range(len(s)):
		while box < len(x) and x[box] <= s[i] + box:
			box += 1
		while j < len(s) and s[j] - s[i] < box:
			j += 1
		ma = max(ma, j - i + suf[box])
	return ma

def main():
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		(A1, A2, B1, B2) = ([], [], [], [])
		for i in map(int, input().split()):
			if i < 0:
				A1.append(-i)
			else:
				A2.append(i)
		for i in map(int, input().split()):
			if i < 0:
				B1.append(-i)
			else:
				B2.append(i)
		A1.reverse()
		B1.reverse()
		print(solve(A1, B1) + solve(A2, B2))
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys
input = sys.stdin.readline
import bisect
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	A = list(map(int, input().split()))
	B = list(map(int, input().split()))
	idx = bisect.bisect(A, 0)
	(posA, negA) = (A[idx:], A[:idx][::-1])
	idx = bisect.bisect(B, 0)
	(posB, negB) = (B[idx:], B[:idx][::-1])

	def cal(A, B):
		(right, pre) = (0, 0)
		(i, j) = (len(A) - 1, len(B) - 1)
		while i >= 0 and j >= 0:
			if A[i] > B[j]:
				i -= 1
				continue
			cnt = i + 1
			idx = bisect.bisect_left(B, B[j] - cnt + 1)
			cnt2 = j - idx + 1
			right = max(right, pre + cnt2)
			if A[i] == B[j]:
				pre += 1
			j -= 1
		return right
	ans = cal(posA, posB) + cal([-x for x in negA], [-x for x in negB])
	print(ans)


from os import path
from io import BytesIO, IOBase
import sys
from heapq import heappush, heappop
from functools import cmp_to_key as ctk
from collections import deque, Counter, defaultdict as dd
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

def ii():
	return int(input())

def si():
	return input().rstrip()

def mi():
	return map(int, input().split())

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('0')
file = 1

def ceil(a, b):
	return (a + b - 1) // b

def solve():
	for _ in range(ii()):
		(n, m) = mi()
		a = li()
		b = li()
		(p1, p2) = ([], [])
		(n1, n2) = ([], [])
		for i in a:
			if i > 0:
				p1.append(i)
			else:
				n1.append(-i)
		for i in b:
			if i > 0:
				p2.append(i)
			else:
				n2.append(-i)
		n1.reverse()
		n2.reverse()

		def calc(p1, p2):
			n = len(p1)
			m = len(p2)

			def get(l, r):
				idx = bisect_right(p2, r)
				idx1 = bisect_right(p2, l - 1)
				return idx - idx1
			suf = [0] * m
			j = n - 1
			for i in range(m - 1, -1, -1):
				if i != m - 1:
					suf[i] = suf[i + 1]
				while j >= 0 and p1[j] > p2[i]:
					j -= 1
				if j >= 0 and p1[j] == p2[i]:
					suf[i] += 1
			ans = 0
			for i in range(m):
				cur = 0
				if i != m - 1:
					cur = suf[i + 1]
				r = p2[i]
				idx = bisect_right(p1, r)
				l = r - idx + 1
				cur += bisect_right(p2, r) - bisect_right(p2, l - 1)
				ans = max(ans, cur)
			return ans
		print(calc(p1, p2) + calc(n1, n2))
if file:
	if path.exists('tmp/input.txt'):
		sys.stdin = open('tmp/input.txt', 'r')
		sys.stdout = open('tmp/output.txt', 'w')
	else:
		input = sys.stdin.readline
solve()


def some_random_function():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function5():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)
import os, sys
from io import BytesIO, IOBase
from bisect import bisect_right as bs, bisect_left as bs1

def main():
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		a = list(map(int, input().split()))
		b = list(map(int, input().split()))
		se = set(b)
		xxx = 0
		pref = []
		for i in range(n):
			if a[i] in se:
				xxx += 1
			pref.append(xxx)
		xxx = 0
		suff = []
		for i in range(n - 1, -1, -1):
			if a[i] in se:
				xxx += 1
			suff.append(xxx)
		suff.reverse()
		sp = bs(b, 0) - 1
		bo = bs(a, 0) - 1
		cnt = 0
		ans1 = 0
		while sp != -1:
			while bo != -1 and a[bo] >= b[sp] - cnt:
				bo -= 1
				cnt += 1
			xx = bs(b, b[sp] - cnt)
			ans1 = max(ans1, min(cnt, sp - xx + 1) + (pref[bo] if bo != -1 else 0))
			sp -= 1
		sp = bs(b, 0)
		bo = bs(a, 0)
		cnt = 0
		ans2 = 0
		while sp != m:
			while bo != n and a[bo] <= b[sp] + cnt:
				bo += 1
				cnt += 1
			xx = bs1(b, b[sp] + cnt) - 1
			ans2 = max(ans2, min(cnt, xx - sp + 1) + (suff[bo] if bo != n else 0))
			sp += 1
		print(ans1 + ans2)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def some_random_function1():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function2():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function3():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function4():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function6():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function7():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)

def some_random_function8():
	x = 10
	x *= 100
	i_dont_know = x
	why_am_i_writing_this = x * x
	print(i_dont_know)
	print(why_am_i_writing_this)
main()


from collections import deque

def bin_s(sum_arr, stored_arr, arr, l):
	maxi = 0
	for i in range(l - 1, -1, -1):
		r = i
		l = 0
		d = arr[i] - stored_arr[i] + 1
		while l < r:
			m = (l + r) // 2
			if arr[m] < d:
				l = m + 1
			else:
				r = m
		if arr[l] < d:
			l += 1
		maxi = max(maxi, i - l + 1 + sum_arr[i + 1])
	return maxi

def store(a, b, l):
	sum_a = [0] * (l + 1)
	stored = [0] * l
	count = 0
	stack = [-5] + a
	queue = deque(a + [9999999999])
	for i in range(l):
		while queue[0] <= b[i]:
			queue.popleft()
			count += 1
		stored[i] = count
	for i in range(l - 1, -1, -1):
		while stack[-1] > b[i]:
			stack.pop()
		if stack[-1] == b[i]:
			sum_a[i] += 1
		sum_a[i] += sum_a[i + 1]
	return (sum_a, stored)
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	pos_a = []
	neg_a = []
	a.append(999999999999)
	b.append(999999999999)
	(pos_b, neg_b) = ([], [])
	for i in range(n + 1):
		if a[i] > 0:
			pos_a = a[i:n]
			neg_a = a[:i]
			break
		a[i] *= -1
	for i in range(m + 1):
		if b[i] > 0:
			pos_b = b[i:m]
			neg_b = b[:i]
			break
		b[i] *= -1
	(sum_a, stored_a) = store(pos_a, pos_b, len(pos_b))
	(sum_b, stored_b) = store(neg_a[::-1], neg_b[::-1], len(neg_b))
	nm = bin_s(sum_a, stored_a, pos_b, len(pos_b))
	mn = bin_s(sum_b, stored_b, neg_b[::-1], len(neg_b))
	print(nm + mn)


import sys, functools, collections, bisect, math, heapq
input = sys.stdin.readline
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().strip().split())
	a = list(map(int, input().strip().split()))
	aset = set(a)
	b = list(map(int, input().strip().split()))
	bcommon = [0] * m
	ind = bisect.bisect_left(b, 0)
	bcommon[0] = 1 if b[0] in aset else 0
	for i in range(1, ind):
		bcommon[i] += bcommon[i - 1]
		if b[i] in aset:
			bcommon[i] += 1
	bcommon[m - 1] = 1 if b[m - 1] in aset else 0
	for i in range(m - 2, ind - 1, -1):
		bcommon[i] += bcommon[i + 1]
		if b[i] in aset:
			bcommon[i] += 1
	k = bisect.bisect_right(a, 0)
	resright = 0
	for i in range(ind, m):
		x = bisect.bisect_right(a, b[i])
		count = x - k
		y = bisect.bisect_left(b, b[i] - count + 1)
		res = i - y + 1
		res += bcommon[i + 1] if i < m - 1 else 0
		resright = max(res, resright)
	resleft = 0
	for i in range(ind - 1, -1, -1):
		x = bisect.bisect_left(a, b[i])
		count = k - x
		y = bisect.bisect_right(b, b[i] + count - 1)
		res = y - i
		res += bcommon[i - 1] if i > 0 else 0
		resleft = max(res, resleft)
	print(resleft + resright)


import sys
from bisect import bisect_left as l
r = range

def s(A, B):
	S = set(A)
	b = len(B)
	C = [0] * (b + 1)
	for i in r(b - 1, -1, -1):
		if B[i] in S:
			C[i] += 1
		C[i] += C[i + 1]
	a = C[0]
	X = 0
	for i in r(b):
		while X < len(A) and A[X] <= B[i]:
			X += 1
		if X > 0:
			a = max(a, l(B, B[i]) - l(B, B[i] - X + 1) + 1 + C[i + 1])
	return a
p = lambda : map(int, sys.stdin.buffer.readline().split())
for t in r(*p()):
	p()
	A = []
	X = []
	B = []
	Y = []
	for v in p():
		if v < 0:
			A.append(-v)
		else:
			B.append(v)
	for w in p():
		if w < 0:
			X.append(-w)
		else:
			Y.append(w)
	print(s(A[::-1], X[::-1]) + s(B, Y))


import sys
import bisect as bi
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))

def ans(a, b):
	an = 0
	if a:
		st = a[0]
	else:
		return 0
	prev = 0
	while b:
		cr = b[-1]
		ans = bi.bisect(a, cr)
		pos = bi.bisect(b, cr - ans)
		poss = min(len(b) - pos, ans)
		an = max(an, poss + prev)
		if cr == a[ans - 1]:
			prev += 1
		b.pop()
	return an
(t,) = I()
for _ in range(t):
	(n, m) = I()
	l = I()
	sp = I()
	an = 0
	fill = [0] * m
	rk = n
	pk = m
	for i in range(n):
		if l[i] > 0:
			rk = i
			break
	for i in range(m):
		if sp[i] > 0:
			pk = i
			break
	print(ans([-i for i in l[:rk][::-1]], [-i for i in sp[:pk][::-1]]) + ans(l[rk:], sp[pk:]))


import os
import sys
from io import BytesIO, IOBase
import math
import itertools
import bisect
import heapq

def main():
	pass
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def binary(n):
	return bin(n).replace('0b', '')

def decimal(s):
	return int(s, 2)

def pow2(n):
	p = 0
	while n > 1:
		n //= 2
		p += 1
	return p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(i)
			n = n / i
	if n > 2:
		l.append(int(n))
	return l

def isPrime(n):
	if n == 1:
		return False
	else:
		root = int(n ** 0.5)
		root += 1
		for i in range(2, root):
			if n % i == 0:
				return False
		return True

def maxPrimeFactors(n):
	maxPrime = -1
	while n % 2 == 0:
		maxPrime = 2
		n >>= 1
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			maxPrime = i
			n = n / i
	if n > 2:
		maxPrime = n
	return int(maxPrime)

def countcon(s, i):
	c = 0
	ch = s[i]
	for i in range(i, len(s)):
		if s[i] == ch:
			c += 1
		else:
			break
	return c

def lis(arr):
	n = len(arr)
	lis = [1] * n
	for i in range(1, n):
		for j in range(0, i):
			if arr[i] > arr[j] and lis[i] < lis[j] + 1:
				lis[i] = lis[j] + 1
	maximum = 0
	for i in range(n):
		maximum = max(maximum, lis[i])
	return maximum

def isSubSequence(str1, str2):
	m = len(str1)
	n = len(str2)
	j = 0
	i = 0
	while j < m and i < n:
		if str1[j] == str2[i]:
			j = j + 1
		i = i + 1
	return j == m

def maxfac(n):
	root = int(n ** 0.5)
	for i in range(2, root + 1):
		if n % i == 0:
			return n // i
	return n

def p2(n):
	c = 0
	while n % 2 == 0:
		n //= 2
		c += 1
	return c

def seive(n):
	primes = [True] * (n + 1)
	primes[1] = primes[0] = False
	for i in range(2, n + 1):
		if primes[i]:
			for j in range(i + i, n + 1, i):
				primes[j] = False
	p = []
	for i in range(0, n + 1):
		if primes[i]:
			p.append(i)
	return p

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def denofactinverse(n, m):
	fac = 1
	for i in range(1, n + 1):
		fac = fac * i % m
	return pow(fac, m - 2, m)

def numofact(n, m):
	fac = 1
	for i in range(1, n + 1):
		fac = fac * i % m
	return fac

def sumnum(n):
	s = 0
	for i in str(n):
		s += int(i)
	return s

def solve(a, b):
	b2 = set(b)
	same = []
	for i in a:
		if i in b2:
			same.append(i)
	ans = 0
	n = len(a)
	m = len(b)
	if n == 0 or m == 0 or a[0] > b[-1]:
		return 0
	sl = len(same)
	fans = 0
	for i in range(0, n):
		a[i] = a[i] - i
	for i in range(0, m):
		posa = bisect.bisect(a, b[i])
		if posa >= n:
			blocks = n
		else:
			blocks = posa
		pos2 = bisect.bisect(b, b[i] + blocks - 1)
		ans = pos2 - i
		ans += sl - bisect.bisect(same, blocks + b[i] - 1)
		fans = max(fans, ans)
	return fans
for xyz in range(0, int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	(an, bn) = ([], [])
	pos = n
	for i in range(0, n):
		if a[i] < 0:
			an.append(-a[i])
		else:
			pos = i
			break
	a = a[pos:]
	pos = n
	for i in range(0, m):
		if b[i] < 0:
			bn.append(-b[i])
		else:
			pos = i
			break
	b = b[pos:]
	bn = bn[::-1]
	an = an[::-1]
	print(solve(an, bn) + solve(a, b))


from sys import stdin, stdout
from math import gcd, sqrt, factorial, pi, inf
from collections import deque, defaultdict
from bisect import bisect, bisect_left
from itertools import permutations as per
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
L = lambda : list(R())
P = lambda x: stdout.write(str(x) + '\n')
nCr = lambda x, y: f[x] * inv(f[y] * f[x - y] % N) % N

def bin_l(a, r, val):
	l = 0
	r -= 1
	ans = 0
	while l <= r:
		m = (l + r) // 2
		if a[m] <= val:
			ans = m + 1
			l = m + 1
		else:
			r = m - 1
	return ans

def bin_h(a, r, val):
	l = 0
	r -= 1
	ans = 0
	while l <= r:
		m = (l + r) // 2
		if a[m] >= val:
			ans = m
			r = m - 1
		else:
			l = m + 1
	return ans

def get_ans(x, a):
	ln_x = len(x)
	ln_a = len(a)
	p = set(x)
	v = [1 if i in p else 0 for i in a]
	mx = sum(v)
	ans = mx
	for i in range(ln_a):
		mx -= v[i]
		low = bin_l(x, ln_x, a[i])
		if not low:
			continue
		ans = max(ans, mx + 1 + i - bin_h(a, ln_a, a[i] - low + 1))
	return ans
for _ in range(I()):
	(n, m) = R()
	x = []
	y = []
	for i in R():
		if i < 0:
			x += (abs(i),)
		else:
			y += (i,)
	x.reverse()
	a = []
	b = []
	for i in R():
		if i < 0:
			a += (abs(i),)
		else:
			b += (i,)
	a.reverse()
	print(get_ans(x, a) + get_ans(y, b))


from bisect import bisect_left

def proc(a, b):
	a_set = set(a)
	b_suffix = [0]
	cur_suffix = 0
	for val in reversed(b):
		if val in a_set:
			cur_suffix += 1
		b_suffix.append(cur_suffix)
	b_suffix = list(reversed(b_suffix))
	a_idx = 0
	ans = 0
	for (i, val) in enumerate(b):
		while a_idx < len(a) and a[a_idx] <= val:
			a_idx += 1
		chain_len = a_idx - 1
		start_pos = bisect_left(b, val - chain_len)
		cur_chain = i - start_pos + 1
		ans = max(ans, cur_chain + b_suffix[i + 1])
	return ans

def main():
	cases = int(input())
	ans_list = []
	for _ in range(cases):
		(n, m) = map(int, input().split(' '))
		a = list(map(int, input().split(' ')))
		b = list(map(int, input().split(' ')))
		zero_idx_a = bisect_left(a, 0)
		zero_idx_b = bisect_left(b, 0)
		(pos_a, pos_b) = (a[zero_idx_a:], b[zero_idx_b:])
		pos_ans = proc(pos_a, pos_b)
		(neg_a, neg_b) = (a[:zero_idx_a], b[:zero_idx_b])
		neg_a = list(reversed(list(map(lambda x: -x, neg_a))))
		neg_b = list(reversed(list(map(lambda x: -x, neg_b))))
		neg_ans = proc(neg_a, neg_b)
		ans_list.append(pos_ans + neg_ans)
	print('\n'.join(map(str, ans_list)))
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return 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 -= 1
		return 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.flush
		self.writable = self.buffer.writable
		self.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, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys, math, itertools
from collections import Counter, deque, defaultdict
from bisect import bisect_left, bisect_right
from heapq import heappop, heappush, heapify, nlargest
from copy import deepcopy
mod = 10 ** 9 + 7
INF = float('inf')

def inp():
	return int(sys.stdin.readline())

def inpl():
	return list(map(int, sys.stdin.readline().split()))

def inpl_1():
	return list(map(lambda x: int(x) - 1, sys.stdin.readline().split()))

def inps():
	return sys.stdin.readline()

def inpsl(x):
	tmp = sys.stdin.readline()
	return list(tmp[:x])

def err(x):
	print(x)
	exit()
for _ in range(inp()):
	(n, m) = inpl()
	a = inpl()
	b = inpl()
	A = [[], []]
	B = [[], []]
	for x in a:
		if x > 0:
			A[0].append(x)
		else:
			A[1].append(-x)
	A[1] = A[1][::-1]
	for x in b:
		if x > 0:
			B[0].append(x)
		else:
			B[1].append(-x)
	B[1] = B[1][::-1]

	def sol(A, B):
		n = len(A)
		m = len(B)
		sa = set(A)
		sb = set(B)
		alrea = []
		for x in A:
			if x in sb:
				alrea.append(x)
		ln = len(alrea)
		alpa = ln
		alidx = 0 if alpa else INF
		res = alpa
		for (i, x) in enumerate(B):
			boxcnt = bisect_right(A, x)
			placecnt = i + 1 - bisect_left(B, x - boxcnt + 1)
			while alidx < ln and alrea[alidx] <= x:
				alidx += 1
				alpa -= 1
			res = max(res, alpa + placecnt)
		return res
	res = 0
	for i in range(2):
		res += sol(A[i], B[i])
	print(res)


import io
import os
from collections import Counter, defaultdict, deque
from bisect import bisect_right
DEBUG = False

def solve2(A, B):
	score = sum((int(v == 2) for v in Counter(A + B).values()))
	A = deque(A)
	push = 0
	best = score
	for (i, b) in enumerate(B):
		while A and A[0] <= b:
			if A[0] == b:
				score -= 1
			push += 1
			A.popleft()
		index = bisect_right(B, b - push)
		overlap = max(0, i - index + 1)
		best = max(best, overlap + score)
		if DEBUG:
			print('proc', b)
			print(B)
			print(A)
			print(push, (b - push, b), (overlap, score))
	if DEBUG:
		print('ans', best)
		print()
	return best

def solve(N, M, A, B):
	return solve2([a for a in A if a > 0], [b for b in B if b > 0]) + solve2([-a for a in A if a < 0][::-1], [-b for b in B if b < 0][::-1])
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
TC = int(input())
for tc in range(1, TC + 1):
	(N, M) = [int(x) for x in input().split()]
	A = [int(x) for x in input().split()]
	B = [int(x) for x in input().split()]
	ans = solve(N, M, A, B)
	print(ans)


import sys
input = sys.stdin.readline
from bisect import bisect_left, bisect_right
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	b = list(map(int, input().split()))
	a1 = []
	a2 = []
	for e in a:
		if e < 0:
			a2.append(-e)
		else:
			a1.append(e)
	b1 = []
	b2 = []
	for e in b:
		if e < 0:
			b2.append(-e)
		else:
			b1.append(e)
	result1 = 0
	result2 = 0
	for t in range(2):
		if t == 0:
			box = a1
			po = b1
		else:
			box = a2[::-1]
			po = b2[::-1]
		sp = []
		i = j = 0
		while i < len(box) and j < len(po):
			if box[i] == po[j]:
				sp.append(box[i])
				i += 1
				j += 1
			elif box[i] < po[j]:
				i += 1
			else:
				j += 1
		l = len(sp)
		result = 0
		for e in po:
			nbox = bisect_right(box, e)
			result = max(bisect_right(po, e) - bisect_left(po, e - nbox + 1) + l - bisect_right(sp, e), result)
		if t == 0:
			result1 = result
		else:
			result2 = result
	print(result1 + result2)


t = int(input())
for _ in range(t):

	def main():

		def go(box, pos):
			(neb, nep) = (0, 0)
			(nb, np) = (len(box), len(pos))
			cb = 0
			pos.append(10 ** 10)
			ready = 0
			mid = 0
			for q in range(np):
				while mid < nb and box[mid] < pos[q]:
					mid += 1
				if mid == nb:
					break
				if box[mid] == pos[q]:
					ready += 1
			ans = ready
			for q in range(np):
				while neb < nb and box[neb] <= pos[q]:
					cb += 1
					neb += 1
				if neb and pos[q] == box[neb - 1]:
					ready -= 1
				while pos[q] - cb >= pos[nep]:
					nep += 1
				ans = max(ans, q - nep + 1 + ready)
			return ans

		def find(nums):
			left = 0
			right = len(nums)
			while left < right:
				mid = (left + right) // 2
				if nums[mid] > 0:
					right = mid
				else:
					left = mid + 1
			return left
		(n, m) = map(int, input().split())
		boxes = list(map(int, input().split()))
		positions = list(map(int, input().split()))
		bz = find(boxes)
		pz = find(positions)
		b1 = []
		p1 = []
		for i in range(bz - 1, -1, -1):
			b1.append(-boxes[i])
		for i in range(pz - 1, -1, -1):
			p1.append(-positions[i])
		b2 = boxes[bz:]
		p2 = positions[pz:]
		res = go(b1, p1) + go(b2, p2)
		print(res)
	main()