Problem: There is a road with length l meters. The start of the road has coordinate 0, the end of the road has coordinate l.

There are two cars, the first standing at the start of the road and the second standing at the end of the road. They will start driving simultaneously. The first car will drive from the start to the end and the second car will drive from the end to the start.

Initially, they will drive with a speed of 1 meter per second. There are n flags at different coordinates a_1, a_2, …, a_n. Each time when any of two cars drives through a flag, the speed of that car increases by 1 meter per second.

Find how long will it take for cars to meet (to reach the same coordinate). 

Input

The first line contains one integer t (1 ≤ t ≤ 10^4): the number of test cases.

The first line of each test case contains two integers n, l (1 ≤ n ≤ 10^5, 1 ≤ l ≤ 10^9): the number of flags and the length of the road.

The second line contains n integers a_1, a_2, …, a_n in the increasing order (1 ≤ a_1 < a_2 < … < a_n < l).

It is guaranteed that the sum of n among all test cases does not exceed 10^5.

Output

For each test case print a single real number: the time required for cars to meet.

Your answer will be considered correct, if its absolute or relative error does not exceed 10^{-6}. More formally, if your answer is a and jury's answer is b, your answer will be considered correct if \frac{|a-b|}{max{(1, b)}} ≤ 10^{-6}.

Example

Input


5
2 10
1 9
1 10
1
5 7
1 2 3 4 6
2 1000000000
413470354 982876160
9 478
1 10 25 33 239 445 453 468 477


Output


3.000000000000000
3.666666666666667
2.047619047619048
329737645.750000000000000
53.700000000000000

Note

In the first test case cars will meet in the coordinate 5.

The first car will be in the coordinate 1 in 1 second and after that its speed will increase by 1 and will be equal to 2 meters per second. After 2 more seconds it will be in the coordinate 5. So, it will be in the coordinate 5 in 3 seconds.

The second car will be in the coordinate 9 in 1 second and after that its speed will increase by 1 and will be equal to 2 meters per second. After 2 more seconds it will be in the coordinate 5. So, it will be in the coordinate 5 in 3 seconds.

In the second test case after 1 second the first car will be in the coordinate 1 and will have the speed equal to 2 meters per second, the second car will be in the coordinate 9 and will have the speed equal to 1 meter per second. So, they will meet after (9-1)/(2+1) = 8/3 seconds. So, the answer is equal to 1 + 8/3 = 11/3.

Solution (in JAVA):

Solution:
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Solution 
{
	static InputReader in = new InputReader(System.in);
	static int mod = (int)1e9 + 7;
	static int MAXN = 100005;
	static long[] fact = new long[MAXN];
	static long[] inv = new long[MAXN];
	
    public static void main(String args[]) {
        new Thread(null, new Runnable() {
            public void run() {
                try{
                    solve();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }, "1", 1 << 26).start();
    }
    
    public static void solve(){
    	int T = in.ni();
    	for(int t = 1; t <= T; t++) {
    		int n = in.ni();
    		int l = in.ni();
    		int[] ar = intArray(n);
    		
    		double lo = 0, hi = 1e9 + 5;
    		for(int i = 0; i < 150; i++) {
    			double m = lo + (hi - lo)/2;
    			double d1 = forward(ar, m, l);
    			double d2 = backward(ar, m, l);
    			//pn(d1+ " " + d2 +" " + m);
    			if(d1 + d2 < l) lo = m;
    			else hi = m;
    		}
    		
    		System.out.printf("%.7f\n", lo);
    	}
    } 
    
    private static double backward(int[] ar, double t, int l) {
    	double d = 0.0;
    	double speed = 1.0;
    	double prev = l;
    	for(int i = ar.length - 1; i >= 0; i--) {
    		double temp = (prev - ar[i])/speed;
    		if(temp <= t) {
    			t -= temp;
    			d += (prev - ar[i]);
    		} else {
    			d += t * speed;
    			t = 0;
    			break;
    		}
    		prev = ar[i];
    		speed++;
    	}
    	
    	if(t > 0 && d < l) {
    		d += t * speed;
    	}
		
		return d;
	}

	private static double forward(int[] ar, double t, int l) {
    	double d = 0.0;
    	double speed = 1.0;
    	double prev = 0;
    	for(int i = 0; i < ar.length; i++) {
    		double temp = (ar[i] - prev)/speed;
    		if(temp <= t) {
    			t -= temp;
    			d += (ar[i] - prev);
    		} else {
    			d += t * speed;
    			t = 0;
    			break;
    		}
    		prev = ar[i];
    		speed++;
    	}
    	
    	if(t > 0 && d < l) {
    		d += t * speed;
    	}
		return d;
	}

	public static void solve(int t) {
    	System.out.print("Case #"+t+": ");
    	pn("");
    }
   
    /*TEMPLATE*/
    
    //MATHS
    static int max(Integer... ar) {
    	int max = Integer.MIN_VALUE;
    	for(int i: ar) {
    		max = Math.max(max, i);
    	}
    	return max;
    }
    
    static long max(Long... ar) {
    	long max = Integer.MIN_VALUE;
    	for(long i: ar) {
    		max = Math.max(max, i);
    	}
    	return max;
    }
  
    static int gcd(int a, int b) {
    	return (b==0)?a:gcd(b,a%b);
    }
    
    static long binPow(long x, long y) {
        long ans = 1L;
        while(y > 0) {
            if(y % 2 == 1)
                ans = mul(ans, x);
            x = mul(x, x);
            y /= 2;
        }
        return ans;
    }
    
    static long add(long x, long y) {
    	x += y;
    	return mod(x, mod);
    }
    
    static long mul(long x, long y) {
    	return mod(x * y, mod);
    }
    
    static long divide(long x, long y) {
        return mul(x, binPow(y, mod - 2));
    }

    static long mod(long x, long p) {
        x %= p;
        if (x < 0)
            x += p;
        return x;
    }
        
    public static int[] spf(int maxn) {
    	int[] spf=new int[maxn+1];
    	spf[0]=spf[1]=1;
    	for(int i=2;i<=maxn;i++) {
    		if(i%2==0) spf[i]=2;
    		else 
    			spf[i]=i;
    	}
    	for(int i=3;i*i<=maxn;i++) {
    		if(spf[i]==i){
    			for (int j=i*i; j<=maxn; j+=i) 
                    if (spf[j]==j) 
                        spf[j] = i;
    		}
    	}
    	return spf;
    }
    
    static void nCrInit() {
    	fact[0] = 1;
    	for(int i = 1; i < MAXN; i++) fact[i] = mul(fact[i - 1], 1L * i);
    	inv[MAXN - 1] = binPow(fact[MAXN - 1], mod - 2); 
    	for(int i = MAXN - 2; i >= 0; i--) inv[i] = mul(inv[i + 1], 1L * (i + 1));
     }
    
    static long nCr(int n, int r) {
    	if(r > n || n < 0 || r < 0) return 0;
    	return fact[n] * inv[r] % mod * inv[n - r] % mod;
    }
    
    //ARRAYS
    public static int[] intArray(int n) {
    	int ar[]=new int[n];
    	for(int i=0;i<n;i++)
    		ar[i]=in.nextInt();
    	return ar;
    }
    
    public static void swap(int i, int j, int ar[]) {
    	int c=ar[i];ar[i]=ar[j];ar[j]=c;
    }
    
    public static void reverse(int ar[]) {
    	int l=0, r=ar.length-1;
    	while(l<r) {
    		int temp=ar[l]; ar[l]=ar[r]; ar[r]=temp;
    		l++; r--;
    	}
    }
    
    public static int upperBound(int[] array, int value) {
    	//return next higher element. If greater than all elements then returns array.length
    	//returns 0 if smaller than all elements
    	int low = 0;
    	int high = array.length;
    	while (low < high) {
    		final int mid = (low + high) / 2;
    		if (value >= array[mid]) {
    			low = mid + 1;
    		} else {
    			high = mid;
    		}
    	}
    	return low;
    }
    
    public static int lowerBound(int[] array, int value) {
    	//Returns first occurrence.
    	//Bigger than all elements then return array.length
    	//Not found, then next greater.s
    	int low = 0;
    	int high = array.length;
    	while (low < high) {
    		final int mid = (low + high) / 2;
			if (value <= array[mid]) {
			high = mid;
			} else {
				low = mid + 1;
			}
    	}
    	return low;
	}
    
    //Segment Tree
    static class SegNode {
    	//SegNode contains all query variables
    	long v;
    	SegNode() {
    		//Initialise using identity values
    		v = 0;
    	}
    	
    	SegNode(long v) {
    		this.v = v;
    	}
    	
    	public void merge(SegNode l, SegNode r) {
    		this.v = l.v + r.v;
    	}
    }
    
    static class SegUpdate {
    	//It contains only the updates not the query variables.
    	long v; 
    	SegUpdate() {
    		//Initialise all segupdate variables here with identity values
    		// 0 for sum
    		//Integer.MAX_VALUE for min operations
    		// 1 for product, etc.
    		this.v = 0;
    	}
    	
    	SegUpdate(long v) {
    		this.v = v;
    	}
    	
    	//Combine current update with other update.
    	//Other update is newer than my present update
    	//In case of non-lazy propagation leave this blank
    	public void combine(SegUpdate other, int tl, int tr) {
    		v += other.v;
    	}
    	
    	//Apply all updates so far in the query variables inside SegNode
    	//In case of non-lazy updates, consider x to be a leaf node.
    	public void apply(SegNode x, int tl, int tr) {
    		x.v += (tr - tl + 1) * v;
    	}
    }
    
    static class SegTree {
    	int len;
    	SegNode[] t;
    	SegUpdate[] u;
    	boolean[] lazy;
    	
    	SegTree(int l) {
    		len = l;
    		t = new SegNode[4 * len];
    		for(int i = 0; i < t.length; i++) t[i] = new SegNode();
    		u = new SegUpdate[4 * len];
    		for(int i = 0; i < u.length; i++) u[i] = new SegUpdate();    		
    		lazy = new boolean[4 * len];
    	}
    	
    	int descent(int k) {
    		return descent(1, 0, len - 1, k);
    	}
    	
    	int descent(int v, int tl, int tr, int k) {
    		if(t[v].v < k) {
    			return -1;
    		} 
    		while(tl < tr) {
    			int tm = (tl + tr)/2;
    			if(t[2*v].v >= k) {
    				tr = tm;
    				v = 2*v;
    			} else {
    				tl = tm + 1;
    				k -= t[2*v].v;
    				v = 2*v + 1;
    			}
    		}
			return tl;
    	}
     
    	void pushdown(int v, int tl, int tr){
    		if(!lazy[v]) return;
    		int tm = (tl + tr) >> 1;
    		apply(v<<1, tl, tm, u[v]);
    		apply(v<<1|1, tm + 1, tr, u[v]);
    		u[v] = new SegUpdate();
    		lazy[v] = false;
    	}
     
    	void apply(int v, int tl, int tr, SegUpdate upd){
    		if(tl != tr){
    			lazy[v] = true;
    			u[v].combine(upd, tl, tr);
    		}
    		upd.apply(t[v], tl, tr);
    	}
    	
    	private void build(int[] arr, int v, int tl, int tr){
    		if(tl == tr){
    			t[v] = new SegNode(arr[tl]);
    			return;
    		}
    		int tm = (tl + tr) >> 1;
    		build(arr, v<<1, tl, tm);
    		build(arr, v<<1|1, tm + 1, tr);
    		t[v].merge(t[v<<1], t[v<<1|1]);
    	}
     
    	private SegNode query(int v, int tl, int tr, int l, int r){
    		if(l > tr || r < tl){
    			return new SegNode();
    		}
    		if(tl >= l && tr <= r){
    			return t[v];
    		}
    		pushdown(v, tl, tr);
    		int tm = (tl + tr) >> 1;
    		SegNode a = query(v<<1,tl,tm,l,r),b = query(v<<1|1,tm+1,tr,l,r);
    		SegNode ans = new SegNode();
    		ans.merge(a,b);
    		return ans;
    	}
     
    	// rupd = range update
    	private void rupd(int v, int tl, int tr, int l, int r, SegUpdate upd){
    		if(l > tr || r < tl){
    			return;
    		}
    		if(tl >= l && tr <= r){
    			apply(v,tl,tr,upd);
    			return;
    		}
    		pushdown(v,tl,tr);
    		int tm = (tl + tr) >> 1;
    		rupd(v<<1,tl,tm,l,r,upd);
    		rupd(v<<1|1,tm+1,tr,l,r,upd);
    		t[v].merge(t[v<<1], t[v<<1|1]);
    	}
     
    	void build(int[] arr){
    		build(arr, 1, 0, len - 1);
    	}
    	
    	void build(long[] arr){
    		build(arr, 1, 0, len - 1);
    	}
    	
    	private void build(long[] arr, int v, int tl, int tr){
    		if(tl == tr){
    			t[v] = new SegNode(arr[tl]);
    			return;
    		}
    		int tm = (tl + tr) >> 1;
    		build(arr, v<<1, tl, tm);
    		build(arr, v<<1|1, tm + 1, tr);
    		t[v].merge(t[v<<1], t[v<<1|1]);
    	}
    	
    	SegNode query(int l, int r){
    		return query(1,0,len-1,l,r);
    	}
    	
    	void rupd(int l, int r, SegUpdate upd){
    		rupd(1,0,len-1,l,r,upd);
    	}
    	
    	void debug() { 
    		System.out.println("------Debug-----");
    		for(int i = 0; i < 4 * len; i++) {
        		System.out.print(t[i].v+" ");
        	}
    		
    		for(int i = 0; i < 4 * len; i++) {
        		System.out.print(u[i].v+" ");
        	}
    		
        	System.out.println();
        	System.out.println(Arrays.toString(lazy));
        	System.out.println("-------------");
    	}
    }
   
    public static void pn(Object o) {
      System.out.println(o);
    }
    
    static class InputReader {
 
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int snumChars;
        private SpaceCharFilter filter;
 
        public InputReader(InputStream stream) {
            this.stream = stream;
        }
 
        public int ni() {
			return nextInt();
		}

		public int snext() {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars) {
                curChar = 0;
                try {
                    snumChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }
 
        public int nextInt() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
 
            int res = 0;
 
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
 
            return res * sgn;
        }
 
        public long nextLong() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
 
            long res = 0;
 
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
 
            return res * sgn;
        }
        
        public double nextDouble() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = snext();
            }
 
            double res = 0, div = 1.0;
            
            do {
                res = res * 10 + c - '0';
            } while ((c = snext()) >= '0' && c <= '9');
 
            if (c == '.') {
                while ((c = snext()) >= '0' && c <= '9') {
                    res += (c - '0') / (div *= 10);
                }
            }
            
            return res * sgn;
        }
 
        public String readString() {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = snext();
            } 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 interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }
}