Problem: It happened at the times of the Great Berland Empire. Once the Emperor dreamt that the Messenger from the gods ordered to build a temple whose base would be a convex polygon with n angles. Next morning the Emperor gave the command to build a temple whose base was a regular polygon with n angles. The temple was built but soon the Empire was shaken with disasters and crop failures. After an earthquake destroyed the temple, the Emperor understood that he somehow caused the wrath of gods to fall on his people. He ordered to bring the wise man. When the wise man appeared, the Emperor retold the dream to him and asked "Oh the wisest among the wisest, tell me how could I have infuriated the Gods?". "My Lord," the wise man answered. "As far as I can judge, the gods are angry because you were too haste to fulfill their order and didn't listen to the end of the message".

Indeed, on the following night the Messenger appeared again. He reproached the Emperor for having chosen an imperfect shape for the temple. "But what shape can be more perfect than a regular polygon!?" cried the Emperor in his dream. To that the Messenger gave a complete and thorough reply. 

  * All the vertices of the polygon should be positioned in the lattice points. 
  * All the lengths of its sides should be different. 
  * From the possible range of such polygons a polygon which maximum side is minimal possible must be chosen. 



You are an obedient architect who is going to make the temple's plan. Note that the polygon should be simple (having a border without self-intersections and overlapping) and convex, however, it is acceptable for three consecutive vertices to lie on the same line.

Input

The first line contains the single number n (3 ≤ n ≤ 10000).

Output

Print "YES" (without quotes) in the first line if it is possible to build a polygon possessing the needed qualities. In the next n lines print integer coordinates of the polygon vertices in the order in which they would be passed counter clockwise. The absolute value of the coordinates shouldn't exceed 109. No two vertices can coincide. It is permitted to print any of the possible solutions. Print "NO" if to build the polygon is impossible.

Examples

Input

3


Output

YES
0 0
1 0
0 2


Input

3


Output

YES
0 1
-1 0
-1 -1

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;

public class Solution {
    boolean[] isSq;
    int[] lens;
    int[] cnt;
    int[][] vx, vy;
    
    int N;
    
    int[] solX, solY;
    
    boolean[][][][] was;
    
    final int LIM = 90;
    
    class Segment implements Comparable<Segment> {
        int dx, dy;
        double angle;
        
        public Segment(int dx, int dy) {
            this.dx = dx;
            this.dy = dy;
            this.angle = Math.atan2(dy, dx);
        }
        
        public int compareTo(Segment other) {
            return new Double(this.angle).compareTo(new Double(other.angle));
        }
    }
    
    int it = 0;
    boolean retFlag = false;
    
    boolean[] skipped;
    
    void go(int pos, int take, int curX, int curY, int skip) {
        /*if (Math.abs(curX) >= LIM || Math.abs(curY) >= LIM)
            return;*/
        
        if (take == N) {
            if (curX==0 && curY==0) {
                System.out.println("YES");
                
                Segment[] segm = new Segment[N];
                for (int i=0; i < N; i++)
                    segm[i] = new Segment(solX[i], solY[i]);
                Arrays.sort(segm);
                int cx=0, cy=0;
                
                for (int i=0; i < N; i++) {
                    System.out.println(cx + " " + cy);
                    cx += segm[i].dx;
                    cy += segm[i].dy;
                }
                System.exit(0);
            }
            it++;
            if (it==10000) retFlag = true;
            return;
        }

        /*int A = Math.max(Math.abs(curX), Math.abs(curY));
        int B = Math.min(Math.abs(curX), Math.abs(curY));
        if (was[pos][A][B][skip]) {
            return;
        }
        was[pos][A][B][skip] = true;*/
        
        int[] nx = new int[cnt[pos]];
        int[] ny = new int[cnt[pos]];
        int[] dist = new int[cnt[pos]];
        
        for (int x=0; x < cnt[pos]; x++) {
            nx[x] = curX + vx[pos][x];
            ny[x] = curY + vy[pos][x];
            dist[x] = nx[x] * nx[x] + ny[x] * ny[x];
        }
        
        for (int x=0; x + 1 < cnt[pos]; x++)
            for (int y=0; y + 1 < cnt[pos]; y++)
                if (dist[y] > dist[y + 1]) {
                    int tmp = nx[y]; nx[y] = nx[y+1]; nx[y+1] = tmp;
                    tmp = ny[y]; ny[y] = ny[y+1]; ny[y+1] = tmp;
                    tmp = dist[y]; dist[y] = dist[y+1]; dist[y+1] = tmp;
                }
        
        if (skip > 0 && skipped[pos])
            go(pos - 1, take, curX, curY, skip - 1);
        
        if (retFlag) return;
    
        for (int x=0; x < cnt[pos]; x++) {
            solX[take] = nx[x] - curX;
            solY[take] = ny[x] - curY;
            go(pos - 1, take + 1, nx[x], ny[x], skip);
            if (retFlag) return;
        }       
    }
    
    public void doMain() {
        Scanner sc = new Scanner(new InputStreamReader(System.in));
        N = sc.nextInt();
        
        if (N==3) {
            System.out.println("YES");
            System.out.println("0 0");
            System.out.println("1 0");
            System.out.println("0 2");
            System.exit(0);
        }
        
        isSq = new boolean[100000];
        for (int i=0; i*i < isSq.length; i++)
            isSq[i*i] = true;
        
        lens = new int[11000];
        vx = new int[11000][100];
        vy = new int[11000][100];
        cnt = new int[11000];
        
        int pos = 0;
        skipped = new boolean[N + 2];
        for (int len=1; ; len++) {
            boolean ok = false;
            for (int x=0; x*x <= len; x++) {
                if (!isSq[len-x*x]) continue;
                lens[pos] = len;
                int y = (int)Math.sqrt(len - x*x);
                ok = true;
                
                vx[pos][cnt[pos]] = x;
                vy[pos][cnt[pos]++] = y;
                
                if (x != 0) {
                    vx[pos][cnt[pos]] = -x;
                    vy[pos][cnt[pos]++] = y;
                }
                
                if (y != 0) {
                    vx[pos][cnt[pos]] = x;
                    vy[pos][cnt[pos]++] = -y;
                }
                
                if (x != 0 && y != 0) {
                    vx[pos][cnt[pos]] = -x;
                    vy[pos][cnt[pos]++] = -y;
                }
            }
            if (ok) {
                pos++;
            }
            if (pos == N + 1) break;
        }
        
        int oo = 0, ee = 0, oe = 0;
        for (int i=0; i < N; i++) {
            if (vx[i][0] % 2 == 0 && vy[i][0] % 2 == 0)
                ee++;
            else if (vx[i][0] % 2 == 1 && vy[i][0] % 2 == 1)
                oo++;
            else
                oe++;
        }
        
        int stSkip = 0;
        
        if (oe % 2 == 1) {
            stSkip = 1;
        }
                
        solX = new int[N];
        solY = new int[N];
        
        /*was = new boolean[N+2][LIM][][];
        
        for (int i=0; i < was.length; i++)
            for (int A=0; A<LIM; A++)
                was[i][A] = new boolean[A+1][2];*/
        
        for (int skip=stSkip; skip<2; skip = (skip + 1) % 2) {      
            /*for (int i=0; i < was.length; i++)
                for (int j=0; j < was[i].length; j++)
                    for (int k=0; k < was[i][j].length; k++)
                        Arrays.fill(was[i][j][k], false);*/
            
            if (skip == 1) {
                for (int i=0; i < N+1; i++) {
                    skipped[i] = true;
                    retFlag = false;
                    it = 0;
                    go(N + skip - 1, 0, 0, 0, skip);
                    skipped[i] = false;
                }
            } else {
                retFlag = false;
                it = 0;
                go(N + skip - 1, 0, 0, 0, skip);
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        new Solution().doMain();
    }
}