Problem: Once Bob saw a string. It contained so many different letters, that the letters were marked by numbers, but at the same time each letter could be met in the string at most 10 times. Bob didn't like that string, because it contained repeats: a repeat of length x is such a substring of length 2x, that its first half coincides character by character with its second half. Bob started deleting all the repeats from the string. He does it as follows: while it's possible, Bob takes the shortest repeat, if it is not unique, he takes the leftmost one, and deletes its left half and everything that is to the left of this repeat.

You're given the string seen by Bob. Find out, what it will look like after Bob deletes all the repeats in the way described above.

Input

The first input line contains integer n (1 ≤ n ≤ 105) — length of the string. The following line contains n space-separated integer numbers from 0 to 109 inclusive — numbers that stand for the letters of the string. It's guaranteed that each letter can be met in the string at most 10 times.

Output

In the first line output the length of the string's part, left after Bob's deletions. In the second line output all the letters (separated by a space) of the string, left after Bob deleted all the repeats in the described way.

Examples

Input

6
1 2 3 1 2 3


Output

3
1 2 3 


Input

7
4 5 6 5 6 7 7


Output

1
7 

Solution (in JAVA):

Solution:
//package codeforces.practice.stringhashing;

import java.io.*;
import java.util.*;

public class DeletionOfRepeats {
    public static void main(String[] args) {
//        try {
//            FastScanner in = new FastScanner(new FileInputStream("src/input.in"));
//            PrintWriter out = new PrintWriter(new FileOutputStream("src/output.out"));

        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

            solve(1, in, out);

//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    private static void solve(int q, FastScanner in, PrintWriter out) {
        for (int qq = 0; qq < q; qq++) {
            int n = in.nextInt();
            Long[] a = in.nextLongArray(n);
            long[] hash_value = new long[n];
            long[] p_pow = new long[n];
            long p = (long)1e5 + 9, mod = (long)1e9 + 7;

            hash_value[0] = a[0];
            p_pow[0] = 1;
            for(int i = 1; i < n; i++) {
                p_pow[i] = p_pow[i - 1] * p % mod;
            }
            for(int i = 1; i < n; i++) {
                hash_value[i] = (hash_value[i - 1] + a[i] * p_pow[i]) % mod;
            }

            //get a map from an integer to the list of all its indices
            Map<Long, List<Integer>> map = new HashMap<>();
            for(int i = 0; i < n; i++) {
                map.computeIfAbsent(a[i], k -> new ArrayList<>()).add(i);
            }
            List<int[]> intervals = new ArrayList<>();
            for(Map.Entry<Long, List<Integer>> e : map.entrySet()) {
                List<Integer> list = e.getValue();
                for(int i = 0; i < list.size(); i++) {
                    int l = list.get(i);
                    for(int j = i + 1; j < list.size(); j++) {
                        int r = list.get(j);
                        if(n - r >= r - l) {
                            long hv1 = (hash_value[r - 1] - (l > 0 ? hash_value[l - 1] : 0) + mod) % mod;
                            long hv2 = (hash_value[r * 2 - l - 1] - (r > 0 ? hash_value[r - 1] : 0) + mod) % mod;
                            if(hv1 * p_pow[r - l] % mod == hv2) {
                                intervals.add(new int[]{l, r - 1});
                            }
                        }
                    }
                }
            }
            Collections.sort(intervals, (i1, i2) -> {
                if(i1[1] - i1[0] != i2[1] - i2[0]) {
                    return i1[1] - i1[0] - (i2[1] - i2[0]);
                }
                return i1[0] - i2[0];
            });
            int start = 0;
            for(int i = 0; i < intervals.size(); i++) {
                //if the remaining string's start index is at most the current 1st half's start
                if(start <= intervals.get(i)[0]) {
                    start = intervals.get(i)[1] + 1;
                }
            }
            out.println(n - start);
            for(int i = start; i < n; i++) {
                out.print(a[i] + " ");
            }
        }
        out.close();
    }

    private static class BinarySearch {
        // return the right most index i such that a[i] <= t
        private static int rightMostUpperBound(Integer[] a, int t) {
            int l = 0, r = a.length - 1;
            while (l < r - 1) {
                int mid = l + (r - l) / 2;
                if (a[mid] <= t) {
                    l = mid;
                } else {
                    r = mid - 1;
                }
            }
            if (a[r] <= t) {
                return r;
            } else if (a[l] <= t) {
                return l;
            }
            return -1;
        }

        // return the left most index i such that a[i] >= t
        private static int leftMostLowerBound(Integer[] a, int t) {
            int l = 0, r = a.length - 1;
            while (l < r - 1) {
                int mid = l + (r - l) / 2;
                if (a[mid] >= t) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            if (a[l] >= t) {
                return l;
            } else if (a[r] >= t) {
                return r;
            }
            return -1;
        }

        // Find the start and end index of a given t in a sorted(ascending) array; return [-1, -1] is t is not found
        private static int[] searchRange(Integer[] a, int t) {
            int first = firstPos(a, t);
            int last = firstPos(a, t + 1) - 1;
            if (first <= last) {
                return new int[]{first, last};
            }
            return new int[]{-1, -1};
        }

        private static int firstPos(Integer[] a, int t) {
            int first = a.length;
            int l = 0, r = a.length - 1;
            while (l <= r) {
                int mid = l + (r - l) / 2;
                if (a[mid] >= t) {
                    first = mid;
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            return first;
        }
    }

    private static class NumberTheory {
        private static long modularAdd(long a, long b, int mod) {
            long sum = a + b;
            if (sum >= mod) {
                sum -= mod;
            }
            return sum;
        }

        private static long modularSubtract(long a, long b, int mod) {
            long diff = a - b;
            if (diff < 0) {
                diff += mod;
            }
            return diff;
        }

        private static long fastModPow(long x, int n, long mod) {
            if (n == 0) {
                return 1;
            }
            long coeff = 1, base = x;
            while (n > 1) {
                if (n % 2 != 0) {
                    coeff = (coeff * base % mod);
                }
                base = (base * base % mod);
                n = n / 2;
            }
            long res = coeff * base % mod;
            return res;
        }

        private static long gcd(long a, long b) {
            if (b == 0) {
                return a;
            }
            return gcd(b, a % b);
        }

        private static long[] factorial(int n, long mod) {
            long[] factor = new long[n + 1];
            factor[0] = 1;
            for (int i = 1; i <= n; i++) {
                factor[i] = factor[i - 1] * i % mod;
            }
            return factor;
        }

        private static long modInv_EEA(long a, long mod) {
            long[] res = solveGcdEquation(a, mod);
            if (res[2] != 1) {
                // a and m are not coprime, modular inverse of a by m does not exist.
                return -1;
            }
            return (res[0] % mod + mod) % mod;
        }

        private static long[] solveGcdEquation(long a, long b) {
            if (b == 0) {
                return new long[]{1, 0, a};
            }
            long[] res = solveGcdEquation(b, a % b);
            return new long[]{res[1], res[0] - (a / b) * res[1], res[2]};
        }

        private static long binomialCoefficient(long[] factorial, long n, long k, long mod) {
            return factorial[(int) n] * modInv_EEA(factorial[(int) k], mod) % mod
                    * modInv_EEA(factorial[(int) (n - k)], mod) % mod;
        }
    }

    private static class Graph {
        private static int UNVISITED = 0;
        private static int VISITING = -1;
        private static int VISITED = 1;

        private static Stack<Integer> topologicalSort(Set<Integer>[] g) {
            Stack<Integer> stack = new Stack<>();
            int[] state = new int[g.length];

            for (int node = 0; node < g.length; node++) {
                if (!topoSortHelper(g, stack, state, node)) {
                    return null;
                }
            }
            return stack;
        }

        private static boolean topoSortHelper(Set<Integer>[] g, Stack<Integer> stack, int[] state, int currNode) {
            if (state[currNode] == VISITED) {
                return true;
            } else if (state[currNode] == VISITING) {
                return false;
            }
            state[currNode] = VISITING;
            for (int neighbor : g[currNode]) {
                if (!topoSortHelper(g, stack, state, neighbor)) {
                    return false;
                }
            }
            state[currNode] = VISITED;
            stack.push(currNode);
            return true;
        }
    }

    private static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

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

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