import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Pranay2516
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(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, FastReader in, PrintWriter out) {
            int n = in.nextInt(), k = in.nextInt(), x[] = in.readIntArray(n), y[] = in.readIntArray(n), l[] = new int[n], r[] = new int[n], j = 0, ans = 1;
            func.sort(x);
            for (int i = 0; i < n; ++i) {
                while (x[i] - x[j] > k) ++j;
                l[i] = i - j + 1;
                if (i > 0) l[i] = Math.max(l[i], l[i - 1]);
            }
            j = n - 1;
            for (int i = n - 1; i >= 0; --i) {
                while (x[j] - x[i] > k) --j;
                r[i] = j - i + 1;
                if (i < n - 1) r[i] = Math.max(r[i], r[i + 1]);
            }
            for (int i = 0; i < n - 1; ++i) ans = Math.max(ans, r[i + 1] + l[i]);
            out.println(ans);
        }

    }

    static class func {
        public static void sort(int[] arr) {
            //Taken from @KharYusuf
            int n = arr.length, mid, h, s, l, i, j, k;
            int[] res = new int[n];
            n--;
            for (s = 1; s <= n; s <<= 1) {
                for (l = 0; l < n; l += (s << 1)) {
                    h = Math.min(l + (s << 1) - 1, n);
                    mid = Math.min(l + s - 1, n);
                    i = l;
                    j = mid + 1;
                    k = l;
                    while (i <= mid && j <= h) res[k++] = (arr[i] <= arr[j] ? arr[i++] : arr[j++]);
                    while (i <= mid) res[k++] = arr[i++];
                    while (j <= h) res[k++] = arr[j++];
                    for (k = l; k <= h; k++) arr[k] = res[k];
                }
            }
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) return -1;
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[(int) size];
            for (int i = 0; i < size; i++) array[i] = nextInt();
            return array;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {

    InputReader in;
    Printer out;

    long mod = 1000000007;

    private void start() throws Exception {
        int t = in.nextInt();

        while (t-- > 0) {
            int n = in.nextInt();
            long k = in.nextLong();

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

            HashMap<Long, Long> map = new HashMap<>();
            for (long xval: x) {
                long count = map.getOrDefault(xval, 0L);
                map.put(xval, count + 1);
            }
            ArrayList<Pair> list = new ArrayList<>();

            for (long xval: map.keySet()) {
                list.add(new Pair(xval, map.get(xval)));
            }
            long[] prefixSum = new long[list.size()];
            Collections.sort(list);
            for (int i = 0; i < prefixSum.length; i++) {
                if (i == 0) {
                    prefixSum[i] = list.get(0).count;
                } else {
                    prefixSum[i] = prefixSum[i - 1] + list.get(i).count;
                }
            }
            long[] res1 = new long[list.size()];
            long[] res2 = new long[list.size()];

            res1[0] = list.get(0).count;

            for (int i = 1; i < list.size(); i++) {
                int l = 0; int r = i - 1;
                int res = i;
                while (l <= r) {
                    int mid = (l + r) / 2;

                    long midVal = list.get(mid).val;
                    if (list.get(i).val - midVal > k) {
                        l = mid + 1;
                    } else {
                        r = mid - 1;
                        res = mid;
                    }
                }
                if (res == 0) {
                    res1[i] = prefixSum[i];
                } else {
                    res1[i] = prefixSum[i] - prefixSum[res - 1];
                }
            }
//            out.println();

//            out.println("calculating res2");
            for (int i = list.size() - 1; i >= 0; i--) {
//                out.println("i " + i);
                int l = i + 1; int r = list.size() - 1;
                int res = i;
                while (l <= r) {
                    int mid = (l + r) / 2;

                    long midVal = list.get(mid).val;
                    if (-list.get(i).val + midVal > k) {
                        r = mid - 1;
                    } else {
                        l = mid + 1;
                        res = mid;
                    }
                }

//                out.println("res " + res);
                if (i == 0) {
                    res2[i] = prefixSum[res];
                } else {
                    res2[i] = prefixSum[res] - prefixSum[i - 1];
                }
            }

            long maxRes2[] = new long[list.size()];
            maxRes2[list.size() - 1] = res2[list.size() - 1];

            for (int i = list.size() - 2; i >= 0; i--) {
                maxRes2[i] = Math.max(maxRes2[i + 1], res2[i]);
            }

            long res = res1[0];
            res = Math.max(res, maxRes2[0]);
            for (int i = 0; i < list.size() - 1; i++) {
                res = Math.max(res, res1[i] + maxRes2[i + 1]);
//                out.println("AA " + (res1[i] + maxRes2[i + 1]));
            }
            res = Math.max(res, res1[list.size() - 1]);

//            out.println("list " + list);
//            out.println("res1 " + Arrays.toString(res1));
//            out.println("res2 " + Arrays.toString(res2));
            out.println(res);
        }
    }

    class Pair implements Comparable {
        long val;
        long count;

        public Pair(long v, long i) {
            val = v;
            count = i;
        }

        @Override
        public String toString() {
            return "(" + val + "," + count + ")";
        }

        @Override
        public int compareTo(Object o) {
            if (!(o instanceof Pair)) {
                return -1;
            }

            Pair pair2 = (Pair) o;

            if (this.val < pair2.val) {
                return -1;
            } else if (this.val > pair2.val) {
                return 1;
            }
            return 0;
        }
    }

    long power(long x, long n) {
        if (n <= 0) {
            return 1;
        }

        long y = power(x, n / 2);

        if ((n % 2) == 0) {
            return (y * y) % mod;
        } else {
            return (((y * y) % mod) * x) % mod;
        }
    }

    long gcd(long a, long b) {
        return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).longValue();
    }

    public static void main(String[] args) throws Exception {
        InputReader in;
        PrintStream out;

//        in = new InputReader(new FileInputStream(new File("in.txt")));
        in = new InputReader(System.in);
        out = System.out;

        Main main = new Main();

        main.in = in;
        main.out = new Printer(out, false);

        main.start();
        main.out.flush();
    }

    private static class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public String nextString() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E') {
                    return res * Math.pow(10, nextInt());
                }
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E') {
                        return res * Math.pow(10, nextInt());
                    }
                    if (c < '0' || c > '9') {
                        throw new InputMismatchException();
                    }
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return nextString();
        }

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }
    }

    private static class Printer {

        PrintStream out;
        StringBuilder buffer = new StringBuilder();
        boolean autoFlush;

        public Printer(PrintStream out) {
            this.out = out;
        }

        public Printer(PrintStream out, boolean autoFlush) {
            this.out = out;
            this.autoFlush = autoFlush;
        }

        public void println() {
            buffer.append("\n");

            if (autoFlush) {
                flush();
            }
        }

        public void println(int n) {
            println(Integer.toString(n));
        }

        public void println(long n) {
            println(Long.toString(n));
        }

        public void println(double n) {
            println(Double.toString(n));
        }

        public void println(float n) {
            println(Float.toString(n));
        }

        public void println(boolean n) {
            println(Boolean.toString(n));
        }

        public void println(char n) {
            println(Character.toString(n));
        }

        public void println(byte n) {
            println(Byte.toString(n));
        }

        public void println(short n) {
            println(Short.toString(n));
        }

        public void println(Object o) {
            println(o.toString());
        }

        public void println(Object ... args) {
            print(args);
            println();
        }

        public void print(Object ... args) {
            for (int i = 0; i < args.length; i++) {
                Object item = args[i];
                buffer.append(item.toString());

                if (i < args.length - 1) {
                    buffer.append(" ");
                }
            }
            if (autoFlush) {
                flush();
            }
        }

        public void println(String s) {
            buffer.append(s).append("\n");

            if (autoFlush) {
                flush();
            }
        }

        public void print(char s) {
            buffer.append(s);

            if (autoFlush) {
                flush();
            }
        }

        public void print(String s) {
            buffer.append(s);

            if (autoFlush) {
                flush();
            }
        }

        public void flush() {
            try {
                BufferedWriter log = new BufferedWriter(new OutputStreamWriter(out));
                log.write(buffer.toString());

                log.flush();
                buffer = new StringBuilder();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private class PairSet<T, S> {

        HashMap<T, HashSet<S>> map = new HashMap<>();

        public void add(T a, S b) {
            if (map.containsKey(a)) {
                map.get(a).add(b);
            }

            HashSet<S> set = new HashSet<>();
            set.add(b);
            map.put(a, set);
        }

        public boolean contains(T a, S b) {
            if (map.containsKey(a)) {
                return map.get(a).contains(b);
            }

            return false;
        }
    }

    private class Bit {

        int N;
        long ft1[], ft2[];

        Bit(int n) {
            N = n;
            ft1 = new long[N + 1];
            ft2 = new long[N + 1];
        }

        void update(long ft[], int p, long v) {
            for (; p <= N; p += p & (-p)) {
                ft[p] += v;
//                ft[p] %= MOD;
            }
        }

        void update(int a, int b, long v) {
            update(ft1, a, v);
            update(ft1, b + 1, -v);
            update(ft2, a, v * (a - 1));
            update(ft2, b + 1, -v * b);
        }

        long query(long ft[], int b) {
            long sum = 0;
            for (; b > 0; b -= b & (-b)) {
                sum += ft[b];
//                sum %= MOD;
            }

            return sum;
        }

        long query(int b) {
            return query(ft1, b) * b - query(ft2, b);
        }

        long query(int a, int b) {
            return query(b) - query(a - 1);
        }
    }

    class Bipartite {

        int m, n;
        boolean[][] graph;
        boolean seen[];
        int matchL[];   //What left vertex i is matched to (or -1 if unmatched)
        int matchR[];   //What right vertex j is matched to (or -1 if unmatched)

        public Bipartite(boolean[][] graph) {
            this.graph = graph;
            m = graph.length;
            n = graph[0].length;

            matchL = new int[m];
            matchR = new int[n];
            seen = new boolean[n];
        }

        int maximumMatching() {
            //Read input and populate graph[][]
            //Set m to be the size of L, n to be the size of R
            Arrays.fill(matchL, -1);
            Arrays.fill(matchR, -1);

            int count = 0;
            for (int i = 0; i < m; i++) {
                Arrays.fill(seen, false);
                if (bpm(i)) {
                    count++;
                }
            }
            return count;
        }

        boolean bpm(int u) {
            //try to match with all vertices on right side
            for (int v = 0; v < n; v++) {
                if (!graph[u][v] || seen[v]) {
                    continue;
                }
                seen[v] = true;
                //match u and v, if v is unassigned, or if v's match on the left side can be reassigned to another right vertex
                if (matchR[v] == -1 || bpm(matchR[v])) {
                    matchL[u] = v;
                    matchR[v] = u;
                    return true;
                }
            }
            return false;
        }
    }

    public static Set<Integer[]> getPermutationsRecursive(Integer[] num) {
        if (num == null) {
            return null;
        }

        Set<Integer[]> perms = new HashSet<>();

        //base case
        if (num.length == 0) {
            perms.add(new Integer[0]);
            return perms;
        }

        //shave off first int then get sub perms on remaining ints.
        //...then insert the first into each position of each sub perm..recurse
        int first = num[0];
        Integer[] remainder = Arrays.copyOfRange(num, 1, num.length);
        Set<Integer[]> subPerms = getPermutationsRecursive(remainder);
        for (Integer[] subPerm : subPerms) {
            for (int i = 0; i <= subPerm.length; ++i) { // '<='   IMPORTANT !!!
                Integer[] newPerm = Arrays.copyOf(subPerm, subPerm.length + 1);
                for (int j = newPerm.length - 1; j > i; --j) {
                    newPerm[j] = newPerm[j - 1];
                }
                newPerm[i] = first;
                perms.add(newPerm);
            }
        }

        return perms;
    }

    public class SuffixArray {

        /*  // Usage:
            SuffixArray sf = new SuffixArray();

            String s1 = "abcab";
            int[] sa1 = sf.suffixArray(s1);

            // print suffixes in lexicographic order
            for (int p : sa1) {
                System.out.println(s1.substring(p));
            }

            System.out.println("lcp = " + Arrays.toString(sf.lcp(sa1, s1)));
         */
        // sort suffixes of S in O(n*log(n))
        public int[] suffixArray(CharSequence S) {
            int n = S.length();
            Integer[] order = new Integer[n];
            for (int i = 0; i < n; i++) {
                order[i] = n - 1 - i;
            }

            // stable sort of characters
            Arrays.sort(order, (a, b) -> Character.compare(S.charAt(a), S.charAt(b)));

            int[] sa = new int[n];
            int[] classes = new int[n];
            for (int i = 0; i < n; i++) {
                sa[i] = order[i];
                classes[i] = S.charAt(i);
            }
            // sa[i] - suffix on i'th position after sorting by first len characters
            // classes[i] - equivalence class of the i'th suffix after sorting by first len characters

            for (int len = 1; len < n; len *= 2) {
                int[] c = classes.clone();
                for (int i = 0; i < n; i++) {
                    // condition sa[i - 1] + len < n simulates 0-symbol at the end of the string
                    // a separate class is created for each suffix followed by simulated 0-symbol
                    classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
                }
                // Suffixes are already sorted by first len characters
                // Now sort suffixes by first len * 2 characters
                int[] cnt = new int[n];
                for (int i = 0; i < n; i++) {
                    cnt[i] = i;
                }
                int[] s = sa.clone();
                for (int i = 0; i < n; i++) {
                    // s[i] - order of suffixes sorted by first len characters
                    // (s[i] - len) - order of suffixes sorted only by second len characters
                    int s1 = s[i] - len;
                    // sort only suffixes of length > len, others are already sorted
                    if (s1 >= 0) {
                        sa[cnt[classes[s1]]++] = s1;
                    }
                }
            }
            return sa;
        }

        // sort rotations of S in O(n*log(n))
        public int[] rotationArray(CharSequence S) {
            int n = S.length();
            Integer[] order = new Integer[n];
            for (int i = 0; i < n; i++) {
                order[i] = i;
            }
            Arrays.sort(order, (a, b) -> Character.compare(S.charAt(a), S.charAt(b)));
            int[] sa = new int[n];
            int[] classes = new int[n];
            for (int i = 0; i < n; i++) {
                sa[i] = order[i];
                classes[i] = S.charAt(i);
            }
            for (int len = 1; len < n; len *= 2) {
                int[] c = classes.clone();
                for (int i = 0; i < n; i++) {
                    classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && c[(sa[i - 1] + len / 2) % n] == c[(sa[i] + len / 2) % n] ? classes[sa[i - 1]] : i;
                }
                int[] cnt = new int[n];
                for (int i = 0; i < n; i++) {
                    cnt[i] = i;
                }
                int[] s = sa.clone();
                for (int i = 0; i < n; i++) {
                    int s1 = (s[i] - len + n) % n;
                    sa[cnt[classes[s1]]++] = s1;
                }
            }
            return sa;
        }

        // longest common prefixes array in O(n)
        public int[] lcp(int[] sa, CharSequence s) {
            int n = sa.length;
            int[] rank = new int[n];
            for (int i = 0; i < n; i++) {
                rank[sa[i]] = i;
            }
            int[] lcp = new int[n - 1];
            for (int i = 0, h = 0; i < n; i++) {
                if (rank[i] < n - 1) {
                    for (int j = sa[rank[i] + 1];
                         Math.max(i, j) + h < s.length() && s.charAt(i + h) == s.charAt(j + h);
                         ++h) {
                    }
                    lcp[rank[i]] = h;
                    if (h > 0) {
                        --h;
                    }
                }
            }
            return lcp;
        }

        public void main() {
            String s1 = "abcab";
            int[] sa1 = suffixArray(s1);

            // print suffixes in lexicographic order
            for (int p : sa1) {
                System.out.println(s1.substring(p));
            }

            System.out.println("lcp = " + Arrays.toString(lcp(sa1, s1)));

            // random test
            Random rnd = new Random(1);
            for (int step = 0; step < 100000; step++) {
                int n = rnd.nextInt(100) + 1;
                StringBuilder s = new StringBuilder();
                for (int i = 0; i < n; i++) {
                    s.append((char) ('\1' + rnd.nextInt(10)));
                }
                int[] sa = suffixArray(s);
                int[] ra = rotationArray(s.toString() + '\0');
                int[] lcp = lcp(sa, s);
                for (int i = 0; i + 1 < n; i++) {
                    String a = s.substring(sa[i]);
                    String b = s.substring(sa[i + 1]);
                    if (a.compareTo(b) >= 0
                            || !a.substring(0, lcp[i]).equals(b.substring(0, lcp[i]))
                            || (a + " ").charAt(lcp[i]) == (b + " ").charAt(lcp[i])
                            || sa[i] != ra[i + 1]) {
                        throw new RuntimeException();
                    }
                }
            }
            System.out.println("Test passed");
        }
    }

    class LazySegmentTree {

        final int MAX = 262146;
        int tree[] = new int[MAX];
        int lazy[] = new int[MAX];

        void updateRangeUtil(int si, int ss, int se, int us,
                             int ue, int diff) {
            if (lazy[si] != 0) {
                tree[si] += (se - ss + 1) * lazy[si];

                if (ss != se) {
                    lazy[si * 2 + 1] += lazy[si];
                    lazy[si * 2 + 2] += lazy[si];
                }

                lazy[si] = 0;
            }

            if (ss > se || ss > ue || se < us) {
                return;
            }

            if (ss >= us && se <= ue) {
                tree[si] += (se - ss + 1) * diff;

                if (ss != se) {
                    lazy[si * 2 + 1] += diff;
                    lazy[si * 2 + 2] += diff;
                }
                return;
            }

            int mid = (ss + se) / 2;
            updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);
            updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);

            tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];
        }

        void updateRange(int n, int us, int ue, int diff) {
            updateRangeUtil(0, 0, n - 1, us, ue, diff);
        }

        int getSumUtil(int ss, int se, int qs, int qe, int si) {
            if (lazy[si] != 0) {
                tree[si] += (se - ss + 1) * lazy[si];

                if (ss != se) {
                    lazy[si * 2 + 1] += lazy[si];
                    lazy[si * 2 + 2] += lazy[si];
                }

                lazy[si] = 0;
            }

            if (ss > se || ss > qe || se < qs) {
                return 0;
            }
            if (ss >= qs && se <= qe) {
                return tree[si];
            }

            int mid = (ss + se) / 2;
            return getSumUtil(ss, mid, qs, qe, 2 * si + 1)
                    + getSumUtil(mid + 1, se, qs, qe, 2 * si + 2);
        }

        int getSum(int n, int qs, int qe) {
            // Check for erroneous input values
            if (qs < 0 || qe > n - 1 || qs > qe) {
                System.out.println("Invalid Input");
                return -1;
            }

            return getSumUtil(0, n - 1, qs, qe, 0);
        }

        void constructSTUtil(int arr[], int ss, int se, int si) {
            // out of range as ss can never be greater than se
            if (ss > se) {
                return;
            }

            /* If there is one element in array, store it in
         current node of segment tree and return */
            if (ss == se) {
                tree[si] = arr[ss];
                return;
            }

            /* If there are more than one elements, then recur
           for left and right subtrees and store the sum
           of values in this node */
            int mid = (ss + se) / 2;
            constructSTUtil(arr, ss, mid, si * 2 + 1);
            constructSTUtil(arr, mid + 1, se, si * 2 + 2);

            tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2];
        }

        void constructST(int arr[], int n) {
            // Fill the allocated memory st
            constructSTUtil(arr, 0, n - 1, 0);
        }

        public void main() {
            int arr[] = {1, 3, 5, 7, 9, 11};
            int n = arr.length;
            LazySegmentTree segTree = new LazySegmentTree();

            // Build segment tree from given array
            segTree.constructST(arr, n);

            // Print sum of values in array from index 1 to 3
            System.out.println("Sum of values in given range = "
                    + segTree.getSum(n, 1, 3));

            // Add 10 to all nodes at indexes from 1 to 5.
            segTree.updateRange(n, 1, 5, 10);

            // Find sum after the value is updated
            System.out.println("Updated sum of values in given range = "
                    + segTree.getSum(n, 1, 3));
        }
    }

    class SegmentTreeRMQ {

        int st[]; //array to store segment tree

        // A utility function to get minimum of two numbers
        int minVal(int x, int y) {
            return (x < y) ? x : y;
        }

        // A utility function to get the middle index from corner
        // indexes.
        int getMid(int s, int e) {
            return s + (e - s) / 2;
        }

        /*  A recursive function to get the minimum value in a given
        range of array indexes. The following are parameters for
        this function.

        st    --> Pointer to segment tree
        index --> Index of current node in the segment tree. Initially
                   0 is passed as root is always at index 0
        ss & se  --> Starting and ending indexes of the segment
                     represented by current node, i.e., st[index]
        qs & qe  --> Starting and ending indexes of query range */
        int RMQUtil(int ss, int se, int qs, int qe, int index) {
            // If segment of this node is a part of given range, then
            // return the min of the segment
            if (qs <= ss && qe >= se) {
                return st[index];
            }

            // If segment of this node is outside the given range
            if (se < qs || ss > qe) {
                return Integer.MAX_VALUE;
            }

            // If a part of this segment overlaps with the given range
            int mid = getMid(ss, se);
            return minVal(RMQUtil(ss, mid, qs, qe, 2 * index + 1),
                    RMQUtil(mid + 1, se, qs, qe, 2 * index + 2));
        }

        // Return minimum of elements in range from index qs (quey
        // start) to qe (query end).  It mainly uses RMQUtil()
        int RMQ(int n, int qs, int qe) {
            // Check for erroneous input values
            if (qs < 0 || qe > n - 1 || qs > qe) {
                System.out.println("Invalid Input");
                return -1;
            }

            return RMQUtil(0, n - 1, qs, qe, 0);
        }

        // A recursive function that constructs Segment Tree for
        // array[ss..se]. si is index of current node in segment tree st
        int constructSTUtil(int arr[], int ss, int se, int si) {
            // If there is one element in array, store it in current
            //  node of segment tree and return
            if (ss == se) {
                st[si] = arr[ss];
                return arr[ss];
            }

            // If there are more than one elements, then recur for left and
            // right subtrees and store the minimum of two values in this node
            int mid = getMid(ss, se);
            st[si] = minVal(constructSTUtil(arr, ss, mid, si * 2 + 1),
                    constructSTUtil(arr, mid + 1, se, si * 2 + 2));
            return st[si];
        }

        /* Function to construct segment tree from given array. This function
       allocates memory for segment tree and calls constructSTUtil() to
       fill the allocated memory */
        void constructST(int arr[], int n) {
            // Allocate memory for segment tree

            //Height of segment tree
            int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));

            //Maximum size of segment tree
            int max_size = 2 * (int) Math.pow(2, x) - 1;
            st = new int[max_size]; // allocate memory

            // Fill the allocated memory st
            constructSTUtil(arr, 0, n - 1, 0);
        }

        // Driver program to test above functions
        public void main(String args[]) {
            int arr[] = {1, 3, 2, 7, 9, 11};
            int n = arr.length;
            SegmentTreeRMQ tree = new SegmentTreeRMQ();

            // Build segment tree from given array
            tree.constructST(arr, n);

            int qs = 1;  // Starting index of query range
            int qe = 5;  // Ending index of query range

            // Print minimum value in arr[qs..qe]
            System.out.println("Minimum of values in range [" + qs + ", "
                    + qe + "] is = " + tree.RMQ(n, qs, qe));
        }
    }

    class DisjointUnionSets {

        int[] rank, parent;
        int n;

        // Constructor
        public DisjointUnionSets(int n) {
            rank = new int[n];
            parent = new int[n];
            this.n = n;
            makeSet();
        }

        // Creates n sets with single item in each
        void makeSet() {
            for (int i = 0; i < n; i++) {
                // Initially, all elements are in
                // their own set.
                parent[i] = i;
            }
        }

        // Returns representative of x's set
        int find(int x) {
            // Finds the representative of the set
            // that x is an element of
            if (parent[x] != x) {
                // if x is not the parent of itself
                // Then x is not the representative of
                // his set,
                parent[x] = find(parent[x]);

                // so we recursively call Find on its parent
                // and move i's node directly under the
                // representative of this set
            }

            return parent[x];
        }

        // Unites the set that includes x and the set
        // that includes x
        void union(int x, int y) {
            // Find representatives of two sets
            int xRoot = find(x), yRoot = find(y);

            // Elements are in the same set, no need
            // to unite anything.
            if (xRoot == yRoot) {
                return;
            }

            // If x's rank is less than y's rank
            if (rank[xRoot] < rank[yRoot]) // Then move x under y  so that depth
            // of tree remains less
            {
                parent[xRoot] = yRoot;
            } // Else if y's rank is less than x's rank
            else if (rank[yRoot] < rank[xRoot]) // Then move y under x so that depth of
            // tree remains less
            {
                parent[yRoot] = xRoot;
            } else // if ranks are the same
            {
                // Then move y under x (doesn't matter
                // which one goes where)
                parent[yRoot] = xRoot;

                // And increment the the result tree's
                // rank by 1
                rank[xRoot] = rank[xRoot] + 1;
            }
        }
    }
}


//Level 5
import java.util.*;
import java.io.*;
import java.math.*;

   public class E
   {
      public static void main(String hi[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int T = Integer.parseInt(st.nextToken());
         StringBuilder sb = new StringBuilder();
         while(T-->0)
         {
            st = new StringTokenizer(infile.readLine());
            int N = Integer.parseInt(st.nextToken());
            int K = Integer.parseInt(st.nextToken());
            int[] px = readArr(N, infile, st);
            int[] py = readArr(N, infile, st);
            HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
            for(int i=0; i < N; i++)
            {
               if(!map.containsKey(px[i]))
                  map.put(px[i], 1);
               else
                  map.put(px[i], map.get(px[i])+1);
            }
            ArrayList<Point> ls = new ArrayList<Point>();
            for(int k: map.keySet())
               ls.add(new Point(k, map.get(k)));
            Collections.sort(ls);
            int M = ls.size();
            int[] psums = new int[M];
            psums[0] = ls.get(0).cnt;
            for(int i=1; i < M; i++)
               psums[i] = psums[i-1]+ls.get(i).cnt;
            int[] prefix = new int[M];
            int[] suffix = new int[M];
            for(int i=0; i < M; i++)
            {
               prefix[i] = suffix[i] = ls.get(i).cnt;
               if(i+1 < M && ls.get(i+1).x-ls.get(i).x <= K)
               {
                  int low = i+1;
                  int high = M-1;
                  while(low != high)
                  {
                     int mid = (low+high+1)/2;
                     if(ls.get(mid).x-ls.get(i).x <= K)
                        low = mid;
                     else
                        high = mid-1;
                  }
                  prefix[i] += psums[low]-psums[i];
               }
               if(i-1 >= 0 && ls.get(i).x-ls.get(i-1).x <= K)
               {
                  int high = i-1;
                  int low = 0;
                  while(low != high)
                  {
                     int mid = (low+high)/2;
                     if(ls.get(i).x-ls.get(mid).x <= K)
                        high = mid;
                     else
                        low = mid+1;
                  }
                  suffix[i] += psums[i-1];
                  if(low > 0)
                     suffix[i] -= psums[low-1];
               }
            }
            SegmentTree left = new SegmentTree(0, M+1);
            SegmentTree right = new SegmentTree(0, M+1);
            for(int i=0; i < M; i++)
            {
               left.update(i, suffix[i]);
               right.update(i, prefix[i]);
            }
            int res = 0;
            int dex = 0;
            for(int i=0; i < M; i++)
            {
               int temp = prefix[i];
               while(dex < M && ls.get(dex).x-ls.get(i).x <= K)
                  dex++;
               temp += Math.max(left.query(0, i-1), right.query(dex, M));
               res = Math.max(res, temp);
            }
            sb.append(res+"\n");
         }
         System.out.print(sb);
      }
      public static int[] readArr(int N, BufferedReader infile, StringTokenizer st) throws Exception
      {
         int[] arr = new int[N];
         st = new StringTokenizer(infile.readLine());
         for(int i=0; i < N; i++)
            arr[i] = Integer.parseInt(st.nextToken());
         return arr;
      }
   }
   class Point implements Comparable<Point>
   {
      public int x;
      public int cnt;

      public Point(int a, int b)
      {
         x = a;
         cnt = b;
      }
      public int compareTo(Point oth)
      {
         return x-oth.x;
      }
   }
   class SegmentTree
   {
      //range query, non lazy
      final int[] val;
      final int treeFrom;
      final int length;

      public SegmentTree(int treeFrom, int treeTo)
      {
         this.treeFrom = treeFrom;
         int length = treeTo - treeFrom + 1;
         int l;
         for (l = 0; (1 << l) < length; l++);
         val = new int[1 << (l + 1)];
         this.length = 1 << l;
      }
      public void update(int index, int delta)
      {
         //replaces value
         int node = index - treeFrom + length;
         val[node] = delta;
         for (node >>= 1; node > 0; node >>= 1)
           val[node] = comb(val[node << 1], val[(node << 1) + 1]);
      }
      public int query(int from, int to)
      {
         //inclusive bounds
         if (to < from)
            return 0; //0 or 1?
         from += length - treeFrom;
         to += length - treeFrom + 1;
         //0 or 1?
         int res = 0;
         for (; from + (from & -from) <= to; from += from & -from)
             res = comb(res, val[from / (from & -from)]);
         for (; to - (to & -to) >= from; to -= to & -to)
             res = comb(res, val[(to - (to & -to)) / (to & -to)]);
         return res;
      }
      public int comb(int a, int b)
      {
         //change this
         return Math.max(a,b);
      }
   }


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

public class E {
    private static void merge(int arr[], int l, int m, int r)
    {
        int i, j, k;
        int n1 = m - l + 1;
        int n2 = r - m;

        /* create temp arrays */
        int[] L = new int[n1];
        int[] R = new int[n2];

        /* Copy data to temp arrays L[] and R[] */
        for (i = 0; i < n1; i++)
            L[i] = arr[l + i];
        for (j = 0; j < n2; j++)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays back into arr[l..r]*/
        i = 0; // Initial index of first subarray
        j = 0; // Initial index of second subarray
        k = l; // Initial index of merged subarray
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            }
            else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

    /* Copy the remaining elements of L[], if there
       are any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

    /* Copy the remaining elements of R[], if there
       are any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    /* l is for left index and r is right index of the
       sub-array of arr to be sorted */
    private static void mergeSort(int arr[], int l, int r)
    {
        if (l < r) {
            // Same as (l+r)/2, but avoids overflow for
            // large l and h
            int m = l + (r - l) / 2;

            // Sort first and second halves
            mergeSort(arr, l, m);
            mergeSort(arr, m + 1, r);

            merge(arr, l, m, r);
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        // code goes here
        int t = nextInt(br);
        while (t-- > 0){
            int[] in = nextIntArray(br, 2);
            int n = in[0];
            int k = in[1];
            int[] x = nextIntArray(br, n);
            int[] y = nextIntArray(br, n);
            mergeSort(x, 0, n - 1);
            List<Pair<Integer, Integer>> list = new ArrayList<>();
            for(int i = 0; i < n; i++){
                int bs = x[i];
                int be = bs + k;
                int start = i;
                int end = n - 1;
                int pos = -1;
                while (start <= end){
                    int mid = start + (end - start)/2;
                    if(x[mid] < be){
                        start = mid + 1;
                        pos = mid;
                    } else if(x[mid] > be){
                        end = mid - 1;
                    } else {
                        start = mid + 1;
                        pos = mid;
                    }
                }
                int points = pos - i + 1;
                list.add(new Pair<>(pos, points));
            }
            int[] max = new int[n + 1];
            int current = 0;
            for(int i = list.size() - 1; i >= 0; i--){
                current = Math.max(list.get(i).second, current);
                max[i] = current;
            }
            int ans = 0;
            for(int i = 0; i < list.size(); i++){
                Pair<Integer, Integer> pair = list.get(i);
                ans = Math.max(ans, pair.second + max[pair.first + 1]);
            }
            sb.append(ans).append("\n");
        }
        System.out.print(sb.toString());
    }

    private static int nextInt(BufferedReader br) throws IOException{
        return Integer.parseInt(br.readLine());
    }

    private static int[] nextIntArray(BufferedReader br, int n) throws IOException{
        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = Integer.parseInt(st.nextToken());
        }
        return arr;
    }

    static class Pair<A, B>{
        A first;
        B second;
        public Pair(A first, B second){
            this.first = first;
            this.second = second;
        }
    }
}


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

public class E {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        // code goes here
        int t = nextInt(br);
        while (t-- > 0){
            int[] in = nextIntArray(br, 2);
            int n = in[0];
            int k = in[1];
            int[] x = nextIntArray(br, n);
            int[] y = nextIntArray(br, n);
            Arrays.sort(x);
            List<Pair<Integer, Integer>> list = new ArrayList<>();
            for(int i = 0; i < n; i++){
                int bs = x[i];
                int be = bs + k;
                int start = i;
                int end = n - 1;
                int pos = -1;
                while (start <= end){
                    int mid = start + (end - start)/2;
                    if(x[mid] < be){
                        start = mid + 1;
                        pos = mid;
                    } else if(x[mid] > be){
                        end = mid - 1;
                    } else {
                        start = mid + 1;
                        pos = mid;
                    }
                }
                int points = pos - i + 1;
                list.add(new Pair<>(pos, points));
            }
            int[] max = new int[n + 1];
            int current = 0;
            for(int i = list.size() - 1; i >= 0; i--){
                current = Math.max(list.get(i).second, current);
                max[i] = current;
            }
            int ans = 0;
            for(int i = 0; i < list.size(); i++){
                Pair<Integer, Integer> pair = list.get(i);
                ans = Math.max(ans, pair.second + max[pair.first + 1]);
            }
            sb.append(ans).append("\n");
        }
        System.out.print(sb.toString());
    }

    private static int nextInt(BufferedReader br) throws IOException{
        return Integer.parseInt(br.readLine());
    }

    private static int[] nextIntArray(BufferedReader br, int n) throws IOException{
        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = Integer.parseInt(st.nextToken());
        }
        return arr;
    }

    static class Pair<A, B>{
        A first;
        B second;
        public Pair(A first, B second){
            this.first = first;
            this.second = second;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int count = 1;
		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    Pair[] arr = new Pair[n];
		    input = br.readLine().trim().split(" ");
		    int[] xCoordinates = new int[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    for(int i = 0; i < n; i++){
		        int x = xCoordinates[i];
		        int y = yCoordinates[i];
		        arr[i] = new Pair(x, y);
		    }

		    out.println(maxPoints(arr, k));

		    if(count == 45)
		    {
		        System.out.println("input is ");
		        System.out.println(n + " " + k);
		        for(int i = 0; i < n; i++){
		            System.out.println(xCoordinates[i] + " , " + yCoordinates[i]);
		        }
		        System.out.println();
		    }
		    count++;
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Pair[] arr, int k)
	{
	    Arrays.sort(arr);
	    int n = arr.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            numPoints[i] = index - i;
        }
        SegmentTree segTree = new SegmentTree(numPoints);
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + segTree.getMax(index, n - 1));
        }
        return ans;
	}
	public static int binarySearch(Pair[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid].x > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}

class Pair implements Comparable<Pair>{
    int x;
    int y;

    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int compareTo(Pair p)
    {
        return this.x - p.x;
    }
}

class SegmentTree{
    private int[] tree;
    private int n;

    public SegmentTree(int[] arr)
    {
        this.n = arr.length;
        tree = new int[n];
        buildTree(0, 0, n - 1, arr);
    }
    public void buildTree(int treeNodeIndex, int start, int end, int[] arr)
    {
        if(start == end){
            tree[treeNodeIndex] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        buildTree(treeNodeIndex * 2, start, mid, arr);
        buildTree(treeNodeIndex * 2 + 1, mid + 1, end, arr);
        tree[treeNodeIndex] = Math.max(tree[treeNodeIndex * 2], tree[treeNodeIndex * 2 + 1]);
    }
    public int getMax(int l, int r)
    {
        return getMaxHelper(0, 0, n - 1, l, r);
    }
    public int getMaxHelper(int treeNodeIndex, int nodeStart, int nodeEnd, int queryStart, int queryEnd)
    {
        if(nodeEnd < queryStart || nodeStart > queryEnd)
        {
            // no overlap
            return Integer.MIN_VALUE;
        }
        else if(nodeStart >= queryStart && nodeEnd <= queryEnd)
        {
            // complete overlap
            return tree[treeNodeIndex];
        }
        else{
            // partial overlap
            int mid = (nodeStart + nodeEnd) / 2;
            int leftAns = getMaxHelper(treeNodeIndex * 2, nodeStart, mid, queryStart, queryEnd);
            int rightAns = getMaxHelper(treeNodeIndex * 2 + 1, mid + 1, nodeEnd, queryStart, queryEnd);
            int ans = Math.max(leftAns, rightAns);
            return ans;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    Pair[] arr = new Pair[n];
		    input = br.readLine().trim().split(" ");
		    int[] xCoordinates = new int[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    for(int i = 0; i < n; i++){
		        int x = xCoordinates[i];
		        int y = yCoordinates[i];
		        arr[i] = new Pair(x, y);
		    }

		    out.println(maxPoints(arr, k));
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Pair[] arr, int k)
	{
	    Arrays.sort(arr);
	    int n = arr.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            numPoints[i] = index - i;
        }
        SegmentTree segTree = new SegmentTree(numPoints);
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + segTree.getMax(index, n - 1));
        }
        return ans;
	}
	public static int binarySearch(Pair[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid].x > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}

class Pair implements Comparable<Pair>{
    int x;
    int y;

    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int compareTo(Pair p)
    {
        return this.x - p.x;
    }
}

class SegmentTree{
    private int[] tree;
    private int n;

    public SegmentTree(int[] arr)
    {
        this.n = arr.length;
        tree = new int[n];
        buildTree(0, 0, n - 1, arr);
    }
    public void buildTree(int treeNodeIndex, int start, int end, int[] arr)
    {
        if(start == end){
            tree[treeNodeIndex] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        buildTree(treeNodeIndex * 2, start, mid, arr);
        buildTree(treeNodeIndex * 2 + 1, mid + 1, end, arr);
        tree[treeNodeIndex] = Math.max(tree[treeNodeIndex * 2], tree[treeNodeIndex * 2 + 1]);
    }
    public int getMax(int l, int r)
    {
        return getMaxHelper(0, 0, n - 1, l, r);
    }
    public int getMaxHelper(int treeNodeIndex, int nodeStart, int nodeEnd, int queryStart, int queryEnd)
    {
        if(nodeEnd < queryStart || nodeStart > queryEnd)
        {
            // no overlap
            return Integer.MIN_VALUE;
        }
        else if(nodeStart >= queryStart && nodeEnd <= queryEnd)
        {
            return tree[treeNodeIndex];
        }
        else{
            int mid = (nodeStart + nodeEnd) / 2;
            int leftAns = getMaxHelper(treeNodeIndex * 2, nodeStart, mid, queryStart, queryEnd);
            int rightAns = getMaxHelper(treeNodeIndex * 2 + 1, mid + 1, nodeEnd, queryStart, queryEnd);
            int ans = Math.max(leftAns, rightAns);
            return ans;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int count = 1;
		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    Pair[] arr = new Pair[n];
		    input = br.readLine().trim().split(" ");
		    int[] xCoordinates = new int[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    for(int i = 0; i < n; i++){
		        int x = xCoordinates[i];
		        int y = yCoordinates[i];
		        arr[i] = new Pair(x, y);
		    }

		    out.println(maxPoints(arr, k));

		    if(count == 45)
		    {
		        out.println("input is ");
		        out.println(n + " " + k);
		        for(int i = 0; i < n; i++){
		            out.print(xCoordinates[i] + " , " + yCoordinates[i]);
		        }
		        out.println();
		    }
		    count++;
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Pair[] arr, int k)
	{
	    Arrays.sort(arr);
	    int n = arr.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            numPoints[i] = index - i;
        }
        SegmentTree segTree = new SegmentTree(numPoints);
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + segTree.getMax(index, n - 1));
        }
        return ans;
	}
	public static int binarySearch(Pair[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid].x > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}

class Pair implements Comparable<Pair>{
    int x;
    int y;

    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int compareTo(Pair p)
    {
        return this.x - p.x;
    }
}

class SegmentTree{
    private int[] tree;
    private int n;

    public SegmentTree(int[] arr)
    {
        this.n = arr.length;
        tree = new int[n];
        buildTree(0, 0, n - 1, arr);
    }
    public void buildTree(int treeNodeIndex, int start, int end, int[] arr)
    {
        if(start == end){
            tree[treeNodeIndex] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        buildTree(treeNodeIndex * 2, start, mid, arr);
        buildTree(treeNodeIndex * 2 + 1, mid + 1, end, arr);
        tree[treeNodeIndex] = Math.max(tree[treeNodeIndex * 2], tree[treeNodeIndex * 2 + 1]);
    }
    public int getMax(int l, int r)
    {
        return getMaxHelper(0, 0, n - 1, l, r);
    }
    public int getMaxHelper(int treeNodeIndex, int nodeStart, int nodeEnd, int queryStart, int queryEnd)
    {
        if(nodeEnd < queryStart || nodeStart > queryEnd)
        {
            // no overlap
            return Integer.MIN_VALUE;
        }
        else if(nodeStart >= queryStart && nodeEnd <= queryEnd)
        {
            // complete overlap
            return tree[treeNodeIndex];
        }
        else{
            // partial overlap
            int mid = (nodeStart + nodeEnd) / 2;
            int leftAns = getMaxHelper(treeNodeIndex * 2, nodeStart, mid, queryStart, queryEnd);
            int rightAns = getMaxHelper(treeNodeIndex * 2 + 1, mid + 1, nodeEnd, queryStart, queryEnd);
            int ans = Math.max(leftAns, rightAns);
            return ans;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    Pair[] arr = new Pair[n];
		    input = br.readLine().trim().split(" ");
		    int[] xCoordinates = new int[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    for(int i = 0; i < n; i++){
		        int x = xCoordinates[i];
		        int y = yCoordinates[i];
		        arr[i] = new Pair(x, y);
		    }

		    out.println(maxPoints(arr, k));
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Pair[] arr, int k)
	{
	    Arrays.sort(arr);
	    int n = arr.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            numPoints[i] = index - i;
        }
        SegmentTree segTree = new SegmentTree(numPoints);
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + segTree.getMax(index, n - 1));
        }
        return ans;
	}
	public static int binarySearch(Pair[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid].x > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}

class Pair implements Comparable<Pair>{
    int x;
    int y;

    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int compareTo(Pair p)
    {
        return this.x - p.x;
    }
}

class SegmentTree{
    private int[] tree;
    private int n;

    public SegmentTree(int[] arr)
    {
        this.n = arr.length;
        tree = new int[4 * n + 1];
        buildTree(0, 0, n - 1, arr);
    }
    public void buildTree(int treeNodeIndex, int start, int end, int[] arr)
    {
        if(start == end){
            tree[treeNodeIndex] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        buildTree(treeNodeIndex * 2 + 1, start, mid, arr);
        buildTree(treeNodeIndex * 2 + 2, mid + 1, end, arr);
        tree[treeNodeIndex] = Math.max(tree[treeNodeIndex * 2 + 1], tree[treeNodeIndex * 2 + 2]);
    }
    public int getMax(int l, int r)
    {
        return getMaxHelper(0, 0, n - 1, l, r);
    }
    public int getMaxHelper(int treeNodeIndex, int nodeStart, int nodeEnd, int queryStart, int queryEnd)
    {
        if(nodeEnd < queryStart || nodeStart > queryEnd)
        {
            // no overlap
            return Integer.MIN_VALUE;
        }
        else if(nodeStart >= queryStart && nodeEnd <= queryEnd)
        {
            // complete overlap
            return tree[treeNodeIndex];
        }
        else{
            // partial overlap
            int mid = (nodeStart + nodeEnd) / 2;
            int leftAns = getMaxHelper(treeNodeIndex * 2 + 1, nodeStart, mid, queryStart, queryEnd);
            int rightAns = getMaxHelper(treeNodeIndex * 2 + 2, mid + 1, nodeEnd, queryStart, queryEnd);
            int ans = Math.max(leftAns, rightAns);
            return ans;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int count = 1;
		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    Pair[] arr = new Pair[n];
		    input = br.readLine().trim().split(" ");
		    int[] xCoordinates = new int[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    for(int i = 0; i < n; i++){
		        int x = xCoordinates[i];
		        int y = yCoordinates[i];
		        arr[i] = new Pair(x, y);
		    }

		    out.println(maxPoints(arr, k));

		    if(count == 45)
		    {
		        System.out.println("input is ");
		        System.out.println(n + " " + k);
		        for(int i = 0; i < n; i++){
		            System.out.print(xCoordinates[i] + " , " + yCoordinates[i]);
		        }
		        System.out.println();
		    }
		    count++;
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Pair[] arr, int k)
	{
	    Arrays.sort(arr);
	    int n = arr.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            numPoints[i] = index - i;
        }
        SegmentTree segTree = new SegmentTree(numPoints);
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(arr, i + 1, arr[i].x + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + segTree.getMax(index, n - 1));
        }
        return ans;
	}
	public static int binarySearch(Pair[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid].x > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}

class Pair implements Comparable<Pair>{
    int x;
    int y;

    public Pair(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public int compareTo(Pair p)
    {
        return this.x - p.x;
    }
}

class SegmentTree{
    private int[] tree;
    private int n;

    public SegmentTree(int[] arr)
    {
        this.n = arr.length;
        tree = new int[n];
        buildTree(0, 0, n - 1, arr);
    }
    public void buildTree(int treeNodeIndex, int start, int end, int[] arr)
    {
        if(start == end){
            tree[treeNodeIndex] = arr[start];
            return;
        }
        int mid = (start + end) / 2;
        buildTree(treeNodeIndex * 2, start, mid, arr);
        buildTree(treeNodeIndex * 2 + 1, mid + 1, end, arr);
        tree[treeNodeIndex] = Math.max(tree[treeNodeIndex * 2], tree[treeNodeIndex * 2 + 1]);
    }
    public int getMax(int l, int r)
    {
        return getMaxHelper(0, 0, n - 1, l, r);
    }
    public int getMaxHelper(int treeNodeIndex, int nodeStart, int nodeEnd, int queryStart, int queryEnd)
    {
        if(nodeEnd < queryStart || nodeStart > queryEnd)
        {
            // no overlap
            return Integer.MIN_VALUE;
        }
        else if(nodeStart >= queryStart && nodeEnd <= queryEnd)
        {
            // complete overlap
            return tree[treeNodeIndex];
        }
        else{
            // partial overlap
            int mid = (nodeStart + nodeEnd) / 2;
            int leftAns = getMaxHelper(treeNodeIndex * 2, nodeStart, mid, queryStart, queryEnd);
            int rightAns = getMaxHelper(treeNodeIndex * 2 + 1, mid + 1, nodeEnd, queryStart, queryEnd);
            int ans = Math.max(leftAns, rightAns);
            return ans;
        }
    }
}


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

public class Solution{
	static PrintWriter out=new PrintWriter(System.out);
	public static void main (String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		String[] input=br.readLine().trim().split(" ");

		int numTestCases=Integer.parseInt(input[0]);
		while(numTestCases-->0){
		    input=br.readLine().trim().split(" ");
		    int n = Integer.parseInt(input[0]);
		    int k = Integer.parseInt(input[1]);
		    input = br.readLine().trim().split(" ");
		    Integer[] xCoordinates = new Integer[n];
		    int[] yCoordinates = new int[n];
		    for(int i = 0; i < n; i++){
		        xCoordinates[i] = Integer.parseInt(input[i]);
		    }
		    input = br.readLine().trim().split(" ");
		    for(int i = 0; i < n; i++){
		        yCoordinates[i] = Integer.parseInt(input[i]);
		    }

		    out.println(maxPoints(xCoordinates, k));
		}

		out.flush();
		out.close();
	}
	public static int maxPoints(Integer[] xCoordinates, int k)
	{
	    Arrays.sort(xCoordinates);
	    int n = xCoordinates.length;
        int[] numPoints = new int[n];
        for(int i = 0; i < n; i++){
            int index = binarySearch(xCoordinates, i + 1, xCoordinates[i] + k);
            numPoints[i] = index - i;
        }
        int[] max = new int[n];
        max[n - 1] = numPoints[n - 1];
        for(int i = n - 2; i >= 0; i--){
            max[i] = Math.max(max[i + 1], numPoints[i]);
        }
        int ans = 0;
        for(int  i = 0; i < n; i++){
            int index = binarySearch(xCoordinates, i + 1, xCoordinates[i] + k);
            if(index >= n)
            {
                ans = Math.max(ans, numPoints[i]);
            }
            else ans = Math.max(ans, numPoints[i] + max[index]);
        }
        return ans;
	}
	public static int binarySearch(Integer[] arr, int start, int value)
	{
	    int n = arr.length;
	    int end = n - 1;
	    int ans = n;
	    while(start <= end)
	    {
	        int mid = (start + end) / 2;
	        if(arr[mid] > value)
	        {
	            ans = mid;
	            end = mid - 1;
	        }
	        else{
	            start = mid + 1;
	        }
	    }
	    return ans;
	}
}


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

public class Main {
    static PrintWriter out;
    static Reader in;
    public static void main(String[] args) throws IOException {
        //out = new PrintWriter(new File("out.txt"));
        //PrintWriter out = new PrintWriter(System.out);
        //in = new Reader(new FileInputStream("in.txt"));
        //Reader in = new Reader();
        input_output();
        Main solver = new Main();
        solver.solve();
        out.flush();
        out.close();

    }

    static int INF = (int)1e9;
    static int maxn = 1000;
    static int mod=(int)1e9+7 ;
    static int n, m, q, k, t;

    void solve() throws IOException{
        t = in.nextInt();

        while (t --> 0) {
            n = in.nextInt();
            k = in.nextInt();

            ArrayList<Integer> arr = new ArrayList<>();
            for (int i = 0; i < n; i++) arr.add(in.nextInt());
            for (int i = 0; i < n; i++) in.nextInt();

            Collections.sort(arr);
            TreeSet<Integer> set = new TreeSet<Integer>();
            Map<Integer, Integer> id_num = new HashMap<>();
            Map<Integer, Integer> num_id = new HashMap<>();

            int c = 0;
            id_num.put(c, arr.get(0));
            num_id.put(arr.get(0), c);
            set.add(arr.get(0));

            for (int i = 1; i < n; i++) {
                if (arr.get(i) != arr.get(i-1)) {
                    c++;
                    id_num.put(c, arr.get(i));
                    num_id.put(arr.get(i), c);
                    set.add(arr.get(i));
                }
            }

            int[] cnt = new int[c+1];
            for (int i = 0; i < n; i++)
                cnt[num_id.get(arr.get(i))]++;
            for (int i = 1 ; i <= c; i++) cnt[i] += cnt[i-1];

            set.add(2000000000);
            int[] dp = new int[c+1];
            if (c != 0) dp[c] = cnt[c]-cnt[c-1];
            else dp[c] = cnt[c];
            int ans = dp[c];

            int high = 0, tmp = 0, highId = 0;
            for (int i = c-1; i >= 0; i--) {
                high = set.higher(id_num.get(i)+k);
                if (high == 2000000000) highId = c+1;
                else highId = num_id.get(high);

                tmp = cnt[highId-1];
                if (i != 0) tmp -= cnt[i-1];
                dp[i] = Math.max(tmp, dp[i+1]);
                if (highId != c+1) tmp += dp[highId];
                ans = Math.max(tmp, ans);
            }
            out.println(ans);
        }
    }

    //<>

    static class Reader {

        private InputStream mIs;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public Reader() {
            this(System.in);
        }

        public Reader(InputStream is) {
            mIs = is;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();

        }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = mIs.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public String nextLine() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

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

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

    }
    static void input_output() throws IOException {
        File f = new File("in.txt");
        if(f.exists() && !f.isDirectory()) {
            in = new Reader(new FileInputStream("in.txt"));
        } else in = new Reader();
        f = new File("out.txt");
        if(f.exists() && !f.isDirectory()) {
            out = new PrintWriter(new File("out.txt"));
        } else out = new PrintWriter(System.out);
    }
}


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

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

    static class TaskE {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int T = in.nextInt();
            while (T-- > 0) {
                int n = in.nextInt();
                int k = in.nextInt();
                int[] x = in.nextIntArray(n);
                int[] y = in.nextIntArray(n);
                ArrayUtils.mergeSort(x);
                int p1 = 0;
                int p2 = 0;
                int[] cover = new int[n];
                while (p1 < n) {
                    int left = x[p1];
                    while (p2 + 1 < n && x[p2 + 1] - left <= k) ++p2;
                    cover[p1] = p2;
                    ++p1;
                }
                int[] maxBehind = new int[n + 1];
                for (int i = n - 1; i >= 0; --i) {
                    maxBehind[i] = Math.max(maxBehind[i + 1], cover[i] - i + 1);
                }
                int best = 0;
                //for (int i = 0; i < n; ++i) Utils.pf("%d", x[i]);

                for (int i = 0; i < n; ++i) {
                    //Utils.pf("cover[%d] = %d, maxBehind[%d] = %d", i, cover[i], i, maxBehind[i]);
                    best = Math.max(best, cover[i] - i + 1 + ((cover[i] + 1 < n) ? maxBehind[cover[i] + 1] : 0));
                }
                out.println(best);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer = new StringTokenizer("");

        public InputReader(InputStream inputStream) {
            this.reader = new BufferedReader(
                    new InputStreamReader(inputStream));
        }

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

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

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

    }

    static class ArrayUtils {
        public static void mergeSort(int[] a) {
            mergeSort(a, 0, a.length);
        }

        public static void mergeSort(int[] a, int l, int r) {
            if (l + 1 < r) {
                // Find the middle point
                int m = (l + r) / 2;

                // Sort first and second halves
                mergeSort(a, l, m);
                mergeSort(a, m, r);

                // Merge the sorted halves
                merge(a, l, m, r);
            }
        }

        public static void merge(int arr[], int l, int m, int r) {
            // Find sizes of two subarrays to be merged
            int n1 = m - l;
            int n2 = r - m;

            /* Create temp arrays */
            int L[] = new int[n1];
            int R[] = new int[n2];

            /*Copy data to temp arrays*/
            for (int i = 0; i < n1; ++i)
                L[i] = arr[l + i];
            for (int j = 0; j < n2; ++j)
                R[j] = arr[m + j];

            int i = 0, j = 0;

            // Initial index of merged subarry array
            int k = l;
            while (i < n1 && j < n2) {
                if (L[i] <= R[j]) {
                    arr[k] = L[i];
                    i++;
                } else {
                    arr[k] = R[j];
                    j++;
                }
                k++;
            }

            /* Copy remaining elements of L[] if any */
            while (i < n1) {
                arr[k] = L[i];
                i++;
                k++;
            }

            /* Copy remaining elements of R[] if any */
            while (j < n2) {
                arr[k] = R[j];
                j++;
                k++;
            }
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.StringTokenizer;

/*

1
1 1
5
5

1
7 1
1 5 2 3 1 5 4
1 3 6 7 2 5 4

 */
public class E {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int T=fs.nextInt();
		PrintWriter out=new PrintWriter(System.out);
		for (int tt=0; tt<T; tt++) {
			int nPoints=fs.nextInt(), length=fs.nextInt();
			ArrayList<Event> events1=new ArrayList<>();
			ArrayList<Event> events2=new ArrayList<>();

			int[] xs=fs.readArray(nPoints);
			for (int i=0; i<xs.length; i++) xs[i]*=2;
			length*=2;
			fs.readArray(nPoints);
			HashSet<Integer> interesting=new HashSet<>();
			for (int i:xs) {
				events1.add(new Event(i, 1));
				events1.add(new Event(i+length, -1));
				events2.add(new Event(i-length, -1));
				events2.add(new Event(i, 1));
				interesting.add(i-length);
				interesting.add(i);
				interesting.add(i+length);
			}
			for (int i:interesting) {
				events1.add(new Event(i+1, 0));
				events1.add(new Event(i-1, 0));
				events2.add(new Event(i+1, 0));
				events2.add(new Event(i-1, 0));
			}

			HashMap<Integer, Integer> m1=go(events1);
			HashMap<Integer, Integer> m2=go2(events2);
			int ans=0;
			for (int i:m1.keySet()) {
//				System.out.println("For i: "+i+" "+m1.get(i)+" "+m2.get(i));
				ans=Math.max(m1.get(i)+m2.get(i), ans);
			}
			out.println(ans);
		}
		out.close();
	}

	static HashMap<Integer, Integer> go(ArrayList<Event> events) {
		HashMap<Integer, Integer> res=new HashMap<>();
		Collections.sort(events);
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.put(e.x, bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static HashMap<Integer, Integer> go2(ArrayList<Event> events) {
		HashMap<Integer, Integer> res=new HashMap<>();
		for (Event e:events) e.x*=-1;
		Collections.sort(events);
		for (Event e:events) e.x*=-1;
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.put(e.x, bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static class Event implements Comparable<Event> {
		int x, d;//0 if query
		public Event(int x, int d) {
			this.x=x;
			this.d=d;
		}

		public int compareTo(Event o) {
			if (x!=o.x)return Integer.compare(x, o.x);
			return Integer.compare(o.d, d);
		}
	}

	static final Random random=new Random();

	static void ruffleSort(int[] a) {
		int n=a.length;//shuffle, then sort
		for (int i=0; i<n; i++) {
			int oi=random.nextInt(n), temp=a[oi];
			a[oi]=a[i]; a[i]=temp;
		}
		Arrays.sort(a);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.StringTokenizer;

/*

1
1 1
5
5

1
7 1
1 5 2 3 1 5 4
1 3 6 7 2 5 4

 */
public class E {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int T=fs.nextInt();
		for (int tt=0; tt<T; tt++) {
			int nPoints=fs.nextInt(), length=fs.nextInt();
			ArrayList<Event> events1=new ArrayList<>();
			ArrayList<Event> events2=new ArrayList<>();

			int[] xs=fs.readArray(nPoints);
			for (int i=0; i<xs.length; i++) xs[i]*=2;
			length*=2;
			fs.readArray(nPoints);
			HashSet<Integer> interesting=new HashSet<>();
			for (int i:xs) {
				events1.add(new Event(i, 1));
				events1.add(new Event(i+length, -1));
				events2.add(new Event(i-length, -1));
				events2.add(new Event(i, 1));
				interesting.add(i-length);
				interesting.add(i);
				interesting.add(i+length);
			}
			for (int i:interesting) {
				events1.add(new Event(i+1, 0));
				events1.add(new Event(i-1, 0));
				events2.add(new Event(i+1, 0));
				events2.add(new Event(i-1, 0));
			}

			HashMap<Integer, Integer> m1=go(events1);
			HashMap<Integer, Integer> m2=go2(events2);
			int ans=0;
			for (int i:m1.keySet()) {
//				System.out.println("For i: "+i+" "+m1.get(i)+" "+m2.get(i));
				ans=Math.max(m1.get(i)+m2.get(i), ans);
			}
			System.out.println(ans);
		}
	}

	static HashMap<Integer, Integer> go(ArrayList<Event> events) {
		HashMap<Integer, Integer> res=new HashMap<>();
		Collections.sort(events);
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.put(e.x, bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static HashMap<Integer, Integer> go2(ArrayList<Event> events) {
		HashMap<Integer, Integer> res=new HashMap<>();
		for (Event e:events) e.x*=-1;
		Collections.sort(events);
		for (Event e:events) e.x*=-1;
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.put(e.x, bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static class Event implements Comparable<Event> {
		int x, d;//0 if query
		public Event(int x, int d) {
			this.x=x;
			this.d=d;
		}

		public int compareTo(Event o) {
			if (x!=o.x)return Integer.compare(x, o.x);
			return Integer.compare(o.d, d);
		}
	}

	static final Random random=new Random();

	static void ruffleSort(int[] a) {
		int n=a.length;//shuffle, then sort
		for (int i=0; i<n; i++) {
			int oi=random.nextInt(n), temp=a[oi];
			a[oi]=a[i]; a[i]=temp;
		}
		Arrays.sort(a);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.StringTokenizer;

/*

1
1 1
5
5

1
7 1
1 5 2 3 1 5 4
1 3 6 7 2 5 4

 */
public class E {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int T=fs.nextInt();
		PrintWriter out=new PrintWriter(System.out);
		for (int tt=0; tt<T; tt++) {
			int nPoints=fs.nextInt(), length=fs.nextInt();
			ArrayList<Event> events1=new ArrayList<>();
			ArrayList<Event> events2=new ArrayList<>();

			int[] xs=fs.readArray(nPoints);
			for (int i=0; i<xs.length; i++) xs[i]*=2;
			length*=2;
			fs.readArray(nPoints);
			for (int i:xs) {
				events1.add(new Event(i, 1));
				events1.add(new Event(i+length, -1));
				events2.add(new Event(i-length, -1));
				events2.add(new Event(i, 1));

				events1.add(new Event(i-length+1, 0));
				events1.add(new Event(i+1, 0));
				events1.add(new Event(i+length+1, 0));
				events1.add(new Event(i-length-1, 0));
				events1.add(new Event(i-1, 0));
				events1.add(new Event(i+length-1, 0));

				events2.add(new Event(i-length+1, 0));
				events2.add(new Event(i+1, 0));
				events2.add(new Event(i+length+1, 0));
				events2.add(new Event(i-length-1, 0));
				events2.add(new Event(i-1, 0));
				events2.add(new Event(i+length-1, 0));
			}

			ArrayList<Integer> m1=go(events1);
			ArrayList<Integer> m2=go2(events2);
			if (m1.size()!=m2.size()) throw null;
			int ans=0;
			for (int i=0; i<m1.size(); i++)
				ans=Math.max(m1.get(i)+m2.get(m2.size()-1-i), ans);
			out.println(ans);
		}
		out.close();
	}

	static ArrayList<Integer> go(ArrayList<Event> events) {
		ArrayList<Integer> res=new ArrayList<>();
		Collections.sort(events);
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.add(bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static ArrayList<Integer> go2(ArrayList<Event> events) {
		ArrayList<Integer> res=new ArrayList<>();
		for (Event e:events) e.x*=-1;
		Collections.sort(events);
		for (Event e:events) e.x*=-1;
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.add(bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static class Event implements Comparable<Event> {
		int x, d;//0 if query
		public Event(int x, int d) {
			this.x=x;
			this.d=d;
		}

		public int compareTo(Event o) {
			if (x!=o.x)return Integer.compare(x, o.x);
			return Integer.compare(o.d, d);
		}
	}

	static final Random random=new Random();

	static void ruffleSort(int[] a) {
		int n=a.length;//shuffle, then sort
		for (int i=0; i<n; i++) {
			int oi=random.nextInt(n), temp=a[oi];
			a[oi]=a[i]; a[i]=temp;
		}
		Arrays.sort(a);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.StringTokenizer;

/*

1
1 1
5
5

1
7 1
1 5 2 3 1 5 4
1 3 6 7 2 5 4

 */
public class E {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int T=fs.nextInt();
		PrintWriter out=new PrintWriter(System.out);
		for (int tt=0; tt<T; tt++) {
			int nPoints=fs.nextInt(), length=fs.nextInt();
			ArrayList<Event> events1=new ArrayList<>();
			ArrayList<Event> events2=new ArrayList<>();

			int[] xs=fs.readArray(nPoints);
			for (int i=0; i<xs.length; i++) xs[i]*=2;
			length*=2;
			fs.readArray(nPoints);
			HashSet<Integer> interesting=new HashSet<>();
			for (int i:xs) {
				events1.add(new Event(i, 1));
				events1.add(new Event(i+length, -1));
				events2.add(new Event(i-length, -1));
				events2.add(new Event(i, 1));
				interesting.add(i-length);
				interesting.add(i);
				interesting.add(i+length);
			}
			for (int i:interesting) {
				events1.add(new Event(i+1, 0));
				events1.add(new Event(i-1, 0));
				events2.add(new Event(i+1, 0));
				events2.add(new Event(i-1, 0));
			}

			ArrayList<Integer> m1=go(events1);
			ArrayList<Integer> m2=go2(events2);
			if (m1.size()!=m2.size()) throw null;
			int ans=0;
			for (int i=0; i<m1.size(); i++)
				ans=Math.max(m1.get(i)+m2.get(m2.size()-1-i), ans);
			out.println(ans);
		}
		out.close();
	}

	static ArrayList<Integer> go(ArrayList<Event> events) {
		ArrayList<Integer> res=new ArrayList<>();
		Collections.sort(events);
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.add(bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static ArrayList<Integer> go2(ArrayList<Event> events) {
		ArrayList<Integer> res=new ArrayList<>();
		for (Event e:events) e.x*=-1;
		Collections.sort(events);
		for (Event e:events) e.x*=-1;
		int bestSeen=0;
		int curIntersect=0;
		for (Event e:events) {
			if (e.d==0) res.add(bestSeen);
			curIntersect+=e.d;
			bestSeen=Math.max(bestSeen, curIntersect);
		}
		return res;
	}

	static class Event implements Comparable<Event> {
		int x, d;//0 if query
		public Event(int x, int d) {
			this.x=x;
			this.d=d;
		}

		public int compareTo(Event o) {
			if (x!=o.x)return Integer.compare(x, o.x);
			return Integer.compare(o.d, d);
		}
	}

	static final Random random=new Random();

	static void ruffleSort(int[] a) {
		int n=a.length;//shuffle, then sort
		for (int i=0; i<n; i++) {
			int oi=random.nextInt(n), temp=a[oi];
			a[oi]=a[i]; a[i]=temp;
		}
		Arrays.sort(a);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}