Problem: Fox Ciel wants to write a task for a programming contest. The task is: "You are given a simple undirected graph with n vertexes. Each its edge has unit length. You should calculate the number of shortest paths between vertex 1 and vertex 2."

Same with some writers, she wants to make an example with some certain output: for example, her birthday or the number of her boyfriend. Can you help her to make a test case with answer equal exactly to k?

Input

The first line contains a single integer k (1 ≤ k ≤ 109).

Output

You should output a graph G with n vertexes (2 ≤ n ≤ 1000). There must be exactly k shortest paths between vertex 1 and vertex 2 of the graph.

The first line must contain an integer n. Then adjacency matrix G with n rows and n columns must follow. Each element of the matrix must be 'N' or 'Y'. If Gij is 'Y', then graph G has a edge connecting vertex i and vertex j. Consider the graph vertexes are numbered from 1 to n.

The graph must be undirected and simple: Gii = 'N' and Gij = Gji must hold. And there must be at least one path between vertex 1 and vertex 2. It's guaranteed that the answer exists. If there multiple correct answers, you can output any of them. 

Examples

Input

2

Output

4
NNYY
NNYY
YYNN
YYNN

Input

9

Output

8
NNYYYNNN
NNNNNYYY
YNNNNYYY
YNNNNYYY
YNNNNYYY
NYYYYNNN
NYYYYNNN
NYYYYNNN

Input

1

Output

2
NY
YN

Note

In first example, there are 2 shortest paths: 1-3-2 and 1-4-2.

In second example, there are 9 shortest paths: 1-3-6-2, 1-3-7-2, 1-3-8-2, 1-4-6-2, 1-4-7-2, 1-4-8-2, 1-5-6-2, 1-5-7-2, 1-5-8-2.

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;
/*
    @author Mikhail Linkov
 */

public class TaskD {
    public void solve() {
        InputReader reader = new InputReader(System.in);
        PrintWriter writer = new PrintWriter(System.out, true);

        int n = reader.nextInt();

        int [][] answer = new int[1000][1000];
        boolean [] isFree = new boolean[1000];
        Arrays.fill(isFree, true);

        int count = 0;
        int maxLength = -1;

        while (count < n) {
            List<Integer> previous = new ArrayList<Integer>();
            previous.add(0);
            int subSum = 1;
            int length = 0;
            while (true) {
                boolean isExecute = false;
                length++;
                if (length != maxLength) {
                    for (int i = 70; i > 1; i--) {
                        if ((long) i * subSum <= n - count) {
                            subSum *= i;
                            List<Integer> newVertexes = new ArrayList<Integer>();
                            for (int j = 2; j < 1000; j++) {
                                if (isFree[j]) {
                                    isFree[j] = false;
                                    newVertexes.add(j);
                                    for (int vertex : previous) {
                                        answer[vertex][j] = 1;
                                        answer[j][vertex] = 1;
                                    }
                                }
                                if (newVertexes.size() == i) {
                                    previous = newVertexes;
                                    isExecute = true;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
                if (!isExecute) {
                    if (length >= maxLength) {
                        for (int vertex : previous) {
                            answer[vertex][1] = 1;
                            answer[1][vertex] = 1;
                        }
                        break;
                    } else {
                        List<Integer> newVertexes = new ArrayList<Integer>();
                        for (int j = 2; j < 1000; j++) {
                            if (isFree[j]) {
                                isFree[j] = false;
                                newVertexes.add(j);
                                for (int vertex : previous) {
                                    answer[vertex][j] = 1;
                                    answer[j][vertex] = 1;
                                }
                                previous = newVertexes;
                                break;
                            }
                        }
                    }
                }


            }
            maxLength = length;
            count += subSum;
        }

        writer.println(1000);
        for (int i = 0; i < 1000; i++) {
            for (int j = 0; j < 1000; j++) {
                if (answer[i][j] == 1) {
                    writer.print("Y");
                } else {
                    writer.print("N");
                }
            }
            writer.println();
        }

        writer.close();
    }

    public static void main(String[] args) {
        new TaskD().solve();
    }

    private class InputReader {
        private BufferedReader reader;
        private StringTokenizer token;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            if (token == null || !token.hasMoreElements()) {
                try {
                    token = new StringTokenizer(reader.readLine(), " ");
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return token.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(this.next());
        }

        public double nextDouble() {
            return Double.parseDouble(this.next());
        }

        public long nextLong() {
            return Long.parseLong(this.next());
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}