On February 14 Denis decided to give Valentine to Nastya and did not come up with anything better than to draw a huge red heart on the door of the length k (k ≥ 3). Nastya was very confused by this present, so she decided to break the door, throwing it on the mountains.

Mountains are described by a sequence of heights a_1, a_2, ..., a_n in order from left to right (k ≤ n). It is guaranteed that neighboring heights are not equal to each other (that is, a_i ≠ a_{i+1} for all i from 1 to n-1).

Peaks of mountains on the segment [l,r] (from l to r) are called indexes i such that l < i < r, a_{i - 1} < a_i and a_i > a_{i + 1}. It is worth noting that the boundary indexes l and r for the segment are not peaks. For example, if n=8 and a=[3,1,4,1,5,9,2,6], then the segment [1,8] has only two peaks (with indexes 3 and 6), and there are no peaks on the segment [3, 6].

To break the door, Nastya throws it to a segment [l,l+k-1] of consecutive mountains of length k (1 ≤ l ≤ n-k+1). When the door touches the peaks of the mountains, it breaks into two parts, after that these parts will continue to fall in different halves and also break into pieces when touching the peaks of the mountains, and so on. Formally, the number of parts that the door will break into will be equal to p+1, where p is the number of peaks on the segment [l,l+k-1].

Nastya wants to break it into as many pieces as possible. Help her choose such a segment of mountains [l, l+k-1] that the number of peaks on it is maximum. If there are several optimal segments, Nastya wants to find one for which the value l is minimal.

Formally, you need to choose a segment of mountains [l, l+k-1] that has the maximum number of peaks. Among all such segments, you need to find the segment that has the minimum possible value l.

Input

The first line contains an integer t (1 ≤ t ≤ 10^4) — the number of test cases. Then the descriptions of the test cases follow.

The first line of each test case contains two integers n and k (3 ≤ k ≤ n ≤ 2 ⋅ 10^5) — the number of mountains and the length of the door.

The second line of the input data set contains n integers a_1, a_2, ..., a_n (0 ≤ a_i ≤ 10 ^ 9, a_i ≠ a_{i + 1}) — the heights of mountains.

It is guaranteed that the sum of n over all the test cases will not exceed 2 ⋅ 10^5.

Output

For each test case, output two integers t and l — the maximum number of parts that the door can split into, and the left border of the segment of length k that the door should be reset to.

Example

Input


5
8 6
1 2 4 1 2 4 1 2
5 3
3 2 3 2 1
10 4
4 3 4 3 2 3 2 1 0 1
15 7
3 7 4 8 2 3 4 5 21 2 3 4 2 1 3
7 5
1 2 3 4 5 6 1


Output


3 2
2 2
2 1
3 1
2 3

Note

In the first example, you need to select a segment of mountains from 2 to 7. In this segment, the indexes 3 and 6 are peaks, so the answer is 3 (only 2 peaks, so the door will break into 3 parts). It is not difficult to notice that the mountain segments [1, 6] and [3, 8] are not suitable since they only have a 1 peak (for the first segment, the 6 index is not a peak, and for the second segment, the 3 index is not a peak).

In the second example, you need to select a segment of mountains from 2 to 4. In this segment, the index 3 is a peak, so the answer is 2 (only 1 peak, so the door will break into 2 parts).

In the third example, you need to select a segment of mountains from 1 to 4. In this segment, the index 3 is a peak, so the answer is 2 (only 1 peak, so the door will break into 2 parts). You can see that on the segments [2, 5], [4, 7] and [5, 8] the number of peaks is also 1, but these segments have a left border greater than the segment [1, 4], so they are not the correct answer.
import java.util.*;
import java.io.*;
import java.util.function.*;
// import lib.util.*;
// import lib.graph.*;
// import lib.io.*;
// import lib.math.*;

public class Main {
    static long p = 1_000_000_007;

    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        // Scanner sc = new Scanner(System.in);
        // PrintWriter out = new PrintWriter(System.out);
        int t = sc.nextInt();
        loop: for (int sample = 0; sample < t; sample++) {
            int n = sc.nextInt();
            int k = sc.nextInt();
            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = sc.nextInt();
            }
            int[] peaks = new int[n];
            for (int i = 1; i < n - 1; i++) {
                peaks[i + 1] = peaks[i];
                if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
                    peaks[i + 1]++;
                }
            }
            int l = 1;
            int res = 1;
            for (int i = 0; i <= n - k; i++) {

                if (res < peaks[i + k - 1] - peaks[i + 1] + 1) {
                    res = peaks[i + k - 1] - peaks[i + 1] + 1;
                    l = i + 1;
                }
            }
            System.out.println(res + " " + l);
        }
    }

}

class UnionFindTree {
    int[] root;
    int[] rank;
    int[] size;
    int m;

    public UnionFindTree(int n) {
        this.root = new int[n];
        this.rank = new int[n];
        this.size = new int[n];
        this.m = n;
        for (int i = 0; i < n; i++) {
            root[i] = i;
            size[i] = 1;
        }
    }

    public int find(int x) {
        if (root[x] == x)
            return x;
        else {
            return root[x] = find(root[x]);
        }
    }

    public void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y)
            return;
        if (rank[x] < rank[y]) {
            size[find(y)] = size[find(x)];
            root[x] = y;
        } else {
            size[find(x)] = size[find(y)];
            root[y] = x;
            if (rank[x] == rank[y])
                rank[x]++;
        }
        m--;
    }

    public boolean same(int x, int y) {
        return find(x) == find(y);
    }

    public int size(int i) {
        return this.size[find(i)];
    }
}

class Dijkstra {
    private static int prev[];
    private static long dist[];

    public Dijkstra(AbstractGraph graph, int s) {
        prev = new int[graph.n];
        dist = new long[graph.n];
        Arrays.fill(prev, -1);
        Arrays.fill(dist, Long.MAX_VALUE);
        PriorityQueue<Integer> searching = new PriorityQueue<>((x, y) -> Long.compare(dist[x], dist[y]));
        dist[s] = 0;
        searching.add(s);
        while (searching.size() > 0) {
            int now = searching.poll();
            for (Edge e : graph.getEdges(now)) {
                int next = e.to;
                long c = e.cost;
                if (dist[now] + c < dist[next]) {
                    dist[next] = dist[now] + c;
                    prev[next] = now;
                    searching.add(next);
                }
            }
        }
    }

    public int[] path(int to) {
        ArrayList<Integer> rev = new ArrayList<>();
        for (int now = to; now != -1; now = this.prev[now]) {
            rev.add(now);
        }
        int[] path = new int[rev.size()];
        for (int i = 0; i < path.length; i++) {
            path[i] = rev.get(path.length - i - 1);
        }
        return path;
    }
}

class WF {
    private static long[][] dist;

    public WF(AbstractGraph graph) {
        dist = new long[graph.n][graph.n];
        for (int i = 0; i < dist.length; i++) {
            Arrays.fill(dist[i], Integer.MAX_VALUE);
        }
        for (int i = 0; i < graph.n; i++) {
            for (Edge e : graph.getEdges(i)) {
                dist[i][e.to] = e.cost;
            }
            dist[i][i] = 0;
        }
        for (int k = 0; k < graph.n; k++) {
            for (int i = 0; i < graph.n; i++) {
                for (int j = 0; j < graph.n; j++) {
                    if (dist[i][k] != Integer.MAX_VALUE && dist[k][j] != Integer.MAX_VALUE) {
                        dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
                    }
                }
            }
        }
    }

    public static long getShortest(int s, int t) {
        return dist[s][t];
    }

    public static long[][] getAllDist() {
        return dist;
    }

    public static boolean isNegativeLoop() {
        for (int i = 0; i < dist.length; i++) {
            if (dist[i][i] < 0) {
                return true;
            }
        }
        return false;
    }
}

class Edge {
    int from, to;
    long cost;

    public Edge(int from, int to, long cost) {
        this.from = from;
        this.to = to;
        this.cost = cost;
    }

    public Edge(int from, int to) {
        this.from = from;
        this.to = to;
        this.cost = 1;
    }

    public Edge reverse() {
        return new Edge(to, from, cost);
    }
}

@SuppressWarnings("unchecked")
abstract class AbstractGraph {
    int n;
    int m;
    ArrayList<Edge>[] edges;

    public AbstractGraph(int n) {
        this.n = n;
        this.m = 0;
        this.edges = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            this.edges[i] = new ArrayList<Edge>();
        }
    }

    public void addEdge(Edge e) {
        this.m++;
        this.edges[e.from].add(e);
    }

    public int getV() {
        return this.n;
    }

    public int getE() {
        return this.m;
    }

    public ArrayList<Edge> getEdges(int v) {
        return this.edges[v];
    }

    abstract public boolean isBipartite();

    public boolean isTree() {
        // require Modifying.
        return false;
    }
}

class Graph extends AbstractGraph {
    int n;
    int m;
    // array of edges which is connect to the node
    ArrayList<Edge>[] edges;

    public Graph(int n) {
        super(n);
    }

    public void addEdge(int from, int to, int cost) {
        Edge e = new Edge(from, to, cost);
        super.addEdge(e);
        super.addEdge(e.reverse());
        this.m++;
    }

    @Override
    public void addEdge(Edge e) {
        this.edges[e.from].add(e);
        this.edges[e.to].add(e.reverse());
        this.m++;
    }

    public int getV(int v) {
        return n;
    }

    public int getE() {
        return m;
    }

    public boolean isBipartite() {
        int[] color = new int[n];
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        HashSet<Integer> visited = new HashSet<>();
        queue.add(0);
        color[0] = 1;
        while (queue.size() > 0) {
            int now = queue.poll();
            visited.add(now);
            for (Edge e : getEdges(now)) {
                if (visited.contains(e.to)) {
                    continue;
                }
                if (color[e.to] == color[now])
                    return false;
                queue.add(e.to);
                if (color[e.to] == 0)
                    color[e.to] = -1 * color[now];
            }
        }
        return true;
    }
}

class DirectedGraph extends AbstractGraph {
    int n;
    int m;
    // array of edges which is connect to the node
    ArrayList<Edge>[] edges;

    public DirectedGraph(int n) {
        super(n);
    }

    public void addEdge(int from, int to, int cost) {
        Edge e = new Edge(from, to, cost);
        super.addEdge(e);
        this.m++;
    }

    @Override
    public void addEdge(Edge e) {
        this.edges[e.from].add(e);
        this.m++;
    }

    public int getV(int v) {
        return this.n;
    }

    public int getE() {
        return this.m;
    }

    public boolean isBipartite() {
        // need to rewrite to work
        return false;
    }

}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        } else {
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }

    private int readByte() {
        if (hasNextByte())
            return buffer[ptr++];
        else
            return -1;
    }

    private static boolean isPrintableChar(int c) {
        return 33 <= c && c <= 126;
    }

    public boolean hasNext() {
        while (hasNextByte() && !isPrintableChar(buffer[ptr]))
            ptr++;
        return hasNextByte();
    }

    public String next() {
        if (!hasNext())
            throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while (isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    public long nextLong() {
        if (!hasNext())
            throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while (true) {
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            } else if (b == -1 || !isPrintableChar(b)) {
                return minus ? -n : n;
            } else {
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }

    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
            throw new NumberFormatException();
        return (int) nl;
    }

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

class MyMath {
    public static long gcm(long a, long b) {

        // if (a < b)
        // return gcm(b, a);

        // if (b == 0 || a % b == 0)
        // return b;

        // return gcm(b, a % b);
        if (a < b) {
            long tmp = a;
            a = b;
            b = tmp;
        }
        long r = -1;
        while (r != 0) {
            r = a % b;
            a = b;
            b = r;
        }
        return a;
    }

    public static long summation(long a, long b) {
        return b * (b + 1) / 2 - a * (a - 1) / 2;
    }

    public static long factorial(long n) {

        if (n <= 1)
            return 1;
        else
            return factorial(n - 1) * n;
    }

    public static long[][] binomialTable(int a, long m) {
        long[][] table = new long[a + 1][a + 1];
        for (int i = 0; i < a + 1; i++) {
            table[0][a] = 0;
            table[i][0] = 1;
            table[i][i] = 1;
        }
        for (int i = 1; i < a + 1; i++) {
            for (int j = 1; j < a + 1; j++) {
                if (i < j)
                    table[i][j] = 0;
                else {
                    table[i][j] = (table[i - 1][j - 1] + table[i - 1][j]) % m;
                }
            }
        }
        return table;
    }

    public static long binomial(int n, int k, long m) {
        long res = 1;
        for (int l = n - k + 1; l <= n; l++) {
            res = (res % m) * (l % m) % m;
        }
        for (int r = 1; r <= k; r++) {
            res = (res % m) * modinv(r, m) % m;
        }
        return res;
    }

    public static long pow(long a, long n, long p) {
        if (n == 0)
            return 1;
        if (n == 1)
            return a % p;
        if (n % 2 == 1)
            return a * pow(a, n - 1, p) % p;
        long tmp = pow(a, n / 2, p) % p;
        return tmp * tmp % p;
    }

    public static long modinv(long a, long p) {
        long b, x, u, q, abs_p, tmp;
        abs_p = Math.abs(p);
        b = p;
        x = 1;
        u = 0;
        while (b > 0) {
            q = a / b;
            tmp = u;
            u = x - q * u;
            x = tmp;
            tmp = b;
            b = a - q * b;
            a = tmp;
        }
        return (x < 0) ? abs_p + x : x;
    }

    public static Long[] eratosthenes(int n) {
        Long[] factor_table = new Long[n];
        for (long i = 1; i <= n; i++) {
            factor_table[(int) (i - 1)] = i;
        }
        for (long i = 1; i <= n; i++) {
            if (factor_table[(int) (i - 1)] == i) {
                int j = 2;
                while (i * j <= n) {
                    factor_table[(int) (i * j - 1)] = i;
                    j++;
                }
            }
        }

        return factor_table;
    }

    public static HashMap<Long, Integer> primeFactorization(long n) {
        HashMap<Long, Integer> primes = new HashMap<>();
        for (long p = 2; p * p <= n; p++) {
            int q = 0;
            while (n % p == 0) {
                n /= p;
                q++;
            }
            if (q > 0)
                primes.put(p, q);
        }
        if (n > 1)
            primes.put(n, 1);
        return primes;
    }

    public static ArrayList<Integer> divisor(int n) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        for (int i = 1; i * i <= n; i++) {
            if (n % i == 0) {
                ret.add(i);
                // n=PQ+0→ PもQも約数. ただし、Q=Pは↑で登録済みなので登録しない
                if (i != n / i)
                    ret.add(n / i);
            }
        }
        return ret;
    }
}

class nextPermutation {
    public static int[] swap(int data[], int left, int right) {

        // Swap the data
        int temp = data[left];
        data[left] = data[right];
        data[right] = temp;

        // Return the updated array
        return data;
    }

    // Function to reverse the sub-array
    // starting from left to the right
    // both inclusive
    public static int[] reverse(int data[], int left, int right) {

        // Reverse the sub-array
        while (left < right) {
            int temp = data[left];
            data[left++] = data[right];
            data[right--] = temp;
        }

        // Return the updated array
        return data;
    }

    // Function to find the next permutation
    // of the given integer array
    public static boolean findNextPermutation(int data[]) {

        // If the given dataset is empty
        // or contains only one element
        // next_permutation is not possible
        if (data.length <= 1)
            return false;

        int last = data.length - 2;

        // find the longest non-increasing suffix
        // and find the pivot
        while (last >= 0) {
            if (data[last] < data[last + 1]) {
                break;
            }
            last--;
        }

        // If there is no increasing pair
        // there is no higher order permutation
        if (last < 0)
            return false;

        int nextGreater = data.length - 1;

        // Find the rightmost successor to the pivot
        for (int i = data.length - 1; i > last; i--) {
            if (data[i] > data[last]) {
                nextGreater = i;
                break;
            }
        }

        // Swap the successor and the pivot
        data = swap(data, nextGreater, last);

        // Reverse the suffix
        data = reverse(data, last + 1, data.length - 1);

        // Return true as the next_permutation is done
        return true;
    }
}

class ArrayUtil {
    private static long INF = 1_000_000_000_0L;

    public static int UpperBound(long[] array, long obj) {
        int l = 0, r = array.length - 1;
        while (r - l >= 0) {
            int c = (l + r) / 2;
            if (obj < array[c]) {
                r = c - 1;
            } else {
                l = c + 1;
            }
        }
        return l;
    }

    public static int LowerBound(long[] array, long obj) {
        int l = 0, r = array.length - 1;
        while (r - l >= 0) {
            int c = (l + r) / 2;
            if (obj <= array[c]) {
                r = c - 1;
            } else {
                l = c + 1;
            }
        }
        return l;
    }

    // return the length of array's LIS
    public static int LIS(long[] array) {
        long[] dp = new long[array.length + 1];
        Arrays.fill(dp, INF);
        for (int i = 0; i < array.length; i++) {
            int idx = LowerBound(dp, array[i]);
            dp[idx] = array[i];
        }
        return LowerBound(dp, INF - 1);
    }

    public static int StrictLIS(long[] array) {
        long[] dp = new long[array.length + 1];
        Arrays.fill(dp, INF);
        for (int i = 0; i < array.length; i++) {
            int idx = UpperBound(dp, array[i]);
            dp[idx] = array[i];
        }
        return UpperBound(dp, INF - 1);
    }
}

class BinaryIndexedTree {
    int[] data;
    long[] tree;
    int n;

    public BinaryIndexedTree(int[] data) {
        this.data = data;
        this.n = data.length;
        this.tree = new long[n + 1];
        buildTree();
    }

    public void buildTree() {
        for (int i = 0; i < n; i++) {
            add(i + 1, data[i]);
        }
    }

    public void add(int index, int value) {
        for (int i = index; i <= n; i += i & -i) {
            tree[i] += value;
        }
    }

    public long sum(int from, int to) {
        return sum(to) - sum(from - 1);
    }

    public long sum(int index) {
        int sum = 0;
        for (int i = index; i > 0; i -= i & -i) {
            sum += tree[i];
        }
        return sum;
    }
}