Problem: You are given a positive integer n, it is guaranteed that n is even (i.e. divisible by 2).

You want to construct the array a of length n such that: 

  * The first n/2 elements of a are even (divisible by 2); 
  * the second n/2 elements of a are odd (not divisible by 2); 
  * all elements of a are distinct and positive; 
  * the sum of the first half equals to the sum of the second half (∑_{i=1}^{n/2} a_i = ∑_{i=n/2 + 1}^{n} a_i). 



If there are multiple answers, you can print any. It is not guaranteed that the answer exists.

You have to answer t independent test cases.

Input

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

The only line of the test case contains one integer n (2 ≤ n ≤ 2 ⋅ 10^5) — the length of the array. It is guaranteed that that n is even (i.e. divisible by 2).

It is guaranteed that the sum of n over all test cases does not exceed 2 ⋅ 10^5 (∑ n ≤ 2 ⋅ 10^5).

Output

For each test case, print the answer — "NO" (without quotes), if there is no suitable answer for the given test case or "YES" in the first line and any suitable array a_1, a_2, ..., a_n (1 ≤ a_i ≤ 10^9) satisfying conditions from the problem statement on the second line.

Example

Input


5
2
4
6
8
10


Output


NO
YES
2 4 1 5
NO
YES
2 4 6 8 1 3 5 11
NO

Solution (in JAVA):

Solution:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class D_Constant_Palindrome_Sum {
	public static void main(String[] args) {
		MyScanner sc = new MyScanner();
	    PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
	    
	    int T = sc.nextInt();
	    
	    while(T-- > 0) {
	    	int N = sc.nextInt();
	    	int K = sc.nextInt();
	    	
	    	int[] vals = new int[N];
	    	for(int i = 0; i < N; i++) {
	    		vals[i] = sc.nextInt();
	    	}
	    	
	    	//All possible x-values
	    	SegmentTree costs = new SegmentTree(2*K + 1);
	    	
	    	for(int i = 0; i < N/2; i++) {
	    		int a = vals[i];
	    		int b = vals[N - i - 1];
	    	
	    		//0: a+b
	    		
	    		//1: [min(a + 1, b + 1), a + b) U (a + b, max(a + K, b + K)]
	    		if((a + b - 1) - Math.min(a + 1, b + 1) >= 0) {
	    			costs.increment(Math.min(a + 1, b + 1), a + b - 1, 1);
	    		}
	    		if(Math.max(a + K, b + K) - (a + b + 1) >= 0) {
	    			costs.increment(a + b + 1, Math.max(a + K, b + K), 1);
	    		}
	    		
	    		//2: [2, min(a + 1, b + 1)) U (max(a + K, b + K), 2*K]
	    		if(Math.min(a + 1, b + 1) - 2 > 0) {
	    			costs.increment(2, Math.min(a + 1, b + 1) - 1, 2);
	    		}
	    		if(2*K - Math.max(a + K, b + K) > 0) {
	    			costs.increment(Math.max(a + K, b + K) + 1, 2*K, 2);
	    		}
	    	}
	    	
	    	//Output answer
	    	out.println(costs.rangeMinQuery(2, 2*K));
	    }
	    
	    out.close();
	}
	
	private static class SegmentTree {
		Node[] st;
		int[] vals;
		int elemCount;
		
		private SegmentTree(int size) {
			this.vals = new int[size];
			elemCount = size;
			
			int treeHeight = (int) Math.ceil(Math.log(elemCount)/Math.log(2));
			//Tree has 2^(h+1) - 1 nodes where h is the height (Add buffer values)
			st = new Node[(int) Math.pow(2, treeHeight + 1) - 1 + 1];
			initialize(1, 0, elemCount);
		}
		
		private SegmentTree(int[] vals) {
			this.vals = Arrays.copyOf(vals, vals.length);
			elemCount = vals.length;
			
			int treeHeight = (int) Math.ceil(Math.log(elemCount)/Math.log(2));
			//Tree has 2^(h+1) - 1 nodes where h is the height (Add buffer values)
			st = new Node[(int) Math.pow(2, treeHeight + 1) - 1 + 1];
			initialize(1, 0, elemCount);
		}
		
		//From and to are inclusive bounds
		private void initialize(int v, int from, int size) {
			st[v] = new Node();
			st[v].from = from;
			st[v].to = from + size - 1;
			
			if(size == 1) {
				st[v].sum = vals[from];
				st[v].max = vals[from];
				st[v].min = vals[from];
			}else {
				initialize(2*v, from, size/2);
				initialize(2*v + 1, from + size/2, size - size/2);
				
				st[v].sum = st[v*2].sum + st[v*2 + 1].sum;
				st[v].max = Math.max(st[v*2].max, st[v*2 + 1].max);
				st[v].min = Math.min(st[v*2].min, st[v*2 + 1].min);
			}
		}
		
		//Range sum query
		public int rsq(int from, int to) {
			return rsq(1, from, to);
		}
		
		private int rsq(int v, int from, int to) {
			Node curr = st[v];
			
			//Update with pending lazy propagation
			propagate(v);
			
			//If no overlap, return 0
			if(!intersects(from, to, curr.from, curr.to))
				return 0;
			//If node.from, node.to to contained within from,to, return sum
			else if(contains(curr.from, curr.to, from, to)) 
				return curr.sum;
			//If partial overlap, send query to children w/ updated to and from
			else if(intersects(from, to, curr.from, curr.to)){
				//Left
				int left = rsq(v*2, from, to);
				
				//Right
				int right = rsq(v*2 + 1, from, to);
				return left + right;
			}
					
			return 0;
		}
		
		//Range max query
		public int rangeMaxQuery(int from, int to) {
			return rangeMaxQuery(1, from, to);
		}
		
		private int rangeMaxQuery(int v, int from, int to) {
			Node curr = st[v];
			
			//Update with pending lazy propagation
			propagate(v);
			
			//If no overlap, return 0
			if(!intersects(from, to, curr.from, curr.to))
				return Integer.MIN_VALUE;
			//If node.from, node.to to contained within from,to, return sum
			else if(contains(curr.from, curr.to, from, to)) 
				return curr.max;
			//If partial overlap, send query to children w/ updated to and from
			else if(intersects(from, to, curr.from, curr.to)){
				//Left
				int left = rangeMaxQuery(v*2, from, to);
				
				//Right
				int right = rangeMaxQuery(v*2 + 1, from, to);
				return Math.max(left, right);
			}
					
			return 0;
		}
		
		//Range min query
		public int rangeMinQuery(int from, int to) {
			return rangeMinQuery(1, from, to);
		}
		
		private int rangeMinQuery(int v, int from, int to) {
			Node curr = st[v];
			
			//Update with pending lazy propagation
			propagate(v);
			
			//If no overlap, return 0
			if(!intersects(from, to, curr.from, curr.to))
				return Integer.MAX_VALUE;
			//If node.from, node.to to contained within from,to, return sum
			else if(contains(curr.from, curr.to, from, to)) 
				return curr.min;
			//If partial overlap, send query to children w/ updated to and from
			else if(intersects(from, to, curr.from, curr.to)){
				//Left
				int left = rangeMinQuery(v*2, from, to);
				
				//Right
				int right = rangeMinQuery(v*2 + 1, from, to);
				return Math.min(left, right);
			}
					
			return 0;
		}
		
		public void increment(int from, int to, int value) {
	        increment(1, from, to, value);
	    }

	    private void increment(int v, int from, int to, int value) {
	    	Node curr = st[v];
	    	
	    	if(from > to)
	    		return;
	    	
	    	propagate(v);
	    	
	    	//Query doesn't overlap at all
	    	if(from > curr.to || to < curr.from)
	    		return;
	    	
	    	//Query overlaps node
	    	if(contains(curr.from, curr.to, from, to)) {
	    		curr.sum += value * (to - from + 1);
	    		curr.max += value;
	    		curr.min += value;
	    		if(curr.from != curr.to) {
	    			st[v*2].pending += value;
	    			st[v*2 + 1].pending += value;
	    		}
	    	//Query intersects
	    	}else if(intersects(from, to, curr.from, curr.to)) {
	    		increment(v*2, from, to, value);
	    		increment(v*2+1, from, to, value);
	    		
	    		st[v].sum = st[v*2].sum + st[v*2+1].sum;
	    		st[v].max = Math.max(st[v*2].max, st[v*2+1].max);
	    		st[v].min = Math.min(st[v*2].min, st[v*2+1].min);
	    		return;
	    	}
	    	
	    	
	    }

		//Propagate
		private void propagate(int v) {
			Node curr = st[v];
			
			if(curr.pending == 0) return;
			
			st[v].sum += curr.pending * (curr.to - curr.from + 1);
			st[v].max += curr.pending;
			st[v].min += curr.pending;
			
			//Left child (if possible)
			if(curr.from != curr.to)
				st[v*2].pending += curr.pending;
			//Right child (if possible)
			if(curr.from != curr.to)
				st[v*2 + 1].pending += curr.pending;
			
			curr.pending = 0;
		}
		
		//Inclusive bounds - checks if range 1 intersects range 2
		private boolean intersects(int f1, int t1, int f2, int t2) {
			//Think about when it fails to understand this boolean expression
			return f1 <= t2 && f2 <= t1;
		}
		
		//Inclusive bounds - if range 1 is contained within range 2
		private boolean contains(int f1, int t1, int f2, int t2) {
			if(f1 >= f2 && t1 <= t2) return true;
			return false;
		}
	}
	
	//Lazy propagate with the Node
	private static class Node {
		int sum = 0;
		int max = 0;
		int min = Integer.MAX_VALUE;
		
		//
		int pending = 0;
		int from = 0;
		int to = 0;
		
		public String toString() {
			return "[" + from + "," + to +"]";
		}
		
		int rangeSize() {
			return to - from + 1;
		}
	}
	
	private static class MyScanner {
		BufferedReader br;
	    StringTokenizer st;
	 
	    public MyScanner() {
	       br = new BufferedReader(new InputStreamReader(System.in));
	    }
	 
	    String next() {
	    	while (st == null || !st.hasMoreElements()) {
	    		try {
	    			st = new StringTokenizer(br.readLine());
	            	
	    		} catch (IOException e) {
	    			e.printStackTrace();
	            }
	          }
	    	return st.nextToken();
	   }
	 
	   int nextInt() {
		   return Integer.parseInt(next());
	   }
	 
	   long nextLong() {
		   return Long.parseLong(next());
	   }
	 
	   double nextDouble() {
		   return Double.parseDouble(next());
	   }
	 
	   String nextLine(){
		   String str = "";
		   try {
			   str = br.readLine();
		   } catch (IOException e) {
			   e.printStackTrace();
		   }
		   return str;
	   }
	}
}