import heapq import sys input = sys.stdin.buffer.read def main(): data = input().split() idx = 0 def rd(): nonlocal idx v = int(data[idx]); idx += 1 return v T = rd() out = [] for _ in range(T): N, K = rd(), rd() A = [rd() for _ in range(N)] B = [rd() for _ in range(N)] C = [rd() for _ in range(N)] D = [rd() for _ in range(N)] blocks = {} min_h = [] max_h = [] bid = 0 total = 0 profit = 0 for i in range(N): a, b, c, d = A[i], B[i], C[i], D[i] # 買いブロックを追加 blocks[bid] = b heapq.heappush(min_h, (a, bid)) heapq.heappush(max_h, (-a, bid)) total += b bid += 1 # D[i]個まで貪欲に売る sold = 0 while sold < d: while min_h and blocks.get(min_h[0][1], 0) == 0: heapq.heappop(min_h) if not min_h or min_h[0][0] >= c: break p, bk = min_h[0] take = min(blocks[bk], d - sold) profit += take * (c - p) blocks[bk] -= take total -= take sold += take # 後悔エントリー: 売った数だけ価格cで買い戻せる仮想オプション if sold > 0: blocks[bid] = sold heapq.heappush(min_h, (c, bid)) heapq.heappush(max_h, (-c, bid)) total += sold bid += 1 # K超過分: 最高値から削除 while total > K: while max_h and blocks.get(max_h[0][1], 0) == 0: heapq.heappop(max_h) if not max_h: break neg_p, bk = max_h[0] remove = min(blocks[bk], total - K) blocks[bk] -= remove total -= remove out.append(profit) sys.stdout.write('\n'.join(map(str, out)) + '\n') main()