Problem: Nauuo is a girl who loves playing chess.

One day she invented a game by herself which needs n chess pieces to play on a m× m chessboard. The rows and columns are numbered from 1 to m. We denote a cell on the intersection of the r-th row and c-th column as (r,c).

The game's goal is to place n chess pieces numbered from 1 to n on the chessboard, the i-th piece lies on (r_i,\,c_i), while the following rule is satisfied: for all pairs of pieces i and j, |r_i-r_j|+|c_i-c_j|≥|i-j|. Here |x| means the absolute value of x.

However, Nauuo discovered that sometimes she couldn't find a solution because the chessboard was too small.

She wants to find the smallest chessboard on which she can put n pieces according to the rules.

She also wonders how to place the pieces on such a chessboard. Can you help her?

Input

The only line contains a single integer n (1≤ n≤ 1000) — the number of chess pieces for the game.

Output

The first line contains a single integer — the minimum value of m, where m is the length of sides of the suitable chessboard.

The i-th of the next n lines contains two integers r_i and c_i (1≤ r_i,c_i≤ m) — the coordinates of the i-th chess piece.

If there are multiple answers, print any.

Examples

Input


2


Output


2
1 1
1 2

Input


4


Output


3
1 1
1 3
3 1
3 3

Note

In the first example, you can't place the two pieces on a 1×1 chessboard without breaking the rule. But you can place two pieces on a 2×2 chessboard like this:

<image>

In the second example, you can't place four pieces on a 2×2 chessboard without breaking the rule. For example, if you place the pieces like this:

<image>

then |r_1-r_3|+|c_1-c_3|=|1-2|+|1-1|=1, |1-3|=2, 1<2; and |r_1-r_4|+|c_1-c_4|=|1-2|+|1-2|=2, |1-4|=3, 2<3. It doesn't satisfy the rule.

However, on a 3×3 chessboard, you can place four pieces like this:

<image>

Solution (in JAVA):

Solution:
import java.io.*;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.text.NumberFormat;
import java.util.*;

public class Main {
    InputStream is;
    PrintWriter out;
    String INPUT = "";

    class Info implements Comparable {
        int x;
        int y;
        int z;
        int go = 0;

        public Info(int x, int y, int z, int go) {
            this.x = x;
            this.y = y;
            this.z = z;
            this.go = go;
        }

        public int hashCode() {
            return (int) (x * 37 + 11 * y + z);
        }

        public boolean equals(Object o) {
            Info pr = (Info) o;

            return x == pr.x && y == pr.y && z == pr.z;
        }

        @Override
        public int compareTo(Object o) {
            Info pr = (Info) o;
            return x == pr.x ? Double.compare(y, pr.y) : Double.compare(x, pr.x);
        }

        public int dis(Info o) {
            return (o.x - x) * (o.x - x) + (o.y - y) * (o.y - y) + (o.z - z) * (o.z - z);
        }
    }

    class Tuple implements Comparable {
        int x;
        int y;
        double z;

        public Tuple(int x, int y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public int hashCode() {
            return (int) (x * 37 + 11 * y + z);
        }

        public boolean equals(Object o) {
            Tuple pr = (Tuple) o;
            return x == pr.x && y == pr.y && z == pr.z;
        }

        @Override
        public int compareTo(Object o) {
            Tuple pr = (Tuple) o;
            return x == pr.x ? (y == pr.y ? Double.compare(z, pr.z) : Integer.compare(y, pr.y)) : Integer.compare(x, pr.x);
        }


    }


    class Pair implements Comparable {
        double x;
        int y;

        public Pair(double x, int y) {
            this.x = x;
            this.y = y;
        }

        public int hashCode() {
            return (int) (x * 37 + y);
        }

        public boolean equals(Object o) {
            Pair pr = (Pair) o;

            return x == pr.x && y == pr.y;
        }

        @Override
        public int compareTo(Object o) {
            Pair pr = (Pair) o;
            return Double.compare(x, pr.x);
        }
    }


    class Edge {
        int x;
        int y;
        int score1;
        int score2;

        public Edge(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    int rk = 0;

    void dfs(int c, int b, Edge[] es, int n) {
        if (c == b) {
            int val[][] = new int[n][2];
            for (int i = 0; i < n; ++i) {
                val[i][1] = i;
            }


            int win[] = new int[n];
            for (int j = 0; j < b; ++j) {
                int x = es[j].x;
                int y = es[j].y;
                if (es[j].score1 == 1) {
                    val[x][0] += 1;
                    val[y][0] += 1;
                } else if (es[j].score1 == 3) {
                    val[x][0] += 3;
                    win[x]++;
                } else if (es[j].score1 == -3) {
                    val[y][0] += 3;
                    win[y]++;
                }
                if (es[j].score2 == 1) {
                    val[x][0] += 1;
                    val[y][0] += 1;
                } else if (es[j].score2 == 3) {
                    val[x][0] += 3;
                    win[x]++;
                } else if (es[j].score2 == -3) {
                    val[y][0] += 3;
                    win[y]++;
                }
            }

            for (int i = 1; i < n; ++i) {
                if (win[i] >= win[0]) return;
            }

            Arrays.sort(val, (x, y) -> {
                return y[0] - x[0];
            });

            for (int i = 0; i < n; ++i) {
                if (val[i][1] == 0) {
                    rk = Math.max(rk, i + 1);
                    break;
                }
            }
            return;
        }
        int v[] = {3, -3, 1};
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                es[c].score1 = v[i];
                es[c].score2 = v[j];
                dfs(c + 1, b, es, n);
            }
        }


    }


    void solvex() {
        String sp = ns();
        long x = Long.parseLong(sp.split("\\+")[0]);
        long y = Long.parseLong(sp.split("\\+")[1]);
        sp = ns();
        long h = Long.parseLong(sp.split("\\+")[0]);
        long d = Long.parseLong(sp.split("\\+")[1]);
        long lo = max(x, h);
        long hi = min(x + y, h + d);
        if (lo < hi) {
            out.println(0);
        } else {
            long dd = (hi - lo);
            BigDecimal bd = new BigDecimal(dd);
            BigDecimal f = bd.multiply(bd);
            BigDecimal re = f.divide(new BigDecimal(y)).divide(new BigDecimal(d));
            BigDecimal res = re.setScale(2, BigDecimal.ROUND_HALF_DOWN);
            out.println(res);
        }

    }


    void solve22() {
        int n = ni();
        List<Tuple> li = new ArrayList<>();
        while (n-- > 0) {
            int id = ni();
            int len = ni();
            double f = nd();
            li.add(new Tuple(id, len, f));
        }
        int pos = ni();
        Collections.sort(li, (a, b) -> {
            return Double.compare((double) a.y * b.z, (double) b.y * a.z);
        });
        out.println(li.get(pos - 1).x);
    }


    long s(long x, long n, long a) {
        if (a == 0) return Long.MAX_VALUE;
        if (a > 0) {
            return (n - x) / a;
        } else {
            return (x - 1) / (-a);
        }
    }


    long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }


    void rotate(char[][] c) {
        int l = c.length;
        for (int i = 0; i < l; ++i) {
            for (int j = 0; j < l - i; ++j) {
                char t = c[i][j];
                c[i][j] = c[l - 1 - j][l - 1 - i];
                c[l - 1 - j][l - 1 - i] = t;
            }
        }

        for (int j = 0; j < l; ++j) {
            for (int i = 0; i < l / 2; ++i) {
                char t = c[i][j];
                c[i][j] = c[l - 1 - i][j];
                c[l - 1 - i][j] = t;
            }
        }


    }

    boolean ok(char[][] mp, char[][] ck, int i, int j) {
        boolean ok = true;
        for (int a = 0; a < 3; ++a) {
            for (int b = 0; b < 3; ++b) {
                if (mp[i + a][j + b] != ck[a][b]) {
                    return false;
                }
            }

        }
        return true;
    }

    boolean ok(char[] a, char[] b) {
        int p = 0;
        for (char c : b) {
            if (p < a.length && a[p] == c) {
                ++p;
            }
        }
        return p == a.length;
    }

///与Eratosthenes筛法不同的是，对于外层枚举i，无论i是质数，还是是合数，我们都会用i的倍数去筛。但在枚举的时候，我们只枚举i的质数倍。比如2i,3i,5i,...，而不去枚举4i,6i...，原因我们后面会讲到。
//
//    此外，在从小到大依次枚举质数p来计算i的倍数时，我们还需要检查i是否能够被p整除。若i能够被p整除，则停止枚举。
//
//    利用该算法，可以保证每个合数只会被枚举到一次。我们可以证明如下命题：
//
//    假设一个合数k=M*p1，p1为其最小的质因子。则k只会在i=M，primeList[j]=p1时被筛掉一次。
//
//    首先会在i=M，primeList[j]=p1时被筛掉是显然的。因为p1是k的最小质因子，所以i=M的所有质因子也≥p1。于是j循环在枚举到primeList[j]=p1前不会break，从而一定会在i=M，primeList[j]=p1时被筛掉
//
//    其次不会在其他时候被筛掉。否则假设k在i=N, primeList[j]=p2时被筛掉了，此时有k=N*p2。由于p1是k最小的质因子，所以p2 > p1，M > N且p1|N。则i=N，j枚举到primeList[j]=p1时(没到primeList[j]=p2)就break了。所以不会有其他时候筛掉k。
//
//    同时，不枚举合数倍数的原因也在此：对于一个合数k=M*2*3。只有在枚举到i=M*3时，才会计算到k。若我们枚举合数倍数，则可能会在i=M时，通过M*6计算到k，这样也就造成了多次重复计算了。
    boolean[] euler(int maxn) {

        int prime[] = new int[maxn + 1];
        boolean visit[] = new boolean[maxn + 1];

        for (int i = 2; i <= maxn; i++) {
            if (!visit[i]) {
                prime[++prime[0]] = i;
            }
            for (int j = 1; j <= prime[0] && i * prime[j] <= maxn; j++) {

                visit[i * prime[j]] = true;
                if (i % prime[j] == 0) {
                    break;
                }
            }
        }
        return visit;
    }

    long mod_pow(long k,long n,long p){
        long res = 1L;
        long temp = k%p;
        while(n!=0){
            long ck = n&1L;
            if(ck==1L){
                res *= temp;
                res %= p;
            }
            temp = temp*temp;
            temp %= p;
            n = n>>>1L;
        }
        return res%p;
    }



    void solve() {
        int n = ni();
        int nn = n+1;
        int m = nn/2;
        if(2*m<nn){
            ++m;
        }
        out.println(m);

        for(int i=1;i<=n;++i){
            if(i<=m){
                out.println(1+" "+i);
            }else{
                out.println(m+" "+(i-m+1));
            }


        }




    }


    void solve2134() {
        int c = 1;
        while (true) {
            int t = ni();
            if (t == 0) return;

            int a[] = new int[t];

            for (int i = 0; i < t; ++i) {
                a[i] = ni();
            }

            int m = 0;

            int s[] = new int[8];

            //dfs();


            out.println("Case " + c + ":");
            out.println(m);
            for (int i = 0; i <= m; ++i) {

            }
            ++c;
        }
    }


    void solve1111() {

        while (true) {
            int n = ni();
            if (n == 0) return;
            long a[] = new long[n];
            for (int i = 0; i < n; ++i) {
                a[i] = nl();
            }

            long x = -a[0];
            long res = Math.abs(x);

            for (int i = 1; i < n; ++i) {
                x = x - a[i];
                res += Math.abs(x);

            }

            out.println(res);


        }
    }

    String round(double v) {
        return new java.text.DecimalFormat("#0.0000").format(v);
    }

    int max(int... a) {
        int x = a[0];
        int len = a.length;
        for (int i = 1; i < len; ++i) {
            x = Math.max(x, a[i]);
        }
        return x;
    }

    long max(long... a) {
        long x = a[0];
        int len = a.length;
        for (int i = 1; i < len; ++i) {
            x = Math.max(x, a[i]);
        }
        return x;
    }

    int min(int... a) {
        int x = a[0];
        int len = a.length;
        for (int i = 1; i < len; ++i) {
            x = Math.min(x, a[i]);
        }
        return x;
    }

    long min(long... a) {
        long x = a[0];
        int len = a.length;
        for (int i = 1; i < len; ++i) {
            x = Math.min(x, a[i]);
        }
        return x;
    }

    int abs(int a) {
        return Math.abs(a);
    }

    long abs(long a) {
        return Math.abs(a);
    }


    void run() throws Exception {
        is = System.in;
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        solve();
        out.flush();
        //tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private String nline() {
        StringBuilder sb = new StringBuilder();
        while (true) {
            int b = readByte();
            if (b == -1) {
                return "";
            }
            if (b == '\n') {
                return sb.toString();
            }
            sb.append((char) b);
        }
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = (num << 3) + (num << 1) + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (!oj) System.out.println(Arrays.deepToString(o));
    }
}