First-rate specialists graduate from Berland State Institute of Peace and Friendship. You are one of the most talented students in this university. The education is not easy because you need to have fundamental knowledge in different areas, which sometimes are not related to each other. 

For example, you should know linguistics very well. You learn a structure of Reberland language as foreign language. In this language words are constructed according to the following rules. First you need to choose the "root" of the word — some string which has more than 4 letters. Then several strings with the length 2 or 3 symbols are appended to this word. The only restriction —  it is not allowed to append the same string twice in a row. All these strings are considered to be suffixes of the word (this time we use word "suffix" to describe a morpheme but not the few last characters of the string as you may used to). 

Here is one exercise that you have found in your task list. You are given the word s. Find all distinct strings with the length 2 or 3, which can be suffixes of this word according to the word constructing rules in Reberland language. 

Two strings are considered distinct if they have different length or there is a position in which corresponding characters do not match. 

Let's look at the example: the word abacabaca is given. This word can be obtained in the following ways: <image>, where the root of the word is overlined, and suffixes are marked by "corners". Thus, the set of possible suffixes for this word is {aca, ba, ca}. 

Input

The only line contains a string s (5 ≤ |s| ≤ 104) consisting of lowercase English letters.

Output

On the first line print integer k — a number of distinct possible suffixes. On the next k lines print suffixes. 

Print suffixes in lexicographical (alphabetical) order. 

Examples

Input

abacabaca


Output

3
aca
ba
ca


Input

abaca


Output

0

Note

The first test was analysed in the problem statement. 

In the second example the length of the string equals 5. The length of the root equals 5, so no string can be used as a suffix.
// package RatingBased.R1800;
import java.io.*;
import java.util.*;

/*
    Author - Ribhav
    MADE ON - 1/2/2019
*/

public class CF666A {
    static FastReader s;
    static PrintWriter out;
    static String INPUT = "abcdeabzzzzzzzz\n";
    static TreeSet<String> set;
    static int[] bool;

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        boolean oj = System.getProperty("ONLINE_JUDGE") != null;
        out = new PrintWriter(System.out);
        s = new FastReader(oj);

        String str = s.next();

        if(str.length() < 7){
            System.out.println(0);
            return;
        }

        set = new TreeSet<>();
        bool = new int[str.length()];
        func(new StringBuilder(str.substring(5)).reverse().toString(), null, 0);
        out.println(set.size());

//        out.println(set);
        Iterator<String> iter = set.iterator();
        StringBuilder ans = new StringBuilder();
        while(iter.hasNext()){
            String s1 = iter.next();
            ans.append(s1);
            ans.append("\n");
        }
        out.println(ans.toString());



        if (!oj) {
            System.out.println(Arrays.deepToString(new Object[]{System.currentTimeMillis() - time + " ms"}));
        }
        out.flush();
    }

    private static void func(String str, String prev, int start) {
        if(prev == null){
            if(str.length() == 2) {
                set.add(new StringBuilder(str).reverse().toString());
            } else {
                String str1 = new StringBuilder(str.substring(0,2)).reverse().toString();
                String str2 = new StringBuilder(str.substring(0,3)).reverse().toString();
                func(str.substring(2), str1, start + 2);
                set.add(str1);
                bool[start] = 1;
                func(str.substring(3), str2, start + 3);
                set.add(str2);
                bool[start] = 2;
            }
            return;
        }
        if(str.length() == 1 || str.length() == 0){
            return;
        }
        if(bool[start] == 2){
            return;
        }
        int len = prev.length();
        String str1 = new StringBuilder(str.substring(0,2)).reverse().toString();
        if(len == 2){
            if(str1.equals(prev)) {
                if(str.length() >= 3) {
                    String str2 = new StringBuilder(str.substring(0,3)).reverse().toString();
                    func(str.substring(3), str2, start + 3);
                    set.add(str2);
                }
                bool[start] = 1;
                return;
            }else {
                func(str.substring(2), str1, start + 2);
                set.add(str1);
                bool[start] = 1;
                if(str.length() >= 3) {
                    String str2 = new StringBuilder(str.substring(0,3)).reverse().toString();
                    func(str.substring(3), str2, start + 3);
                    set.add(str2);
                }
                bool[start] = 2;
            }
        } else {
            if(str.length() >= 3) {
                String str2 = new StringBuilder(str.substring(0,3)).reverse().toString();
                if(str2.equals(prev)) {
                    func(str.substring(2), str1,start + 2);
                    set.add(str1);
                    bool[start] = 1;
                    return;
                } else {
                    func(str.substring(2), str1, start + 2);
                    set.add(str1);
                    bool[start] = 1;
                    func(str.substring(3), str2,start + 3);
                    set.add(str2);
                    bool[start] = 2;
                }
            } else {
                func(str.substring(2), str1,start + 2);
                set.add(str1);
                bool[start] = 2;
            }
        }

    }


    static ArrayList<Long> printDivisors(long n) {
        // Note that this loop runs till square root
        ArrayList<Long> list = new ArrayList<>();
        for (long i = 1; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                if (n / i == i) {
                    list.add(i);
                } else {
                    list.add(i);
                    list.add(n / i);
                }
            }
        }
        return list;
    }


    //    GCD - Using Euclid theorem.
    private static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }

        return gcd(b, a % b);
    }

    //    Extended euclidean algorithm
//    Used to solve equations of the form ax + by = gcd(a,b)
//    return array [d, a, b] such that d = gcd(p, q), ap + bq = d
    static long[] extendedEuclidean(long p, long q) {
        if (q == 0)
            return new long[]{p, 1, 0};

        long[] vals = extendedEuclidean(q, p % q);
        long d = vals[0];
        long a = vals[2];
        long b = vals[1] - (p / q) * vals[2];
        return new long[]{d, a, b};
    }

    // X ^ y mod p
    static long power(long x, long y, long p) {
        long res = 1;
        x = x % p;

        while (y > 0) {
            if ((y & 1) == 1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

    // Returns modulo inverse of a
    // with respect to m using extended
    // Euclid Algorithm. Refer below post for details:
    // https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
    static long inv(long a, long m) {
        long m0 = m, t, q;
        long x0 = 0, x1 = 1;

        if (m == 1)
            return 0;

        // Apply extended Euclid Algorithm
        while (a > 1) {
            q = a / m;
            t = m;
            m = a % m;
            a = t;
            t = x0;
            x0 = x1 - q * x0;
            x1 = t;
        }

        // Make x1 positive
        if (x1 < 0)
            x1 += m0;

        return x1;
    }

    // k is size of num[] and rem[].
    // Returns the smallest number
    // x such that:
    // x % num[0] = rem[0],
    // x % num[1] = rem[1],
    // ..................
    // x % num[k-2] = rem[k-1]
    // Assumption: Numbers in num[] are pairwise
    // coprime (gcd for every pair is 1)
    static long findMinX(long num[], long rem[], long k) {
        int prod = 1;
        for (int i = 0; i < k; i++)
            prod *= num[i];

        int result = 0;
        for (int i = 0; i < k; i++) {
            long pp = prod / num[i];
            result += rem[i] * inv(pp, num[i]) * pp;
        }

        return result % prod;
    }

    //  Binary search
    private static int binarySearch(int[] arr, int ele) {
        int low = 0;
        int high = arr.length - 1;
        while (low <= high) {
            int mid = (low + high) / 2;
            if (arr[mid] == ele) {
                return mid;
            } else if (ele < arr[mid]) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return -1;
    }

    //    First occurence using binary search
    private static int binarySearchFirstOccurence(int[] arr, int ele) {
        int low = 0;
        int high = arr.length - 1;
        int ans = -1;
        while (low <= high) {
            int mid = (low + high) / 2;
            if (arr[mid] == ele) {
                ans = mid;
                high = mid - 1;
            } else if (ele < arr[mid]) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return ans;
    }


    //    Last occurenece using binary search
    private static int binarySearchLastOccurence(int[] arr, int ele) {
        int low = 0;
        int high = arr.length - 1;
        int ans = -1;
        while (low <= high) {
            int mid = (low + high) / 2;
            if (arr[mid] == ele) {
                ans = mid;
                low = mid + 1;
            } else if (ele < arr[mid]) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return ans;
    }


    // Merge sort
    static void merge(int arr[], int l, int m, int r) {
        int n1 = m - l + 1;
        int n2 = r - m;
        int L[] = new int[n1];
        int R[] = new int[n2];
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];
        int i = 0, j = 0;
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    static void sort(int arr[], int l, int r) {
        if (l < r) {
            int m = (l + r) / 2;
            sort(arr, l, m);
            sort(arr, m + 1, r);
            merge(arr, l, m, r);
        }
    }

    static void sort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    static class FastReader {
        InputStream is;

        public FastReader(boolean oj) {
            is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        }

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

        public 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++];
        }

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

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

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

        public char nextChar() {
            return (char) skip();
        }

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

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

        public char[] next(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);
        }

        public int nextInt() {
            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 * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            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();
            }
        }

        public char[][] nextMatrix(int n, int m) {
            char[][] map = new char[n][];
            for (int i = 0; i < n; i++)
                map[i] = next(m);
            return map;
        }

        public int[] nextIntArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public long[] nextLongArray(int n) {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }

        public int[][] next2DInt(int n, int m) {
            int[][] arr = new int[n][];
            for (int i = 0; i < n; i++) {
                arr[i] = nextIntArray(m);
            }
            return arr;
        }

        public long[][] next2DLong(int n, int m) {
            long[][] arr = new long[n][];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLongArray(m);
            }
            return arr;
        }

        public int[] shuffle(int[] arr) {
            Random r = new Random();
            for (int i = 1, j; i < arr.length; i++) {
                j = r.nextInt(i);
                arr[i] = arr[i] ^ arr[j];
                arr[j] = arr[i] ^ arr[j];
                arr[i] = arr[i] ^ arr[j];
            }
            return arr;
        }

        public int[] uniq(int[] arr) {
            Arrays.sort(arr);
            int[] rv = new int[arr.length];
            int pos = 0;
            rv[pos++] = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] != arr[i - 1]) {
                    rv[pos++] = arr[i];
                }
            }
            return Arrays.copyOf(rv, pos);
        }

    }
}

/*





*/
