// Arup Guha
// 5/2/2019
// Solution to 2019 Code Jam Round 1B Problem: Fair Fight

import java.util.*;
import java.io.*;

public class Solution {

	public static int n;
	public static int diff;
	public static int[] charles;
	public static int[] delila;
	
	public static rmq cRmq;
	public static rmq dRmq;
	
	public static void main(String[] args) throws Exception {
	
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		int nC = Integer.parseInt(stdin.readLine().trim());
		
		// Process each case.
		for (int loop=1; loop<=nC; loop++) {
		
			// Stuff takes a long time to read in, in Java...
			StringTokenizer tok = new StringTokenizer(stdin.readLine());
			n = Integer.parseInt(tok.nextToken());
			diff = Integer.parseInt(tok.nextToken());
			charles = new int[n];
			tok = new StringTokenizer(stdin.readLine());
			for (int i=0; i<n; i++)
				charles[i] = Integer.parseInt(tok.nextToken());
			delila = new int[n];
			tok = new StringTokenizer(stdin.readLine());
			for (int i=0; i<n; i++)
				delila[i] = Integer.parseInt(tok.nextToken());			
	
			// Create RMQ objects.
			cRmq = new rmq(charles);
			dRmq = new rmq(delila);
			
			// Ta da!
			System.out.println("Case #"+loop+": "+ (choose2(n+1)-solve(0, n-1)));
		}
	}
	
	// Returns the opposite for the solution (all the unfair fights) for the subsection arr[low..high].
	public static long solve(int low, int high) {
		
		// Base case size 10 to reduce recursion load.
		if (high-low < 10) {
			long res = 0;
			for (int i=low; i<=high; i++) {
				int maxC = charles[i];
				int maxD = delila[i];
				for (int j=i; j<=high; j++) {
					maxC = Math.max(maxC, charles[j]);
					maxD = Math.max(maxD, delila[j]);
					if (Math.abs(maxC-maxD) > diff) res++;
				}
			}
			return res;
		}
		
		// Get both maxes.
		int[] bestC = cRmq.getMax(low, high);
		int[] bestD = dRmq.getMax(low, high);
		
		long res = 0;
		int splitI = -1;
		
		// Case where highest sword period is charles's in range.
		if (bestC[1] > bestD[1]) {
			splitI = bestC[0];
			int target = bestC[1]-diff;
			
			// Returns indexes in opposite array on both sides of splitI with swords that are good enough.
			int getMax = dRmq.getMaxAtleast(target, low, splitI);
			int getMin = dRmq.getMinAtleast(target, splitI, high);
			
			// These are all of the ranges that are bad starting from splitI or left of it and ending at splitI or after it.
			res += ((long)(splitI-getMax))*(getMin-splitI);
		}
		
		// Delila's here.
		else {
			splitI = bestD[0];
			int target = bestD[1]-diff;
			
			// Returns indexes in opposite array on both sides of splitI with swords that are good enough.
			int getMax = cRmq.getMaxAtleast(target, low, splitI);
			int getMin = cRmq.getMinAtleast(target, splitI, high);	

			// Same count as described in the previous case.
			res += ((long)(splitI-getMax))*(getMin-splitI);		
		}
		
		// Now, we just have to add in bad fights to the left and right of the split Index.
		res += solve(low, splitI-1);
		res += solve(splitI+1, high);
		
		return res;
	}
	
	public static long choose2(int n) {
		return ((long)n)*(n-1)/2;
	}
}

class rmq {
	
	public int d;
	public int[][] vals;
	public int[][] idx;
	
	public rmq(int[] arr) {
		
		// Figure out depth of table.
		d = 0;
		while ((1 << d) < arr.length) d++;
		
		// d+1 table levels.
		vals = new int[d+1][];
		idx = new int[d+1][];
		for (int i=0; i<=d; i++) {
			vals[i] = new int[1<<i];
			idx[i] = new int[1<<i];
		}
		
		// Do bottom level.
		for (int i=0; i<arr.length; i++) {
			vals[d][i] = arr[i];
			idx[d][i] = i;
		}
		for (int i=arr.length; i<idx[d].length; i++)
			idx[d][i] = i;
		
		// Do the rest of the table. This one is for max.
		for (int level=d-1; level>=0; level--) {
			for (int i=0; i<vals[level].length; i++) {
				if (vals[level+1][2*i] > vals[level+1][2*i+1]) {
					vals[level][i] = vals[level+1][2*i];
					idx[level][i] = idx[level+1][2*i];
				}
				else {
					vals[level][i] = vals[level+1][2*i+1];
					idx[level][i] = idx[level+1][2*i+1];
				}
			}
		}
	}
	
	// Wrapper.
	public int[] getMax(int low, int high) {
		return getMax(low, high, 0, 0);
	}
	
	// Return index and value of maximum in range.
	public int[] getMax(int low, int high, int level, int myidx) {
		
		if (low > high) return null;
		
		// Range must be 1 to get here.
		if (level == d) return new int[]{idx[d][myidx], vals[d][myidx]};
		
		int myLowIdx = myidx*(1<<(d-level));
		int myHighIdx = (myidx+1)*(1<<(d-level))-1;
		
		// Exact return it.
		if (myLowIdx == low && myHighIdx == high) return new int[]{idx[level][myidx], vals[level][myidx]};
		
		// Go the level below.
		int lowmap = low/(1<<(d-level-1));
		int highmap = high/(1<<(d-level-1));
		
		// Everything fits in one child.
		if (lowmap == highmap) return getMax(low, high, level+1, lowmap);
		
		// Go both sides.
		int[] left = getMax(low, highmap*(1<<(d-level-1))-1, level+1, lowmap);
		int[] right = getMax(highmap*(1<<(d-level-1)), high, level+1, highmap);
		
		// I probably don't need this, but had a dumb bug and used this to prevent a null ptr error at the time.
		if (left == null && right == null) return null;
		else if (left == null) return right;
		else if (right == null) return left;
		
		// Just take the better of the two.
		if (left[1] > right[1]) 
			return left;
		else
			return right;
	}
	
	// Returns max index i such that rmq[i, high] >= target.
	public int getMaxAtleast(int target, int low, int high) {
		
		// Get these case out of the way.
		if (vals[d][high] >= target) return high;
		if (getMax(low,high)[1] < target) return low-1;
		
		// Binary search max index i.
		int myl = low, myh = high-1;
		while (myl < myh) {
			int mid = (myl+myh+1)/2;
			if (getMax(mid, high)[1] >= target)
				myl = mid;
			else
				myh = mid-1;
		}
		return myl;
	}
	
	// Returns min index i such that rmq[low, i] >= target.
	public int getMinAtleast(int target, int low, int high) {
		
		// Get these case out of the way.
		if (vals[d][low] >= target) return low;
		if (getMax(low,high)[1] < target) return high+1;
		
		// Binary search min index i...
		int myl = low+1, myh = high;
		while (myl < myh) {
			int mid = (myl+myh)/2;
			if (getMax(low, mid)[1] >= target)
				myh = mid;
			else
				myl = mid+1;
		}
		return myl;
	}	
	
}