Problem: Find out if it is possible to partition the first n positive integers into two non-empty disjoint sets S_1 and S_2 such that:

gcd(sum(S_1), sum(S_2)) > 1 

Here sum(S) denotes the sum of all elements present in set S and gcd means the[greatest common divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor).

Every integer number from 1 to n should be present in exactly one of S_1 or S_2.

Input

The only line of the input contains a single integer n (1 ≤ n ≤ 45 000)

Output

If such partition doesn't exist, print "No" (quotes for clarity).

Otherwise, print "Yes" (quotes for clarity), followed by two lines, describing S_1 and S_2 respectively.

Each set description starts with the set size, followed by the elements of the set in any order. Each set must be non-empty.

If there are multiple possible partitions — print any of them.

Examples

Input

1


Output

No

Input

3


Output

Yes
1 2
2 1 3 

Note

In the first example, there is no way to partition a single number into two non-empty sets, hence the answer is "No".

In the second example, the sums of the sets are 2 and 4 respectively. The gcd(2, 4) = 2 > 1, hence that is one of the possible answers.

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.math.BigInteger;
 
 
public class q2 {
		public static void bfs(int i, int j, int[][] visited,int n,int m, String[] board) {
			visited[i][j]=1;
					int left=j-1;
					int right=j+1;
					int up=i-1;
					int down=j+1;
					if(left>=0) {
						if(board[i].charAt(left)=='X' && visited[i][left]==0)
							bfs(i,left,visited,n,m,board);
					}
					if(right<m) {
						if(board[i].charAt(right)=='X' && visited[i][right]==0)
							bfs(i,right,visited,n,m,board);}
					if(up>=0) {
						if(board[up].charAt(j)=='X' && visited[up][j]==0)
							bfs(up,j,visited,n,m,board);}
					if(down<n) {
						if(board[down].charAt(j)=='X' && visited[down][j]==0)
							bfs(down,j,visited,n,m,board);}
		} 
	 
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Reader.init(System.in);
		int n=Reader.nextInt();
		if(n==1 || n==2) {
			System.out.println("No");
		}
		else {
			System.out.println("Yes");
			ArrayList<Integer> a=new ArrayList<Integer>();
			ArrayList<Integer> aa=new ArrayList<Integer>();
			for(int i=1;i<=n;i+=2) {
				a.add(i);
			}
			System.out.print(a.size()+" ");
			for(int i:a) {
				System.out.print(i+" ");
			}
			System.out.println();
			
			for(int i=2;i<=n;i+=2) {
				aa.add(i);
			}
			System.out.print(aa.size()+" ");
			for(int i:aa) {
				System.out.print(i+" ");
			}
		}
		
					
			
			
		}
	}

 class DisJoint {
		int[] parent;
		int[] rank;
		int[] size;
		DisJoint(int n){
			
			parent=new int[n+1];
			rank=new int[n+1];
			size=new int[n+1];
			for(int i=0;i<=n;i++) {
				parent[i]=i;
				size[i]=1;
			}
		}
 
		int find(int value) {
			int par=parent[value];
			if(par==value)
				return par;
			parent[value]=find(par);
			return parent[value];
		}
		
		void union(int data1,int data2) {
			int parent1=find(data1);
			int parent2=find(data2);
			if(parent1!=parent2) {
				if(rank[parent1]>=rank[parent2]) {
					parent[parent2]=parent1;
					if(rank[parent1]==rank[parent2])
						rank[parent1]++;
					size[parent1]+=size[parent2];
				}
				else {
					parent[parent1]=parent2;	
					size[parent2]+=size[parent1];
		}
 
		}
		}
 }
class SegTree{
	int[] seg;
	int[] arr;
	int[] minseg;
	SegTree(int n,int[] a){
		seg=new int[4*n];
		minseg=new int[4*n];
		arr=a;
		
	}
	void build(int low,int high, int pos) {
		if(low==high) {
			seg[pos]=arr[low];
			minseg[pos]=arr[low];
		}
		else {
			int middle=(low+high)/2;
			build(low,middle,2*pos+1);
			build(middle+1,high,2*pos+2);
			seg[pos]=Math.max(seg[2*pos+1],seg[2*pos+2]);
			minseg[pos]=Math.min(minseg[2*pos+1], minseg[2*pos+2]);
			}
	}
	void update(int low,int high, int pos, int elpos,int val) {
		if(low==high) {
			seg[pos]=val;
		}
		else {
			int middle=(low+high)/2;
			if(middle>=elpos) {
				update(low,middle,2*pos+1,elpos,val	);
			}
			else update(middle+1,high,2*pos+2,elpos,val);
			seg[pos]=Math.max(seg[2*pos+1], seg[2*pos+2]);
		}
	}
	int query(int low,int high,int pos,int ql,int qh) {
		if(ql<=low && high<=qh) {
			return seg[pos];
		}
		else if(ql>high || qh<low) {
			return 0;
		}
		else {
			int middle=(low+high)/2;
			return Math.max(query(low,middle,2*pos+1,ql,qh), query(middle+1,high,2*pos+2,ql,qh));
		}
	}
	int minquery(int low,int high,int pos,int ql,int qh) {
		if(ql<=low && high<=qh) {
			return minseg[pos];
		}
		else if(ql>high || qh<low) {
			return 10000000;
		}
		else {
			int middle=(low+high)/2;
			return Math.min(minquery(low,middle,2*pos+1,ql,qh), minquery(middle+1,high,2*pos+2,ql,qh));
		}
	}
}
 class NON{
	 int leftindex;
	 int rightindex;
	 NON(){
		 
	 }
	 NON(int a,int b){
		 leftindex=a;rightindex=b;
	 }
 }
 class NNN{
		int val;
		int ht;
		NNN left;
		NNN right;
		NNN(){
			left=null;right=null;
			
		}
	}
 class AVL {
	 NNN root;
	 NNN a;
		AVL(){
			root=null;
			a=null;
		}
		
		NNN insert(NNN root,int val)
		{
		   NNN nptr=new NNN();
		   nptr.val=val;
		   nptr.left=null;
		   nptr.right=null;
		   nptr.ht=0;
		   if(root==null){
		       root=nptr;
		       return root;
		   }
		   if(val<=root.val){
		       root.left=insert(root.left,val);
		   }
		   else{
		       root.right=insert(root.right,val);
		   }
		   int lh=height(root.left);
		   int rh=height(root.right);
		   if(Math.abs(lh-rh)>1){
		       if(lh>rh){
		           if(height(root.left.right)>height(root.left.left))
		               root.left=RightRotate(root.left);
		           root=LeftRotate(root);
		       }
		       else{
		           if(height(root.right.left)>height(root.right.right))
		               root.right=LeftRotate(root.right);
		           root=RightRotate(root);
		       }
		   }
		   root.ht=height(root);
		   return root;
		}
		int height(NNN roote){
		    if(roote==null) return -1;
		    int left;
		    if(roote.left==null) left=-1;
		    else left=roote.left.ht;
		    int right;
		    if(roote.right==null) right=-1;
		    else right=roote.right.ht;
		    if(left>right) return left+1;
		    else return right+1;
		}
		NNN LeftRotate(NNN prev){
		    NNN newr=prev.left;
		    NNN child=newr.right;
		    prev.left=child;
		    newr.right=prev;
		    prev.ht=height(prev);
		    newr.ht=height(newr);
		    return newr;
		}
		 NNN RightRotate(NNN prev){
		    NNN newr=prev.right;
		    NNN child=newr.left;
		    prev.right=child;
		    newr.left=prev;
		    prev.ht=height(prev);
		    newr.ht=height(newr);
		    return newr;
		}
		 NNN delete(NNN root, int val)
		 {
		        if (root == null)
		            return root;
		 
		        if (val < root.val)
		            root.left = delete(root.left, val);
		        else if (val > root.val)
		            root.right = delete(root.right, val);
		        else
		        {
		 
		           
		            if (root.left == null && root.right==null )
		            {
		                root=null;
		            }
		            else if(root.left==null) root=root.right;
		            else if(root.right==null) root=root.left;
		            else
		            {
		                NNN temp = delmin(root.right);
		                root.val = temp.val;
		                root.right = delete(root.right, temp.val);
		            }
		        }
		        return root;
		    }
		 NNN delmin(NNN roote) {
			 if(roote.left==null) {
				 return roote;
				
			 }
			 else {
				 return delmin(roote.left);
			 }
			
		 }
		int search(NNN roote,long sum, long expsum,int ret){
			if(roote==null) return ret;
			if(sum-roote.val>=expsum) {
				ret=roote.val;
				return search(roote.right,sum,expsum,ret);
			}
			else {
				return search(roote.left,sum,expsum,ret);
			}
			
		}
		int retmax(NNN roote) {
			if(roote.right==null) return roote.val;
			else return retmax(roote.right);
		}	
 }
 class Reader {
	    static BufferedReader reader;
	    static StringTokenizer tokenizer;
	 
	    /** call this method to initialize reader for InputStream */
	    static void init(InputStream input) {
	        reader = new BufferedReader(
	                     new InputStreamReader(input) );
	        tokenizer = new StringTokenizer("");
	    }
	 
	    /** get next word */
	    
	    static String next() throws IOException {
	        while ( ! tokenizer.hasMoreTokens() ) {
	            //TODO add check for eof if necessary
	            tokenizer = new StringTokenizer(
	                   reader.readLine() );
	        }
	        return tokenizer.nextToken();
	    }
	 
	    static int nextInt() throws IOException {
	        return Integer.parseInt( next() );
	    }
	    static long nextLong() throws IOException {
	        return Long.parseLong( next() );
	    }
	    static double nextDouble() throws IOException {
	        return Double.parseDouble( next() );
	    }
	}