import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class E {

	public static void main(String[] args) {
		MyScanner s = new MyScanner();
		out = new PrintWriter(new BufferedOutputStream(System.out));
		int t = s.nextInt();
		StringBuilder sb=new StringBuilder();
		while (t-- > 0) {
			int n=s.nextInt();
			int k=s.nextInt();
			int[] x=new int[n];
			int[] y=new int[n];
			TreeMap<Integer,Integer> map=new TreeMap<>();
			for(int i=0;i<n;i++) {
				x[i]=s.nextInt();
				map.put(x[i],map.getOrDefault(x[i], 0)+1);
			}
			for(int i=0;i<n;i++) {
				y[i]=s.nextInt();
			}
			int[] arr=new int[map.size()];
			int[] num=new int[map.size()];

			int idx=0;
			for(int i:map.keySet()) {

				arr[idx]=i;
				num[idx]=map.get(i);
				idx++;
			}
			int[] prevsum=new int[arr.length];
			prevsum[0]=num[0];
			for(int i=1;i<arr.length;i++) {
				prevsum[i]=prevsum[i-1]+num[i];
			}
			int[] maxleft=new int[arr.length];
			TreeMap<Integer,Integer> map2=new TreeMap<>();
			for(int i=0;i<arr.length;i++) {
				map2.put(arr[i],i);
			}
			maxleft[0]=num[0];
			for(int i=1;i<arr.length;i++) {
				maxleft[i]=num[i];
				if(map2.ceilingKey(arr[i]-k)!=null) {
					if(map2.get(map2.ceilingKey(arr[i]-k))==0)
					maxleft[i]=Math.max(maxleft[i], prevsum[i]);
					else
					maxleft[i]=Math.max(maxleft[i], prevsum[i]-prevsum[map2.get(map2.ceilingKey(arr[i]-k))-1]);
				}
				if(i>0)
				maxleft[i]=Math.max(maxleft[i],maxleft[i-1]);

			}
			int[] maxright=new int[arr.length];
			maxright[arr.length-1]=num[arr.length-1];
			for(int i=arr.length-2;i>=0;i--) {
				maxright[i]=num[i];
				if(map2.floorKey(arr[i]+k)!=null) {
					if(i==0) {
						maxright[i]=Math.max(maxright[i], prevsum[map2.get(map2.floorKey(arr[i]+k))]);
					}
					else {
						maxright[i]=Math.max(maxright[i], prevsum[map2.get(map2.floorKey(arr[i]+k))]-prevsum[i-1]);
					}
				}
				if(i<arr.length-1)
					maxright[i]=Math.max(maxright[i],maxright[i+1]);
			}
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(arr[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(num[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(maxleft[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(maxright[i]+" ");
//			}
			int max=0;
			for(int i=1;i<arr.length;i++) {
				max=Math.max(maxleft[i-1]+maxright[i],max);
			}
			sb.append(max+"\n");

		}
		out.println(sb.toString());
		out.close();

	}

	public static PrintWriter out;

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	public static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s) {
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String nextToken() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(nextToken());
		}

		long nextLong() {
			return Long.parseLong(nextToken());
		}

		double nextDouble() {
			return Double.parseDouble(nextToken());
		}

	}

}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class E {

	public static void main(String[] args) {
		MyScanner s = new MyScanner();
		out = new PrintWriter(new BufferedOutputStream(System.out));
		int t = s.nextInt();
		StringBuilder sb=new StringBuilder();
		while (t-- > 0) {
			int n=s.nextInt();
			int k=s.nextInt();
			int[] x=new int[n];
			int[] y=new int[n];
			TreeMap<Integer,Integer> map=new TreeMap<>();
			for(int i=0;i<n;i++) {
				x[i]=s.nextInt();
				map.put(x[i],map.getOrDefault(x[i], 0)+1);
			}
			for(int i=0;i<n;i++) {
				y[i]=s.nextInt();
			}
			int[] arr=new int[map.size()];
			int[] num=new int[map.size()];

			int idx=0;
			for(int i:map.keySet()) {

				arr[idx]=i;
				num[idx]=map.get(i);
				idx++;
			}
			int[] prevsum=new int[arr.length];
			prevsum[0]=num[0];
			for(int i=1;i<arr.length;i++) {
				prevsum[i]=prevsum[i-1]+num[i];
			}
			int[] maxleft=new int[arr.length];
			TreeMap<Integer,Integer> map2=new TreeMap<>();
			for(int i=0;i<arr.length;i++) {
				map2.put(arr[i],i);
			}
			maxleft[0]=num[0];
			for(int i=1;i<arr.length;i++) {
				maxleft[i]=num[i];
				if(map2.ceilingKey(arr[i]-k)!=null) {
					if(map2.get(map2.ceilingKey(arr[i]-k))==0)
					maxleft[i]=Math.max(maxleft[i], prevsum[i]);
					else
					maxleft[i]=Math.max(maxleft[i], prevsum[i]-prevsum[map2.get(map2.ceilingKey(arr[i]-k))-1]);
				}
				if(i>0)
				maxleft[i]=Math.max(maxleft[i],maxleft[i-1]);

			}
			int[] maxright=new int[arr.length];
			maxright[arr.length-1]=num[arr.length-1];
			for(int i=arr.length-2;i>=0;i--) {
				maxright[i]=num[i];
				if(map2.floorKey(arr[i]+k)!=null) {
					if(i==0) {
						maxright[i]=Math.max(maxright[i], prevsum[map2.get(map2.floorKey(arr[i]+k))]);
					}
					else {
						maxright[i]=Math.max(maxright[i], prevsum[map2.get(map2.floorKey(arr[i]+k))]-prevsum[i-1]);
					}
				}
				if(i<arr.length-1)
					maxright[i]=Math.max(maxright[i],maxright[i+1]);
			}
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(arr[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(num[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(maxleft[i]+" ");
//			}
//			System.out.println();
//			for(int i=0;i<arr.length;i++) {
//				System.out.print(maxright[i]+" ");
//			}

			int max=0;
			if(arr.length==1)
				max=maxleft[0];
			for(int i=1;i<arr.length;i++) {
				max=Math.max(maxleft[i-1]+maxright[i],max);
			}
			sb.append(max+"\n");

		}
		out.println(sb.toString());
		out.close();

	}

	public static PrintWriter out;

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	public static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s) {
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String nextToken() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(nextToken());
		}

		long nextLong() {
			return Long.parseLong(nextToken());
		}

		double nextDouble() {
			return Double.parseDouble(nextToken());
		}

	}

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ETwoPlatforms solver = new ETwoPlatforms();
        solver.solve(1, in, out);
        out.close();
    }

    static class ETwoPlatforms {
        int n;
        int k;
        Integer[] arr;
        Integer[] secondArr;
        int s;
        int e;

        public void solve(int testNumber, Scanner sc, PrintWriter pw) {
            int q = sc.nextInt();
            while (q-- > 0) {
                n = sc.nextInt();
                k = sc.nextInt();
                arr = new Integer[n];
                for (int i = 0; i < n; i++)
                    arr[i] = sc.nextInt();
                for (int i = 0; i < n; i++)
                    sc.nextInt();
                Arrays.sort(arr);
                int low = 1, high = n;
                int ans = 0;
                while (low <= high) {
                    int mid = (low + high) / 2;
                    if (valid(mid, arr, k)) {
                        low = mid + 1;
                        ans = mid;
                    } else
                        high = mid - 1;
                }
                low = 1;
                high = n;
                int ans3 = 0;
                while (low <= high) {
                    int mid = (low + high) / 2;
                    if (valid(mid, arr, 2 * k)) {
                        low = mid + 1;
                        ans3 = mid;
                    } else
                        high = mid - 1;
                }
                valid(ans, arr, k);
                secondArr = new Integer[n - (e - s + 1)];
                int idx = 0;
                for (int i = 0; i < n; i++) {
                    if (i < s || i > e)
                        secondArr[idx++] = arr[i];
                }
                low = 1;
                high = secondArr.length;
                int ans2 = 0;
                while (low <= high) {
                    int mid = (low + high) / 2;
                    if (valid(mid, secondArr, k)) {
                        low = mid + 1;
                        ans2 = mid;
                    } else
                        high = mid - 1;
                }
                pw.println(Math.max(ans + ans2, ans3));
            }
        }

        private boolean valid(int mid, Integer[] arr, int k) {
            for (int i = mid - 1; i < arr.length; i++) {
                if (arr[i].intValue() - arr[i - mid + 1].intValue() <= k) {
                    s = i - mid + 1;
                    e = i;
                    return true;
                }
            }
            return false;
        }

    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ETwoPlatforms solver = new ETwoPlatforms();
        solver.solve(1, in, out);
        out.close();
    }

    static class ETwoPlatforms {
        int n;
        int k;
        Integer[] arr;

        public void solve(int testNumber, Scanner sc, PrintWriter pw) {
            int q = sc.nextInt();
            while (q-- > 0) {
                n = sc.nextInt();
                k = sc.nextInt();
                arr = new Integer[n];
                for (int i = 0; i < n; i++)
                    arr[i] = sc.nextInt();
                for (int i = 0; i < n; i++)
                    sc.nextInt();
                Arrays.sort(arr);
                int l = 0, idx = 0;
                int[] prefix = new int[n];
                while (idx < n) {
                    while (l < idx && arr[idx] - arr[l] > k)
                        l++;
                    prefix[idx] = idx - l + 1;
                    idx++;
                }
                int r = n - 1;
                idx = n - 1;
                int[] suffix = new int[n];
                while (idx >= 0) {
                    while (r > idx && arr[r] - arr[idx] > k)
                        r--;
                    suffix[idx] = r - idx + 1;
                    idx--;
                }
                for (int i = 1; i < n; i++) {
                    prefix[i] = Math.max(prefix[i], prefix[i - 1]);
                }
                for (int i = n - 2; i >= 0; i--) {
                    suffix[i] = Math.max(suffix[i], suffix[i + 1]);
                }
                int max = 1;
                for (int i = 0; i < n - 1; i++)
                    max = Math.max(max, prefix[i] + suffix[i + 1]);
                pw.println(max);
            }
        }

    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.PrintWriter;
import java.util.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);

        int t=sc.nextInt();
        while(t-->0){
            int n=sc.nextInt();
            int k=sc.nextInt();
            int x[]=new int[n];
            HashMap<Integer,Integer> hm=new HashMap<>();
            for(int i=0;i<n;i++){
                x[i]=sc.nextInt();
                hm.put(x[i],hm.getOrDefault(x[i],0)+1);
            }
            for(int i=0;i<n;i++){
                sc.nextInt();
            }
            ArrayList<Node> l=new ArrayList<>();
            for(int key:hm.keySet()){
                l.add(new Node(key,hm.get(key)));
            }
            Collections.sort(l, new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    return Integer.compare(o1.x,o2.x);
                }
            });
//            for(Node xx:l){
//                System.out.println(xx.x+" "+xx.fre);
//            }
            long dp[]=new long[l.size()];
            long sum=0;
            for(int i=0;i<l.size();i++){
                sum+=l.get(i).fre;
                dp[i]=sum;
            }
            long max=0;
            TreeMap<Integer,Integer> tm=new TreeMap<>();
            for(int i=0;i<l.size();i++){
                tm.put(l.get(i).x,i);
            }
            long pre[]=new long[l.size()];
            for(int i=0;i<l.size();i++){
                Integer pk=tm.floorKey(l.get(i).x+k+1);
                if(pk==null){
                    pre[i]=dp[i]-(i>0?dp[i-1]:0);
                }
                else{
                    pre[i]=dp[tm.get(pk)]-(i>0?dp[i-1]:0);
                }
                if(i+1<l.size()){
                    pre[i]=Math.max(pre[i],pre[i+1]);
                }
            }
            for(int i=0;i<l.size();i++){
                Integer pk=tm.floorKey(l.get(i).x+k);
                long range=dp[tm.get(pk)]-(i>0?dp[i-1]:0);
                pk=tm.ceilingKey(pk+1);
                if(pk!=null){
                    range+=pre[tm.get(pk)];
                }
                max=Math.max(max,range);
            }
            System.out.println(max);
        }

        out.close();
    }

    static class Node{
        int x,fre;
        Node(int x,int fre){
            this.x=x;
            this.fre=fre;
        }
    }

}


import java.io.PrintWriter;
import java.util.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);

        int t=sc.nextInt();
        while(t-->0){
            int n=sc.nextInt();
            int k=sc.nextInt();
            int x[]=new int[n];
            HashMap<Integer,Integer> hm=new HashMap<>();
            for(int i=0;i<n;i++){
                x[i]=sc.nextInt();
                hm.put(x[i],hm.getOrDefault(x[i],0)+1);
            }
            for(int i=0;i<n;i++){
                sc.nextInt();
            }
            ArrayList<Node> l=new ArrayList<>();
            for(int key:hm.keySet()){
                l.add(new Node(key,hm.get(key)));
            }
            Collections.sort(l, new Comparator<Node>() {
                @Override
                public int compare(Node o1, Node o2) {
                    return Integer.compare(o1.x,o2.x);
                }
            });
//            for(Node xx:l){
//                System.out.println(xx.x+" "+xx.fre);
//            }
            long dp[]=new long[l.size()];
            long sum=0;
            for(int i=0;i<l.size();i++){
                sum+=l.get(i).fre;
                dp[i]=sum;
            }
            long max=0;
            TreeMap<Integer,Integer> tm=new TreeMap<>();
            for(int i=0;i<l.size();i++){
                tm.put(l.get(i).x,i);
            }
            long pre[]=new long[l.size()];
            for(int i=0;i<l.size();i++){
                Integer pk=tm.floorKey(l.get(i).x+k);
                if(pk==null){
                    pre[i]=dp[i]-(i>0?dp[i-1]:0);
                }
                else{
                    pre[i]=dp[tm.get(pk)]-(i>0?dp[i-1]:0);
                }

            }
            for(int i=l.size()-2;i>=0;i--){
                pre[i]=Math.max(pre[i],pre[i+1]);
            }
            for(int i=0;i<l.size();i++){
                Integer pk=tm.floorKey(l.get(i).x+k);
                long range=dp[tm.get(pk)]-(i>0?dp[i-1]:0);
                pk=tm.ceilingKey(pk+1);
                if(pk!=null){
                    range+=pre[tm.get(pk)];
                }
                max=Math.max(max,range);
            }
            System.out.println(max);
        }

        out.close();
    }

    static class Node{
        int x,fre;
        Node(int x,int fre){
            this.x=x;
            this.fre=fre;
        }
    }

}


import java.io.*;
import java.util.*;
public class Main {
	static BufferedReader br;
	static PrintWriter pr;
	static int cin() throws Exception
	{
		return Integer.valueOf(br.readLine());
	}
	static int[] split() throws Exception
	{
		String[] cmd=br.readLine().split(" ");
		int[] ans=new int[cmd.length];
		for(int i=0;i<cmd.length;i++)
		{
			ans[i]=Integer.valueOf(cmd[i]);
		}
		return ans;
	}
	static long[] splitL() throws IOException
	{
		String[] cmd=br.readLine().split(" ");
		long[] ans=new long[cmd.length];
		for(int i=0;i<cmd.length;i++)
		{
			ans[i]=Long.valueOf(cmd[i]);
		}
		return ans;
	}
	static int sum(long n)
	{
		int ans=0;
		while(n!=0)
		{
			ans=ans+(int)(n%10);
			n=n/10;
		}
		return ans;
	}
	static int gcd(int x,int y)
	{
		if(x==0)
			return y;
		if(y==0)
			return x;
		if(x>y)
			return gcd(x%y,y);
		else
			return gcd(x,y%x);
	}
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		br=new BufferedReader(new InputStreamReader(System.in));
		pr=new PrintWriter(new OutputStreamWriter(System.out));
		int cases=cin();
		while(cases!=0)
		{
			cases--;
			int[]ar=split();
			int n=ar[0];
			int k=ar[1];
			int[]x=split();
			int[]y=split();
			ArrayList<Integer> cor=new ArrayList<>();
			HashMap<Integer,Integer> cnt=new HashMap<>();
			HashMap<Integer,Integer> index=new HashMap<>();
			for(int i=0;i<n;i++)
			{
				if(cnt.containsKey(x[i]))
					cnt.put(x[i], cnt.get(x[i])+1);
				else
				{
					cor.add(x[i]);
					cnt.put(x[i],1);
				}
			}
			Collections.sort(cor);
			int[] sum=new int[cor.size()];
			sum[0]=cnt.get(cor.get(0));
			index.put(cor.get(0),0);
			for(int i=1;i<cor.size();i++)
			{
				sum[i]=sum[i-1]+cnt.get(cor.get(i));
				index.put(cor.get(i), i);
			}
			int[] max1=new int[cor.size()];
			int[] max2=new int[cor.size()];
			TreeSet<Integer> tr=new TreeSet<>();
			tr.add(cor.get(0));
			max1[0]=cnt.get(cor.get(0));
			for(int i=1;i<cor.size();i++)
			{
				int a=cor.get(i);
				if(tr.ceiling(a-k)==null)
				{
					max1[i]=Math.max(max1[i-1],cnt.get(cor.get(i)));
					tr.add(cor.get(i));
					continue;
				}
				int b=tr.ceiling(a-k);
				int ind=index.get(b);
				int su=sum[i];
				if(ind!=0)
					su-=sum[ind-1];
				max1[i]=Math.max(max1[i-1],su);
				tr.add(cor.get(i));
			}
			tr=new TreeSet<>();
			tr.add(cor.get(cor.size()-1));
			max2[cor.size()-1]=cnt.get(cor.get(cor.size()-1));
			for(int i=cor.size()-2;i>=0;i--)
			{
				int a=cor.get(i);
				if(tr.floor(a+k)==null)
				{
					max2[i]=Math.max(max2[i+1],cnt.get(cor.get(i)));
					tr.add(cor.get(i));
					continue;
				}
				int b=tr.floor(a+k);
				int ind=index.get(b);
				int su=sum[ind];
				if(i!=0)
					su-=sum[i-1];
				max2[i]=Math.max(max2[i+1],su);
				tr.add(cor.get(i));
			}
			int ans=0;
			for(int i=0;i<cor.size();i++)
			{
				int f=0;
				if(i!=cor.size()-1)
					f=max2[i+1];
				ans=Math.max(ans, max1[i]+f);
			}
			System.out.println(ans);
		}
	}
}


import static java.lang.Math.max;

import java.io.ByteArrayInputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class E {

	public static void main(String[] args) throws Exception {
		new E().go();
	}
	static boolean LOCAL = System.getProperty("ONLINE_JUDGE") == null;

	Scanner in;
	String INPUT = "5\r\n" +
			"7 1\r\n" +
			"1 5 2 3 1 5 4\r\n" +
			"1 3 6 7 2 5 4\r\n" +
			"1 1\r\n" +
			"1000000000\r\n" +
			"1000000000\r\n" +
			"5 10\r\n" +
			"10 7 5 15 8\r\n" +
			"20 199 192 219 1904\r\n" +
			"9 3                        \r\n" +
			"2 4 4 6 7 8 13 14 14       \r\n" +
			"1 1 1 1 1 1  1  1  1       \r\n" +
			"10 10\r\n" +
			"15 19 8 17 20 10 9 2 10 19\r\n" +
			"12 13 6 17 1 14 7 9 19 3";

	void go() {
		if (LOCAL) {
			System.setIn(new ByteArrayInputStream(INPUT.getBytes()));
		}
		in = new Scanner(System.in);
		long startTime = System.currentTimeMillis();
		solve();
		if (LOCAL) {
			System.out.printf("[%dms]", System.currentTimeMillis()-startTime);
		}
		in.close();
	}

	PrintWriter out = new PrintWriter(System.out);
	StringBuffer sb = new StringBuffer();

	void solve() {
		int t = in.nextInt();
		for (int i=1; i<=t; i++) {
			solve2(i);
		}
		out.flush();

	} // end of solve

	void solve2(int caseNr) {
		int n = in.nextInt();
		int k = in.nextInt();

		int[] x = new int[n];
		int[] y = new int[n];

		for (int i=0; i<n; i++) {
			x[i] = in.nextInt();
		}
		for (int i=0; i<n; i++) {
			y[i] = in.nextInt();
		}

		//		if (caseNr != 1) return;

		if (x.length == 1) {
			out.println(1);
			return;
		}

		List<Integer> x_sorted = new ArrayList<>();
		for (int i=0; i<n; i++) {
			x_sorted.add(x[i]);
		}
		Collections.sort(x_sorted);
		for (int i=0; i<n; i++) {
			x[i] = x_sorted.get(i);
		}

		int[] right = new int[n];
		int p = 0;
		for (int i = 0; i < n; i++) {
			while (p+1 < n && x[p+1] <= x[i]+k) {
				p++;
			}
			right[i] = p-i+1;
		}

		int[] left = new int[n];
		p = n-1;
		for (int i = n-1; i >= 0; i--) {
			while(p-1 >= 0 && x[i] <= x[p-1]+k) {
				p--;
			}
			left[i] = i-p+1;
		}

		int[] best_right = new int[n];
		best_right[n-1] = right[n-1];
		for (int i = n-2; i >= 0; i--) {
			best_right[i] = max(right[i], best_right[i+1]);
		}

		int[] best_left = new int[n];
		best_left[0] = left[0];
		for (int i = 1; i < n; i++) {
			best_left[i] = max(left[i], best_left[i-1]);
		}

		int ans = 0;
		for (int i = 0; i < n-1; i++) {
			ans = max(ans, best_left[i]+best_right[i+1]);
		}

		out.println(ans);

		return;
	} // end of solve2

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.SplittableRandom;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn Agrawal (coderbond007)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ETwoPlatforms solver = new ETwoPlatforms();
        int testCount = Integer.parseInt(in.next());
        for (int i = 1; i <= testCount; i++)
            solver.solve(i, in, out);
        out.close();
    }

    static class ETwoPlatforms {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            long K = in.nextInt();
            long[] x = in.nextLongArray(n);
            long[] y = in.nextLongArray(n);
            ArrayUtils.sort(x);
            long[] dp1 = calculate(x, y, K);
            ArrayUtils.reverseArray(x);
            long[] dp2 = calculate(x, y, K);
            ArrayUtils.reverseArray(dp2);
            long max = 0;
            for (int i = -1; i < n; ++i) {
                int cur = 0;
                if (i >= 0) cur += dp1[i];
                if (i + 1 < n) cur += dp2[i + 1];
                if (cur > max) max = cur;
            }
            out.println(max);
        }

        private long[] calculate(long[] x, long[] y, long K) {
            int n = x.length;
            long[] dp = new long[n];
            int ptr = 0;
            int cur = 0;
            for (int i = 0; i < n; ++i) {
                ++cur;
                while (Math.abs(x[i] - x[ptr]) > K) {
                    ++ptr;
                    --cur;
                }
                dp[i] = cur;
                if (i != 0) dp[i] = Math.max(dp[i], dp[i - 1]);
            }
            return dp;
        }

    }

    static class ArrayUtils {
        public static long[] sort(long[] a) {
            a = shuffle(a, new SplittableRandom());
            Arrays.sort(a);
            return a;
        }

        public static long[] shuffle(long[] a, SplittableRandom gen) {
            for (int i = 0, n = a.length; i < n; i++) {
                int ind = gen.nextInt(n - i) + i;
                long d = a[i];
                a[i] = a[ind];
                a[ind] = d;
            }
            return a;
        }

        public static long[] reverseArray(long... a) {
            for (int i = 0, j = a.length - 1; i < j; i++, j--) {
                long d = a[i];
                a[i] = a[j];
                a[j] = d;
            }
            return a;
        }

    }

    static class FastScanner {
        BufferedReader reader;
        StringTokenizer tokenizer;

        public FastScanner(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public long[] nextLongArray(int n) {
            long[] arr = new long[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLong();
            }
            return arr;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.SplittableRandom;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pradyumn Agrawal (coderbond007)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ETwoPlatforms solver = new ETwoPlatforms();
        int testCount = Integer.parseInt(in.next());
        for (int i = 1; i <= testCount; i++)
            solver.solve(i, in, out);
        out.close();
    }

    static class ETwoPlatforms {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            Debug debug = new Debug(out);
            int n = in.nextInt();
            int K = in.nextInt();
            int[] x = in.nextIntArray(n);
            int[] y = in.nextIntArray(n);
            ArrayUtils.sort(x);
            int[] dp1 = calculate(x, y, K);
            ArrayUtils.reverseArray(x);
            int[] dp2 = calculate(x, y, K);
            ArrayUtils.reverseArray(dp2);
            int max = 0;
            for (int i = -1; i < n; ++i) {
                max = Math.max(max, (i >= 0 ? dp1[i] : 0) + (i + 1 < n ? dp2[i + 1] : 0));
            }
            out.println(max);
        }

        private int[] calculate(int[] x, int[] y, int K) {
            int n = x.length;
            int[] dp = new int[n];
            int ptr = 0;
            int cur = 0;
            for (int i = 0; i < n; ++i) {
                ++cur;
                while (Math.abs(x[i] - x[ptr]) > K) {
                    ++ptr;
                    --cur;
                }
                dp[i] = cur;
            }
            for (int i = 1; i < n; ++i) {
                dp[i] = Math.max(dp[i], dp[i - 1]);
            }
            return dp;
        }

    }

    static class ArrayUtils {
        public static int[] sort(int[] a) {
            a = shuffle(a, new SplittableRandom());
            Arrays.sort(a);
            return a;
        }

        public static int[] shuffle(int[] a, SplittableRandom gen) {
            for (int i = 0, n = a.length; i < n; i++) {
                int ind = gen.nextInt(n - i) + i;
                int d = a[i];
                a[i] = a[ind];
                a[ind] = d;
            }
            return a;
        }

        public static int[] reverseArray(int... a) {
            for (int i = 0, j = a.length - 1; i < j; i++, j--) {
                int d = a[i];
                a[i] = a[j];
                a[j] = d;
            }
            return a;
        }

    }

    static class Debug {
        PrintWriter out;
        boolean oj;
        long timeBegin;
        Runtime runtime;

        public Debug(PrintWriter out) {
            oj = System.getProperty("ONLINE_JUDGE") != null;
            this.out = out;
            this.timeBegin = System.currentTimeMillis();
            this.runtime = Runtime.getRuntime();
        }

        public Debug() {
            oj = System.getProperty("ONLINE_JUDGE") != null;
            OutputStream outputStream = System.err;
            this.out = new PrintWriter(outputStream);
            this.timeBegin = System.currentTimeMillis();
            this.runtime = Runtime.getRuntime();
        }

        public void finalize() {
            out.flush();
            out.close();
        }

    }

    static class FastScanner {
        BufferedReader reader;
        StringTokenizer tokenizer;

        public FastScanner(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public int[] nextIntArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }
            return arr;
        }

    }
}


// package Div3__667;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeMap;

public class ProblemE {
    static class Reader
    {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do
            {
                ret = ret * 10 + c - '0';
            }  while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.')
            {
                while ((c = read()) >= '0' && c <= '9')
                {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }
    public static void main(String[] args)throws IOException {
        Reader s=new Reader();
        int test=s.nextInt();
        StringBuilder print=new StringBuilder();
        int lim=Integer.MAX_VALUE;
        while(test--!=0){
            int n=s.nextInt();
            int k=s.nextInt();
            ArrayList<Integer> x=new ArrayList<>();
            ArrayList<Integer> y=new ArrayList<>();
            for(int i=0;i<n;i++){
                x.add(s.nextInt());
            }
            for(int i=0;i<n;i++){
                y.add(s.nextInt());
            }
            Collections.sort(x);
            TreeMap<Integer,Integer> start=new TreeMap<>();
            TreeMap<Integer,Integer> end=new TreeMap<>();
            start.put(lim,n);
            end.put(lim,n);
            for(int i=0;i<n;i++){
                int xc=x.get(i);
                if(start.containsKey(xc)){
                    end.put(xc,i);
                }
                else{
                    start.put(xc,i);
                    end.put(xc,i);
                }
            }
            int max=0;
            int dp[]=new int[n+1];
            dp[n-1]=1;
            for(int i=n-2;i>=0;i--){
                dp[i]=Math.max(dp[i],dp[i+1]);
                int currx=x.get(i);
                int xend=currx+k;
                int j=start.higherKey(xend);
                j=start.get(j);
                dp[i]=Math.max(dp[i],j-i);
            }
            for(int i=0;i<n;i++){
                int currx=x.get(i);
                int xend=currx+k;
                int j=start.higherKey(xend);
                j=start.get(j);
                int temp=j-i+dp[j];
                max=Math.max(max,temp);
            }
            print.append(max).append("\n");
        }
        System.out.print(print.toString());
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class E {

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader file = new BufferedReader(new InputStreamReader(System.in));
		int inputs = Integer.parseInt(file.readLine());
		while(inputs-->0) {
			StringTokenizer st = new StringTokenizer(file.readLine());
			int n = Integer.parseInt(st.nextToken());
			int k = Integer.parseInt(st.nextToken());
			st = new StringTokenizer(file.readLine());
			Integer[] points = new Integer[n];
			for(int i = 0; i < n; i++) {
				points[i] = Integer.parseInt(st.nextToken());
			}
			Arrays.sort(points);
			file.readLine();
			int[] best = new int[n+1];
			int currLen = 0;
			int curr = 1;
			best[1] = 1;
			for(int i = 1; i < n; i++) {
				currLen += points[i]-points[i-1];
				curr++;
				while(currLen > k) {
					currLen -= points[i-curr+2]-points[i-curr+1];
					curr--;
				}
				best[i+1] = Math.max(best[i], curr);
			}
			int[] best2 = new int[n+1];
			best2[n-1] = 1;
			currLen = 0;
			curr = 1;
			for(int i = n-2; i >= 0; i--) {
				currLen += points[i+1]-points[i];
				curr++;
				while(currLen > k) {
					currLen -= points[i+curr-1]-points[i+curr-2];
					curr--;
				}
				best2[i] = Math.max(best2[i+1], curr);
			}
//			System.out.println(Arrays.toString(best));
//			System.out.println(Arrays.toString(best2));
			int ans = 0;
			for(int i = 0; i <= n; i++) {
				ans = Math.max(ans, best[i]+best2[i]);
			}
			System.out.println(ans);
		}

	}

}


import java.io.*;
import java.util.*;

public class Solution {

    private static boolean useInFile = false;
    private static boolean useOutFile = false;

    public static void main(String args[]) throws IOException {
        InOut inout = new InOut();
        Resolver resolver = new Resolver(inout);
        resolver.solve();
        inout.flush();
    }

    private static class Resolver {

        final long LONG_INF = (long) 1e18;
        final int INF = (int) (1e9 + 7);
        final int MOD = 998244353;
        long f[], inv[];
        InOut inout;

        Resolver(InOut inout) {
            this.inout = inout;
        }

        void initF(int n, int mod) {
            f = new long[n + 1];
            f[1] = 1;
            for (int i = 2; i <= n; i++) {
                f[i] = (f[i - 1] * i) % mod;
            }
        }

        void initInv(int n, int mod) {
            inv = new long[n + 1];
            inv[n] = pow(f[n], INF - 2, INF);
            for (int i = inv.length - 2; i >= 0; i--) {
                inv[i] = inv[i + 1] * (i + 1) % mod;
            }
        }

        long cmn(int n, int m, int mod) {
            return f[n] * inv[m] % mod * inv[n - m] % mod;
        }

        int d[] = {0, -1, 0, 1, 0};

        boolean legal(int r, int c, int n, int m) {
            return r >= 0 && r < n && c >= 0 && c < m;
        }

        void solve() throws IOException {
            int tt = 1;
            boolean hvt = true;
            if (hvt) {
                tt = nextInt();
//                tt = Integer.parseInt(nextLine());
            }
            for (int cs = 1; cs <= tt; cs++) {
                long rs = 0;
                int n = nextInt();
                int len = nextInt();
                int x[] = anInt(0, n - 1);
                int y[] = anInt(0, n - 1);

                Map<Integer, Integer> cnt = new HashMap<>();
                x = unique(x, new HashMap<>(), cnt);
                n = x.length;
                long sum[] = new long[n];
                for (int i = 0; i < n; i++) {
                    sum[i] = cnt.get(i);
                    if (i > 0) {
                        sum[i] += sum[i - 1];
                    }
                }
                long dp[] = new long[n];
                dp[0] = sum[0];
                int[] finalX = x;
                int lft[] = new int[n];
                for (int i = 1; i < n; i++) {
                    final int r = i;
                    int l = (int) BinSearch.bs(0, i, new BinSearch.IBinSearch() {
                        @Override
                        public boolean binSearchCmp(long k) throws IOException {
                            return finalX[r] - finalX[(int) k] > len;
                        }
                    });
                    dp[i] = sum[r] - (l == 0 ? 0 : sum[l - 1]);
                    lft[i] = l;
                }

                for (int i = 0; i < n; i++) {
                    int l = lft[i];
                    rs = Math.max(rs, dp[i] + (l == 0 ? 0 : dp[l - 1]));
                    if (i > 0) {
                        dp[i] = Math.max(dp[i], dp[i - 1]);
                    }
                }

                format("%d", rs);
//                format("Case #%d: %d", cs, rs);

                if (cs < tt) {
                    format("\n");
                }
//                flush();
            }
        }

        private void updateSegTree(int n, long l, SegmentTree lft) {
            long lazy;
            lazy = 1;
            for (int j = 1; j <= l; j++) {
                lazy = (lazy + cmn((int) l, j, INF)) % INF;
                lft.modify(1, j, j, lazy);
            }
            lft.modify(1, (int) (l + 1), n, lazy);
        }

        String next() throws IOException {
            return inout.next();
        }

        String next(int n) throws IOException {
            return inout.next(n);
        }

        String nextLine() throws IOException {
            return inout.nextLine();
        }

        int nextInt() throws IOException {
            return inout.nextInt();
        }

        long nextLong(int n) throws IOException {
            return inout.nextLong(n);
        }

        int[] anInt(int i, int j) throws IOException {
            int a[] = new int[j + 1];
            for (int k = i; k <= j; k++) {
                a[k] = nextInt();
            }
            return a;
        }

        long[] anLong(int i, int j, int len) throws IOException {
            long a[] = new long[j + 1];
            for (int k = i; k <= j; k++) {
                a[k] = nextLong(len);
            }
            return a;
        }

        void print(String s, boolean nextLine) {
            inout.print(s, nextLine);
        }

        void format(String format, Object... obj) {
            inout.format(format, obj);
        }

        void flush() {
            inout.flush();
        }

        void swap(long a[], int i, int j) {
            a[i] ^= a[j];
            a[j] ^= a[i];
            a[i] ^= a[j];
        }

        int getP(int x, int p[]) {
            if (p[x] == 0 || p[x] == x) {
                return x;
            }
            return p[x] = getP(p[x], p);
        }

        void union(int x, int y, int p[]) {
            if (x < y) {
                p[y] = x;
            } else {
                p[x] = y;
            }
        }

        boolean topSort() {
            int n = adj2.length - 1;
            int d[] = new int[n + 1];
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j < adj2[i].size(); j++) {
                    d[adj2[i].get(j)[0]]++;
                }
            }
            List<Integer> list = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
                if (d[i] == 0) {
                    list.add(i);
                }
            }
            for (int i = 0; i < list.size(); i++) {
                for (int j = 0; j < adj2[list.get(i)].size(); j++) {
                    int t = adj2[list.get(i)].get(j)[0];
                    d[t]--;
                    if (d[t] == 0) {
                        list.add(t);
                    }
                }
            }
            return list.size() == n;
        }

        class SegmentTreeNode {
            long defaultVal = 0;
            int l, r;
            long val = defaultVal, lazy = defaultVal;

            SegmentTreeNode(int l, int r) {
                this.l = l;
                this.r = r;
            }
        }

        class SegmentTree {
            SegmentTreeNode tree[];
            long defaultVal = 0;
            long inf = Long.MIN_VALUE;
            long mod = INF;
            int type = 0;
            int MODIFY_VAL = 1;
            int MODIFY_LAZY = 2;
            int MODIFY_ALL = 3;

            SegmentTree(int n) {
                this(n, 0);
            }

            SegmentTree(int n, int type) {
                this.type = type;
                assert n > 0;
                tree = new SegmentTreeNode[n << 2];
            }

            SegmentTree build(int k, int l, int r) {
                if (l > r) {
                    return this;
                }
                if (null == tree[k]) {
                    tree[k] = new SegmentTreeNode(l, r);
                }
                if (l == r) {
                    return this;
                }
                int mid = (l + r) >> 1;
                build(k << 1, l, mid);
                build(k << 1 | 1, mid + 1, r);
                return this;
            }

            void pushDown(int k) {
                if (tree[k].l == tree[k].r) {
                    return;
                }
                long lazy = tree[k].lazy;
                modify(tree[k << 1], MODIFY_ALL, lazy);
                modify(tree[k << 1 | 1], MODIFY_ALL, lazy);
                tree[k].lazy = defaultVal;
            }

            void modify(int k, int l, int r, long val) {
                if (l > r) {
                    return;
                }
                if (tree[k].l >= l && tree[k].r <= r) {
                    modify(tree[k], MODIFY_ALL, val);
                    return;
                }
                int mid = (tree[k].l + tree[k].r) >> 1;
                if (mid >= l) {
                    modify(k << 1, l, r, val);
                }
                if (mid + 1 <= r) {
                    modify(k << 1 | 1, l, r, val);
                }
                tree[k].val = Math.max(tree[k << 1].val, tree[k << 1 | 1].val);
            }

            long query(int k, int l, int r) {
                if (tree[k].l > r || tree[k].r < l) {
                    return inf;
                }
                if (tree[k].lazy != defaultVal) {
                    pushDown(k);
                }
                if (tree[k].l >= l && tree[k].r <= r) {
                    return tree[k].val;
                }
                long ans = Math.max(query(k << 1, l, r), query(k << 1 | 1, l, r));
                if (tree[k].l < tree[k].r) {
                    tree[k].val = Math.max(tree[k << 1].val, tree[k << 1 | 1].val);
                }
                return ans;
            }

            private void modify(SegmentTreeNode node, int x, long val) {
                switch (type) {
                    case 0:
                        if (x == MODIFY_VAL) {
                            node.val += val;
                        } else if (x == MODIFY_LAZY) {
                            node.lazy += val;
                        } else {
                            node.val += val;
                            node.lazy += val;
                        }
                        break;
                    case 1:
                        if (x == MODIFY_VAL) {
                            node.val = node.val * val % mod;
                        } else if (x == MODIFY_LAZY) {
                            node.lazy = node.lazy * val % mod;
                        } else {
                            node.val = node.val * val % mod;
                            node.lazy = node.lazy * val % mod;
                        }
                        break;
                }
            }
        }

        class BinaryIndexedTree {

            int n = 1;
            long C[];

            BinaryIndexedTree(int sz) {
                while (n <= sz) {
                    n <<= 1;
                }
                C = new long[n];
            }

            int lowbit(int x) {
                return x & -x;
            }

            void add(int x, long val) {
                while (x < n) {
                    C[x] += val;
                    x += lowbit(x);
                }
            }

            long getSum(int x) {
                long res = 0;
                while (x > 0) {
                    res += C[x];
                    x -= lowbit(x);
                }
                return res;
            }

            int binSearch(long sum) {
                if (sum == 0) {
                    return 0;
                }
                int n = C.length;
                int mx = 1;
                while (mx < n) {
                    mx <<= 1;
                }
                int res = 0;
                for (int i = mx / 2; i >= 1; i >>= 1) {
                    if (C[res + i] < sum) {
                        sum -= C[res + i];
                        res += i;
                    }
                }
                return res + 1;
            }
        }

        int mnS;
        int mxS;
        Map<Integer, TrieNode> SS = new HashMap<>();
        class TrieNode {
            int cnt = 0;
            boolean isMin = false;
            boolean isMax = false;
            int mnIdx = 26;
            int mxIdx = -1;

            TrieNode next[];

            TrieNode() {
                next = new TrieNode[26];
            }

            private void insert(TrieNode trie, char ch[], int i, int j) {
                while (i < ch.length) {
                    int idx = ch[i] - 'a';
                    if (null == trie.next[idx]) {
                        trie.next[idx] = new TrieNode();
                    }
                    trie.cnt++;
                    int lastMnIdx = trie.mnIdx;
                    int lastMxIdx = trie.mxIdx;
                    trie.mnIdx = Math.min(trie.mnIdx, idx);
                    trie.mxIdx = Math.max(trie.mxIdx, idx);
                    if (trie.isMin && lastMnIdx != trie.mnIdx) {
                        if (lastMnIdx != 26) {
                            notMin(trie.next[lastMnIdx]);
                        }
                        trie.next[trie.mnIdx].isMin = true;
                    }
                    if (trie.isMax && lastMxIdx != trie.mxIdx) {
                        if (lastMxIdx >= 0) {
                            notMax(trie.next[lastMxIdx]);
                        }
                        trie.next[trie.mxIdx].isMax = true;
                    }
                    trie = trie.next[idx];
                    i++;
                }
                SS.put(j + 1, trie);
                if (trie.cnt == 0) {
                    if (trie.isMin) {
                        mnS = j + 1;
                    }
                    if (trie.isMax) {
                        mxS = j + 1;
                    }
                }
            }

            private void notMin(TrieNode trie) {
                while (null != trie) {
                    trie.isMin = false;
                    int val = trie.mnIdx;
                    if (val >= 26 || val < 0 || null == trie.next[val]) {
                        break;
                    }
                    trie = trie.next[val];
                }
            }

            private void notMax(TrieNode trie) {
                while (null != trie) {
                    trie.isMax = false;
                    int val = trie.mxIdx;
                    if (val >= 26 || val < 0 || null == trie.next[val]) {
                        break;
                    }
                    trie = trie.next[val];
                }
            }
        }

        //Binary tree
        class TreeNode {
            int val;
            int tier = -1;
            TreeNode parent;
            TreeNode left;
            TreeNode right;

            TreeNode(int val) {
                this.val = val;
            }
        }

        //binary tree dfs
        void tierTree(TreeNode root) {
            if (null == root) {
                return;
            }
            if (null != root.parent) {
                root.tier = root.parent.tier + 1;
            } else {
                root.tier = 0;
            }
            tierTree(root.left);
            tierTree(root.right);
        }

        //LCA start
        TreeNode[][] lca;
        TreeNode[] tree;

        void lcaDfsTree(TreeNode root) {
            if (null == root) {
                return;
            }
            tree[root.val] = root;
            TreeNode nxt = root.parent;
            int idx = 0;
            while (null != nxt) {
                lca[root.val][idx] = nxt;
                nxt = lca[nxt.val][idx];
                idx++;
            }
            lcaDfsTree(root.left);
            lcaDfsTree(root.right);
        }

        TreeNode lcaTree(TreeNode root, int n, TreeNode x, TreeNode y) throws IOException {
            if (null == root) {
                return null;
            }
            if (-1 == root.tier) {
                tree = new TreeNode[n + 1];
                tierTree(root);
            }
            if (null == lca) {
                lca = new TreeNode[n + 1][31];
                lcaDfsTree(root);
            }
            int z = Math.abs(x.tier - y.tier);
            int xx = x.tier > y.tier ? x.val : y.val;
            while (z > 0) {
                final int zz = z;
                int l = (int) BinSearch.bs(0, 31
                        , k -> zz < (1 << k));
                xx = lca[xx][l].val;
                z -= 1 << l;
            }
            int yy = y.val;
            if (x.tier <= y.tier) {
                yy = x.val;
            }
            while (xx != yy) {
                final int xxx = xx;
                final int yyy = yy;
                int l = (int) BinSearch.bs(0, 31
                        , k -> (1 << k) <= tree[xxx].tier && lca[xxx][(int) k] != lca[yyy][(int) k]);
                xx = lca[xx][l].val;
                yy = lca[yy][l].val;
            }
            return tree[xx];
        }
        //LCA end

        //graph
        List<Integer> adj[];
        List<int[]> adj2[];

        void initGraph(int n, int m, boolean hasW, boolean directed, int type) throws IOException {
            if (type == 1) {
                adj = new List[n + 1];
            } else {
                adj2 = new List[n + 1];
            }
            for (int i = 1; i <= n; i++) {
                if (type == 1) {
                    adj[i] = new ArrayList<>();
                } else {
                    adj2[i] = new ArrayList<>();
                }
            }
            for (int i = 0; i < m; i++) {
                int f = nextInt();
                int t = nextInt();
                if (type == 1) {
                    adj[f].add(t);
                    if (!directed) {
                        adj[t].add(f);
                    }
                } else {
                    int w = hasW ? nextInt() : 0;
                    adj2[f].add(new int[]{t, w});
                    if (!directed) {
                        adj2[t].add(new int[]{f, w});
                    }
                }
            }
        }

        void getDiv(Map<Integer, Integer> map, int n) {
            int sqrt = (int) Math.sqrt(n);
            for (int i = 2; i <= sqrt; i++) {
                int cnt = 0;
                while (n % i == 0) {
                    cnt++;
                    n /= i;
                }
                if (cnt > 0) {
                    map.put(i, cnt);
                }
            }
            if (n > 1) {
                map.put(n, 1);
            }
        }

        boolean[] generatePrime(int n) {
            boolean p[] = new boolean[n + 1];
            p[2] = true;

            for (int i = 3; i <= n; i += 2) {
                p[i] = true;
            }

            for (int i = 3; i <= Math.sqrt(n); i += 2) {
                if (!p[i]) {
                    continue;
                }
                for (int j = i * i; j <= n; j += i << 1) {
                    p[j] = false;
                }
            }
            return p;
        }

        boolean isPrime(long n) { //determines if n is a prime number
            int p[] = {2, 3, 5, 233, 331};
            int pn = p.length;
            long s = 0, t = n - 1;//n - 1 = 2^s * t
            while ((t & 1) == 0) {
                t >>= 1;
                ++s;
            }
            for (int i = 0; i < pn; ++i) {
                if (n == p[i]) {
                    return true;
                }
                long pt = pow(p[i], t, n);
                for (int j = 0; j < s; ++j) {
                    long cur = llMod(pt, pt, n);
                    if (cur == 1 && pt != 1 && pt != n - 1) {
                        return false;
                    }
                    pt = cur;
                }
                if (pt != 1) {
                    return false;
                }
            }
            return true;
        }

        long llMod(long a, long b, long mod) {
            return (a * b - (long) ((double) a / mod * b + 0.5) * mod + mod) % mod;
//        long r = 0;
//        a %= mod;
//        b %= mod;
//        while (b > 0) {
//            if ((b & 1) == 1) {
//                r = (r + a) % mod;
//            }
//            b >>= 1;
//            a = (a << 1) % mod;
//        }
//        return r;
        }

        long pow(long a, long n) {
            long ans = 1;
            while (n > 0) {
                if ((n & 1) == 1) {
                    ans = ans * a;
                }
                a = a * a;
                n >>= 1;
            }
            return ans;
        }

        long pow(long a, long n, long mod) {
            long ans = 1;
            while (n > 0) {
                if ((n & 1) == 1) {
                    ans = llMod(ans, a, mod);
                }
                a = llMod(a, a, mod);
                n >>= 1;
            }
            return ans;
        }

        private long[][] initC(int n) {
            long c[][] = new long[n][n];

            for (int i = 0; i < n; i++) {
                c[i][0] = 1;
            }

            for (int i = 1; i < n; i++) {
                for (int j = 1; j <= i; j++) {
                    c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
                }
            }
            return c;
        }

        /**
         * ps: n >= m, choose m from n;
         */
//        private int cmn(long n, long m) {
//            if (m > n) {
//                n ^= m;
//                m ^= n;
//                n ^= m;
//            }
//            m = Math.min(m, n - m);
//
//            long top = 1;
//            long bot = 1;
//            for (long i = n - m + 1; i <= n; i++) {
//                top = (top * i) % MOD;
//            }
//            for (int i = 1; i <= m; i++) {
//                bot = (bot * i) % MOD;
//            }
//
//            return (int) ((top * pow(bot, MOD - 2, MOD)) % MOD);
//        }

        long gcd(long a, long b) {
            if (a < b) {
                return gcd(b, a);
            }
            while (b != 0) {
                long tmp = a % b;
                a = b;
                b = tmp;
            }
            return a;
        }

        int[] unique(int a[], Map<Integer, Integer> idx, Map<Integer, Integer> cnt) {
            Integer order[] = new Integer[a.length];
            for (int i = 0; i < a.length; i++) {
                order[i] = i;
            }
            Arrays.sort(order, Comparator.comparingInt(o -> a[o]));
            int tmp[] = new int[a.length];
            for (int i = 0; i < a.length; i++) {
                tmp[i] = a[order[i]];
            }
            int j = 0;
            for (int i = 0; i < tmp.length; i++) {
                if (i == 0 || tmp[i] > tmp[i - 1]) {
                    idx.put(tmp[i], j++);
                }
                cnt.put(idx.get(tmp[i]), cnt.getOrDefault(idx.get(tmp[i]), 0) + 1);
            }
            int rs[] = new int[j];
            j = 0;
            for (int key : idx.keySet()) {
                rs[j++] = key;
            }
            Arrays.sort(rs);
            return rs;
        }

        boolean isEven(long n) {
            return (n & 1) == 0;
        }

        static class BinSearch {

            static long bs(long l, long r, IBinSearch sort) throws IOException {
                while (l < r) {
                    long m = l + (r - l) / 2;
                    if (sort.binSearchCmp(m)) {
                        l = m + 1;
                    } else {
                        r = m;
                    }
                }
                return l;
            }

            interface IBinSearch {
                boolean binSearchCmp(long k) throws IOException;
            }

        }
    }

    private static class InOut {
        private BufferedReader br;
        private StreamTokenizer st;
        private PrintWriter pw;

        InOut() throws FileNotFoundException {
            if (useInFile) {
                System.setIn(new FileInputStream("resources/inout/in.text"));
            }
            if (useOutFile) {
                System.setOut(new PrintStream("resources/inout/out.text"));
            }
            br = new BufferedReader(new InputStreamReader(System.in));
            st = new StreamTokenizer(br);
            pw = new PrintWriter(new OutputStreamWriter(System.out));
            st.ordinaryChar('\'');
            st.ordinaryChar('\"');
            st.ordinaryChar('/');
        }

        private long[] anLong(int n) throws IOException {
            long a[] = new long[n];
            for (int i = 0; i < n; i++) {
                a[i] = nextInt();
            }
            return a;
        }

        private String next() throws IOException {
            st.nextToken();
            return st.sval;
        }

        private String next(int len) throws IOException {
            char ch[] = new char[len];
            int cur = 0;
            char c;
            while ((c = (char) br.read()) == '\n' || c == '\r' || c == ' ' || c == '\t') ;
            do {
                ch[cur++] = c;
            } while (!((c = (char) br.read()) == '\n' || c == '\r' || c == ' ' || c == '\t'));
            return String.valueOf(ch, 0, cur);
        }

        private int nextInt() throws IOException {
            st.nextToken();
            return (int) st.nval;
        }

        private long nextLong(int n) throws IOException {
            return Long.parseLong(next(n));
        }

        private double nextDouble() throws IOException {
            st.nextToken();
            return st.nval;
        }

        private String[] nextSS(String reg) throws IOException {
            return br.readLine().split(reg);
        }

        private String nextLine() throws IOException {
            return br.readLine();
        }

        private void print(String s, boolean newLine) {
            if (null != s) {
                pw.print(s);
            }
            if (newLine) {
                pw.println();
            }
        }

        private void format(String format, Object... obj) {
            pw.format(format, obj);
        }

        private void flush() {
            pw.flush();
        }
    }

    private static class FFT {
        double[] roots;
        int maxN;

        public FFT(int maxN) {
            this.maxN = maxN;
            initRoots();
        }

        public long[] multiply(int[] a, int[] b) {
            int minSize = a.length + b.length - 1;
            int bits = 1;
            while (1 << bits < minSize) bits++;
            int N = 1 << bits;
            double[] aa = toComplex(a, N);
            double[] bb = toComplex(b, N);
            fftIterative(aa, false);
            fftIterative(bb, false);
            double[] c = new double[aa.length];
            for (int i = 0; i < N; i++) {
                c[2 * i] = aa[2 * i] * bb[2 * i] - aa[2 * i + 1] * bb[2 * i + 1];
                c[2 * i + 1] = aa[2 * i] * bb[2 * i + 1] + aa[2 * i + 1] * bb[2 * i];
            }
            fftIterative(c, true);
            long[] ret = new long[minSize];
            for (int i = 0; i < ret.length; i++) {
                ret[i] = Math.round(c[2 * i]);
            }
            return ret;
        }

        static double[] toComplex(int[] arr, int size) {
            double[] ret = new double[size * 2];
            for (int i = 0; i < arr.length; i++) {
                ret[2 * i] = arr[i];
            }
            return ret;
        }

        void initRoots() {
            roots = new double[2 * (maxN + 1)];
            double ang = 2 * Math.PI / maxN;
            for (int i = 0; i <= maxN; i++) {
                roots[2 * i] = Math.cos(i * ang);
                roots[2 * i + 1] = Math.sin(i * ang);
            }
        }

        int bits(int N) {
            int ret = 0;
            while (1 << ret < N) ret++;
            if (1 << ret != N) throw new RuntimeException();
            return ret;
        }

        void fftIterative(double[] array, boolean inv) {
            int bits = bits(array.length / 2);
            int N = 1 << bits;
            for (int from = 0; from < N; from++) {
                int to = Integer.reverse(from) >>> (32 - bits);
                if (from < to) {
                    double tmpR = array[2 * from];
                    double tmpI = array[2 * from + 1];
                    array[2 * from] = array[2 * to];
                    array[2 * from + 1] = array[2 * to + 1];
                    array[2 * to] = tmpR;
                    array[2 * to + 1] = tmpI;
                }
            }
            for (int n = 2; n <= N; n *= 2) {
                int delta = 2 * maxN / n;
                for (int from = 0; from < N; from += n) {
                    int rootIdx = inv ? 2 * maxN : 0;
                    double tmpR, tmpI;
                    for (int arrIdx = 2 * from; arrIdx < 2 * from + n; arrIdx += 2) {
                        tmpR = array[arrIdx + n] * roots[rootIdx] - array[arrIdx + n + 1] * roots[rootIdx + 1];
                        tmpI = array[arrIdx + n] * roots[rootIdx + 1] + array[arrIdx + n + 1] * roots[rootIdx];
                        array[arrIdx + n] = array[arrIdx] - tmpR;
                        array[arrIdx + n + 1] = array[arrIdx + 1] - tmpI;
                        array[arrIdx] += tmpR;
                        array[arrIdx + 1] += tmpI;
                        rootIdx += (inv ? -delta : delta);
                    }
                }
            }
            if (inv) {
                for (int i = 0; i < array.length; i++) {
                    array[i] /= N;
                }
            }
        }
    }
}


import java.io.*;
import java.util.*;

public class Solution {

    private static boolean useInFile = false;
    private static boolean useOutFile = false;

    public static void main(String args[]) throws IOException {
        InOut inout = new InOut();
        Resolver resolver = new Resolver(inout);
        resolver.solve();
        inout.flush();
    }

    private static class Resolver {

        final long LONG_INF = (long) 1e18;
        final int INF = (int) (1e9 + 7);
        final int MOD = 998244353;
        long f[], inv[];
        InOut inout;

        Resolver(InOut inout) {
            this.inout = inout;
        }

        void initF(int n, int mod) {
            f = new long[n + 1];
            f[1] = 1;
            for (int i = 2; i <= n; i++) {
                f[i] = (f[i - 1] * i) % mod;
            }
        }

        void initInv(int n, int mod) {
            inv = new long[n + 1];
            inv[n] = pow(f[n], INF - 2, INF);
            for (int i = inv.length - 2; i >= 0; i--) {
                inv[i] = inv[i + 1] * (i + 1) % mod;
            }
        }

        long cmn(int n, int m, int mod) {
            return f[n] * inv[m] % mod * inv[n - m] % mod;
        }

        int d[] = {0, -1, 0, 1, 0};

        boolean legal(int r, int c, int n, int m) {
            return r >= 0 && r < n && c >= 0 && c < m;
        }

        void solve() throws IOException {
            int tt = 1;
            boolean hvt = true;
            if (hvt) {
                tt = nextInt();
//                tt = Integer.parseInt(nextLine());
            }
            for (int cs = 1; cs <= tt; cs++) {
                long rs = 0;
                int n = nextInt();
                int len = nextInt();
                int x[] = anInt(0, n - 1);
                int y[] = anInt(0, n - 1);
                Arrays.sort(x);
                Map<Integer, Integer> cnt = new HashMap<>();
                x = unique(x, new HashMap<>(), cnt);
                n = x.length;
                long sum[] = new long[n];
                for (int i = 0; i < n; i++) {
                    sum[i] = cnt.get(i);
                    if (i > 0) {
                        sum[i] += sum[i - 1];
                    }
                }
                long dp[] = new long[n];
                dp[0] = sum[0];
                int[] finalX = x;
                int lft[] = new int[n];
                for (int i = 1; i < n; i++) {
                    final int r = i;
                    int l = (int) BinSearch.bs(0, i, new BinSearch.IBinSearch() {
                        @Override
                        public boolean binSearchCmp(long k) throws IOException {
                            return finalX[r] - finalX[(int) k] > len;
                        }
                    });
                    dp[i] = sum[r] - (l == 0 ? 0 : sum[l - 1]);
                    lft[i] = l;
                }

                for (int i = 0; i < n; i++) {
                    int l = lft[i];
                    rs = Math.max(rs, dp[i] + (l == 0 ? 0 : dp[l - 1]));
                    if (i > 0) {
                        dp[i] = Math.max(dp[i], dp[i - 1]);
                    }
                }

                format("%d", rs);
//                format("Case #%d: %d", cs, rs);

                if (cs < tt) {
                    format("\n");
                }
//                flush();
            }
        }

        private void updateSegTree(int n, long l, SegmentTree lft) {
            long lazy;
            lazy = 1;
            for (int j = 1; j <= l; j++) {
                lazy = (lazy + cmn((int) l, j, INF)) % INF;
                lft.modify(1, j, j, lazy);
            }
            lft.modify(1, (int) (l + 1), n, lazy);
        }

        String next() throws IOException {
            return inout.next();
        }

        String next(int n) throws IOException {
            return inout.next(n);
        }

        String nextLine() throws IOException {
            return inout.nextLine();
        }

        int nextInt() throws IOException {
            return inout.nextInt();
        }

        long nextLong(int n) throws IOException {
            return inout.nextLong(n);
        }

        int[] anInt(int i, int j) throws IOException {
            int a[] = new int[j + 1];
            for (int k = i; k <= j; k++) {
                a[k] = nextInt();
            }
            return a;
        }

        long[] anLong(int i, int j, int len) throws IOException {
            long a[] = new long[j + 1];
            for (int k = i; k <= j; k++) {
                a[k] = nextLong(len);
            }
            return a;
        }

        void print(String s, boolean nextLine) {
            inout.print(s, nextLine);
        }

        void format(String format, Object... obj) {
            inout.format(format, obj);
        }

        void flush() {
            inout.flush();
        }

        void swap(long a[], int i, int j) {
            a[i] ^= a[j];
            a[j] ^= a[i];
            a[i] ^= a[j];
        }

        int getP(int x, int p[]) {
            if (p[x] == 0 || p[x] == x) {
                return x;
            }
            return p[x] = getP(p[x], p);
        }

        void union(int x, int y, int p[]) {
            if (x < y) {
                p[y] = x;
            } else {
                p[x] = y;
            }
        }

        boolean topSort() {
            int n = adj2.length - 1;
            int d[] = new int[n + 1];
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j < adj2[i].size(); j++) {
                    d[adj2[i].get(j)[0]]++;
                }
            }
            List<Integer> list = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
                if (d[i] == 0) {
                    list.add(i);
                }
            }
            for (int i = 0; i < list.size(); i++) {
                for (int j = 0; j < adj2[list.get(i)].size(); j++) {
                    int t = adj2[list.get(i)].get(j)[0];
                    d[t]--;
                    if (d[t] == 0) {
                        list.add(t);
                    }
                }
            }
            return list.size() == n;
        }

        class SegmentTreeNode {
            long defaultVal = 0;
            int l, r;
            long val = defaultVal, lazy = defaultVal;

            SegmentTreeNode(int l, int r) {
                this.l = l;
                this.r = r;
            }
        }

        class SegmentTree {
            SegmentTreeNode tree[];
            long defaultVal = 0;
            long inf = Long.MIN_VALUE;
            long mod = INF;
            int type = 0;
            int MODIFY_VAL = 1;
            int MODIFY_LAZY = 2;
            int MODIFY_ALL = 3;

            SegmentTree(int n) {
                this(n, 0);
            }

            SegmentTree(int n, int type) {
                this.type = type;
                assert n > 0;
                tree = new SegmentTreeNode[n << 2];
            }

            SegmentTree build(int k, int l, int r) {
                if (l > r) {
                    return this;
                }
                if (null == tree[k]) {
                    tree[k] = new SegmentTreeNode(l, r);
                }
                if (l == r) {
                    return this;
                }
                int mid = (l + r) >> 1;
                build(k << 1, l, mid);
                build(k << 1 | 1, mid + 1, r);
                return this;
            }

            void pushDown(int k) {
                if (tree[k].l == tree[k].r) {
                    return;
                }
                long lazy = tree[k].lazy;
                modify(tree[k << 1], MODIFY_ALL, lazy);
                modify(tree[k << 1 | 1], MODIFY_ALL, lazy);
                tree[k].lazy = defaultVal;
            }

            void modify(int k, int l, int r, long val) {
                if (l > r) {
                    return;
                }
                if (tree[k].l >= l && tree[k].r <= r) {
                    modify(tree[k], MODIFY_ALL, val);
                    return;
                }
                int mid = (tree[k].l + tree[k].r) >> 1;
                if (mid >= l) {
                    modify(k << 1, l, r, val);
                }
                if (mid + 1 <= r) {
                    modify(k << 1 | 1, l, r, val);
                }
                tree[k].val = Math.max(tree[k << 1].val, tree[k << 1 | 1].val);
            }

            long query(int k, int l, int r) {
                if (tree[k].l > r || tree[k].r < l) {
                    return inf;
                }
                if (tree[k].lazy != defaultVal) {
                    pushDown(k);
                }
                if (tree[k].l >= l && tree[k].r <= r) {
                    return tree[k].val;
                }
                long ans = Math.max(query(k << 1, l, r), query(k << 1 | 1, l, r));
                if (tree[k].l < tree[k].r) {
                    tree[k].val = Math.max(tree[k << 1].val, tree[k << 1 | 1].val);
                }
                return ans;
            }

            private void modify(SegmentTreeNode node, int x, long val) {
                switch (type) {
                    case 0:
                        if (x == MODIFY_VAL) {
                            node.val += val;
                        } else if (x == MODIFY_LAZY) {
                            node.lazy += val;
                        } else {
                            node.val += val;
                            node.lazy += val;
                        }
                        break;
                    case 1:
                        if (x == MODIFY_VAL) {
                            node.val = node.val * val % mod;
                        } else if (x == MODIFY_LAZY) {
                            node.lazy = node.lazy * val % mod;
                        } else {
                            node.val = node.val * val % mod;
                            node.lazy = node.lazy * val % mod;
                        }
                        break;
                }
            }
        }

        class BinaryIndexedTree {

            int n = 1;
            long C[];

            BinaryIndexedTree(int sz) {
                while (n <= sz) {
                    n <<= 1;
                }
                C = new long[n];
            }

            int lowbit(int x) {
                return x & -x;
            }

            void add(int x, long val) {
                while (x < n) {
                    C[x] += val;
                    x += lowbit(x);
                }
            }

            long getSum(int x) {
                long res = 0;
                while (x > 0) {
                    res += C[x];
                    x -= lowbit(x);
                }
                return res;
            }

            int binSearch(long sum) {
                if (sum == 0) {
                    return 0;
                }
                int n = C.length;
                int mx = 1;
                while (mx < n) {
                    mx <<= 1;
                }
                int res = 0;
                for (int i = mx / 2; i >= 1; i >>= 1) {
                    if (C[res + i] < sum) {
                        sum -= C[res + i];
                        res += i;
                    }
                }
                return res + 1;
            }
        }

        int mnS;
        int mxS;
        Map<Integer, TrieNode> SS = new HashMap<>();
        class TrieNode {
            int cnt = 0;
            boolean isMin = false;
            boolean isMax = false;
            int mnIdx = 26;
            int mxIdx = -1;

            TrieNode next[];

            TrieNode() {
                next = new TrieNode[26];
            }

            private void insert(TrieNode trie, char ch[], int i, int j) {
                while (i < ch.length) {
                    int idx = ch[i] - 'a';
                    if (null == trie.next[idx]) {
                        trie.next[idx] = new TrieNode();
                    }
                    trie.cnt++;
                    int lastMnIdx = trie.mnIdx;
                    int lastMxIdx = trie.mxIdx;
                    trie.mnIdx = Math.min(trie.mnIdx, idx);
                    trie.mxIdx = Math.max(trie.mxIdx, idx);
                    if (trie.isMin && lastMnIdx != trie.mnIdx) {
                        if (lastMnIdx != 26) {
                            notMin(trie.next[lastMnIdx]);
                        }
                        trie.next[trie.mnIdx].isMin = true;
                    }
                    if (trie.isMax && lastMxIdx != trie.mxIdx) {
                        if (lastMxIdx >= 0) {
                            notMax(trie.next[lastMxIdx]);
                        }
                        trie.next[trie.mxIdx].isMax = true;
                    }
                    trie = trie.next[idx];
                    i++;
                }
                SS.put(j + 1, trie);
                if (trie.cnt == 0) {
                    if (trie.isMin) {
                        mnS = j + 1;
                    }
                    if (trie.isMax) {
                        mxS = j + 1;
                    }
                }
            }

            private void notMin(TrieNode trie) {
                while (null != trie) {
                    trie.isMin = false;
                    int val = trie.mnIdx;
                    if (val >= 26 || val < 0 || null == trie.next[val]) {
                        break;
                    }
                    trie = trie.next[val];
                }
            }

            private void notMax(TrieNode trie) {
                while (null != trie) {
                    trie.isMax = false;
                    int val = trie.mxIdx;
                    if (val >= 26 || val < 0 || null == trie.next[val]) {
                        break;
                    }
                    trie = trie.next[val];
                }
            }
        }

        //Binary tree
        class TreeNode {
            int val;
            int tier = -1;
            TreeNode parent;
            TreeNode left;
            TreeNode right;

            TreeNode(int val) {
                this.val = val;
            }
        }

        //binary tree dfs
        void tierTree(TreeNode root) {
            if (null == root) {
                return;
            }
            if (null != root.parent) {
                root.tier = root.parent.tier + 1;
            } else {
                root.tier = 0;
            }
            tierTree(root.left);
            tierTree(root.right);
        }

        //LCA start
        TreeNode[][] lca;
        TreeNode[] tree;

        void lcaDfsTree(TreeNode root) {
            if (null == root) {
                return;
            }
            tree[root.val] = root;
            TreeNode nxt = root.parent;
            int idx = 0;
            while (null != nxt) {
                lca[root.val][idx] = nxt;
                nxt = lca[nxt.val][idx];
                idx++;
            }
            lcaDfsTree(root.left);
            lcaDfsTree(root.right);
        }

        TreeNode lcaTree(TreeNode root, int n, TreeNode x, TreeNode y) throws IOException {
            if (null == root) {
                return null;
            }
            if (-1 == root.tier) {
                tree = new TreeNode[n + 1];
                tierTree(root);
            }
            if (null == lca) {
                lca = new TreeNode[n + 1][31];
                lcaDfsTree(root);
            }
            int z = Math.abs(x.tier - y.tier);
            int xx = x.tier > y.tier ? x.val : y.val;
            while (z > 0) {
                final int zz = z;
                int l = (int) BinSearch.bs(0, 31
                        , k -> zz < (1 << k));
                xx = lca[xx][l].val;
                z -= 1 << l;
            }
            int yy = y.val;
            if (x.tier <= y.tier) {
                yy = x.val;
            }
            while (xx != yy) {
                final int xxx = xx;
                final int yyy = yy;
                int l = (int) BinSearch.bs(0, 31
                        , k -> (1 << k) <= tree[xxx].tier && lca[xxx][(int) k] != lca[yyy][(int) k]);
                xx = lca[xx][l].val;
                yy = lca[yy][l].val;
            }
            return tree[xx];
        }
        //LCA end

        //graph
        List<Integer> adj[];
        List<int[]> adj2[];

        void initGraph(int n, int m, boolean hasW, boolean directed, int type) throws IOException {
            if (type == 1) {
                adj = new List[n + 1];
            } else {
                adj2 = new List[n + 1];
            }
            for (int i = 1; i <= n; i++) {
                if (type == 1) {
                    adj[i] = new ArrayList<>();
                } else {
                    adj2[i] = new ArrayList<>();
                }
            }
            for (int i = 0; i < m; i++) {
                int f = nextInt();
                int t = nextInt();
                if (type == 1) {
                    adj[f].add(t);
                    if (!directed) {
                        adj[t].add(f);
                    }
                } else {
                    int w = hasW ? nextInt() : 0;
                    adj2[f].add(new int[]{t, w});
                    if (!directed) {
                        adj2[t].add(new int[]{f, w});
                    }
                }
            }
        }

        void getDiv(Map<Integer, Integer> map, int n) {
            int sqrt = (int) Math.sqrt(n);
            for (int i = 2; i <= sqrt; i++) {
                int cnt = 0;
                while (n % i == 0) {
                    cnt++;
                    n /= i;
                }
                if (cnt > 0) {
                    map.put(i, cnt);
                }
            }
            if (n > 1) {
                map.put(n, 1);
            }
        }

        boolean[] generatePrime(int n) {
            boolean p[] = new boolean[n + 1];
            p[2] = true;

            for (int i = 3; i <= n; i += 2) {
                p[i] = true;
            }

            for (int i = 3; i <= Math.sqrt(n); i += 2) {
                if (!p[i]) {
                    continue;
                }
                for (int j = i * i; j <= n; j += i << 1) {
                    p[j] = false;
                }
            }
            return p;
        }

        boolean isPrime(long n) { //determines if n is a prime number
            int p[] = {2, 3, 5, 233, 331};
            int pn = p.length;
            long s = 0, t = n - 1;//n - 1 = 2^s * t
            while ((t & 1) == 0) {
                t >>= 1;
                ++s;
            }
            for (int i = 0; i < pn; ++i) {
                if (n == p[i]) {
                    return true;
                }
                long pt = pow(p[i], t, n);
                for (int j = 0; j < s; ++j) {
                    long cur = llMod(pt, pt, n);
                    if (cur == 1 && pt != 1 && pt != n - 1) {
                        return false;
                    }
                    pt = cur;
                }
                if (pt != 1) {
                    return false;
                }
            }
            return true;
        }

        long llMod(long a, long b, long mod) {
            return (a * b - (long) ((double) a / mod * b + 0.5) * mod + mod) % mod;
//        long r = 0;
//        a %= mod;
//        b %= mod;
//        while (b > 0) {
//            if ((b & 1) == 1) {
//                r = (r + a) % mod;
//            }
//            b >>= 1;
//            a = (a << 1) % mod;
//        }
//        return r;
        }

        long pow(long a, long n) {
            long ans = 1;
            while (n > 0) {
                if ((n & 1) == 1) {
                    ans = ans * a;
                }
                a = a * a;
                n >>= 1;
            }
            return ans;
        }

        long pow(long a, long n, long mod) {
            long ans = 1;
            while (n > 0) {
                if ((n & 1) == 1) {
                    ans = llMod(ans, a, mod);
                }
                a = llMod(a, a, mod);
                n >>= 1;
            }
            return ans;
        }

        private long[][] initC(int n) {
            long c[][] = new long[n][n];

            for (int i = 0; i < n; i++) {
                c[i][0] = 1;
            }

            for (int i = 1; i < n; i++) {
                for (int j = 1; j <= i; j++) {
                    c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
                }
            }
            return c;
        }

        /**
         * ps: n >= m, choose m from n;
         */
//        private int cmn(long n, long m) {
//            if (m > n) {
//                n ^= m;
//                m ^= n;
//                n ^= m;
//            }
//            m = Math.min(m, n - m);
//
//            long top = 1;
//            long bot = 1;
//            for (long i = n - m + 1; i <= n; i++) {
//                top = (top * i) % MOD;
//            }
//            for (int i = 1; i <= m; i++) {
//                bot = (bot * i) % MOD;
//            }
//
//            return (int) ((top * pow(bot, MOD - 2, MOD)) % MOD);
//        }

        long gcd(long a, long b) {
            if (a < b) {
                return gcd(b, a);
            }
            while (b != 0) {
                long tmp = a % b;
                a = b;
                b = tmp;
            }
            return a;
        }

        int[] unique(int a[], Map<Integer, Integer> idx, Map<Integer, Integer> cnt) {
            int tmp[] = a.clone();
            Arrays.sort(tmp);
            int j = 0;
            for (int i = 0; i < tmp.length; i++) {
                if (i == 0 || tmp[i] > tmp[i - 1]) {
                    idx.put(tmp[i], j++);
                }
                cnt.put(idx.get(tmp[i]), cnt.getOrDefault(idx.get(tmp[i]), 0) + 1);
            }
            int rs[] = new int[j];
            j = 0;
            for (int key : idx.keySet()) {
                rs[j++] = key;
            }
            Arrays.sort(rs);
            return rs;
        }

        boolean isEven(long n) {
            return (n & 1) == 0;
        }

        static class BinSearch {

            static long bs(long l, long r, IBinSearch sort) throws IOException {
                while (l < r) {
                    long m = l + (r - l) / 2;
                    if (sort.binSearchCmp(m)) {
                        l = m + 1;
                    } else {
                        r = m;
                    }
                }
                return l;
            }

            interface IBinSearch {
                boolean binSearchCmp(long k) throws IOException;
            }

        }
    }

    private static class InOut {
        private BufferedReader br;
        private StreamTokenizer st;
        private PrintWriter pw;

        InOut() throws FileNotFoundException {
            if (useInFile) {
                System.setIn(new FileInputStream("resources/inout/in.text"));
            }
            if (useOutFile) {
                System.setOut(new PrintStream("resources/inout/out.text"));
            }
            br = new BufferedReader(new InputStreamReader(System.in));
            st = new StreamTokenizer(br);
            pw = new PrintWriter(new OutputStreamWriter(System.out));
            st.ordinaryChar('\'');
            st.ordinaryChar('\"');
            st.ordinaryChar('/');
        }

        private long[] anLong(int n) throws IOException {
            long a[] = new long[n];
            for (int i = 0; i < n; i++) {
                a[i] = nextInt();
            }
            return a;
        }

        private String next() throws IOException {
            st.nextToken();
            return st.sval;
        }

        private String next(int len) throws IOException {
            char ch[] = new char[len];
            int cur = 0;
            char c;
            while ((c = (char) br.read()) == '\n' || c == '\r' || c == ' ' || c == '\t') ;
            do {
                ch[cur++] = c;
            } while (!((c = (char) br.read()) == '\n' || c == '\r' || c == ' ' || c == '\t'));
            return String.valueOf(ch, 0, cur);
        }

        private int nextInt() throws IOException {
            st.nextToken();
            return (int) st.nval;
        }

        private long nextLong(int n) throws IOException {
            return Long.parseLong(next(n));
        }

        private double nextDouble() throws IOException {
            st.nextToken();
            return st.nval;
        }

        private String[] nextSS(String reg) throws IOException {
            return br.readLine().split(reg);
        }

        private String nextLine() throws IOException {
            return br.readLine();
        }

        private void print(String s, boolean newLine) {
            if (null != s) {
                pw.print(s);
            }
            if (newLine) {
                pw.println();
            }
        }

        private void format(String format, Object... obj) {
            pw.format(format, obj);
        }

        private void flush() {
            pw.flush();
        }
    }

    private static class FFT {
        double[] roots;
        int maxN;

        public FFT(int maxN) {
            this.maxN = maxN;
            initRoots();
        }

        public long[] multiply(int[] a, int[] b) {
            int minSize = a.length + b.length - 1;
            int bits = 1;
            while (1 << bits < minSize) bits++;
            int N = 1 << bits;
            double[] aa = toComplex(a, N);
            double[] bb = toComplex(b, N);
            fftIterative(aa, false);
            fftIterative(bb, false);
            double[] c = new double[aa.length];
            for (int i = 0; i < N; i++) {
                c[2 * i] = aa[2 * i] * bb[2 * i] - aa[2 * i + 1] * bb[2 * i + 1];
                c[2 * i + 1] = aa[2 * i] * bb[2 * i + 1] + aa[2 * i + 1] * bb[2 * i];
            }
            fftIterative(c, true);
            long[] ret = new long[minSize];
            for (int i = 0; i < ret.length; i++) {
                ret[i] = Math.round(c[2 * i]);
            }
            return ret;
        }

        static double[] toComplex(int[] arr, int size) {
            double[] ret = new double[size * 2];
            for (int i = 0; i < arr.length; i++) {
                ret[2 * i] = arr[i];
            }
            return ret;
        }

        void initRoots() {
            roots = new double[2 * (maxN + 1)];
            double ang = 2 * Math.PI / maxN;
            for (int i = 0; i <= maxN; i++) {
                roots[2 * i] = Math.cos(i * ang);
                roots[2 * i + 1] = Math.sin(i * ang);
            }
        }

        int bits(int N) {
            int ret = 0;
            while (1 << ret < N) ret++;
            if (1 << ret != N) throw new RuntimeException();
            return ret;
        }

        void fftIterative(double[] array, boolean inv) {
            int bits = bits(array.length / 2);
            int N = 1 << bits;
            for (int from = 0; from < N; from++) {
                int to = Integer.reverse(from) >>> (32 - bits);
                if (from < to) {
                    double tmpR = array[2 * from];
                    double tmpI = array[2 * from + 1];
                    array[2 * from] = array[2 * to];
                    array[2 * from + 1] = array[2 * to + 1];
                    array[2 * to] = tmpR;
                    array[2 * to + 1] = tmpI;
                }
            }
            for (int n = 2; n <= N; n *= 2) {
                int delta = 2 * maxN / n;
                for (int from = 0; from < N; from += n) {
                    int rootIdx = inv ? 2 * maxN : 0;
                    double tmpR, tmpI;
                    for (int arrIdx = 2 * from; arrIdx < 2 * from + n; arrIdx += 2) {
                        tmpR = array[arrIdx + n] * roots[rootIdx] - array[arrIdx + n + 1] * roots[rootIdx + 1];
                        tmpI = array[arrIdx + n] * roots[rootIdx + 1] + array[arrIdx + n + 1] * roots[rootIdx];
                        array[arrIdx + n] = array[arrIdx] - tmpR;
                        array[arrIdx + n + 1] = array[arrIdx + 1] - tmpI;
                        array[arrIdx] += tmpR;
                        array[arrIdx + 1] += tmpI;
                        rootIdx += (inv ? -delta : delta);
                    }
                }
            }
            if (inv) {
                for (int i = 0; i < array.length; i++) {
                    array[i] /= N;
                }
            }
        }
    }
}