You are given n segments on the Ox-axis. You can drive a nail in any integer point on the Ox-axis line nail so, that all segments containing this point, are considered nailed down. If the nail passes through endpoint of some segment, this segment is considered to be nailed too. What is the smallest number of nails needed to nail all the segments down?

Input

The first line of the input contains single integer number n (1 ≤ n ≤ 1000) — amount of segments. Following n lines contain descriptions of the segments. Each description is a pair of integer numbers — endpoints coordinates. All the coordinates don't exceed 10000 by absolute value. Segments can degenarate to points.

Output

The first line should contain one integer number — the smallest number of nails needed to nail all the segments down. The second line should contain coordinates of driven nails separated by space in any order. If the answer is not unique, output any.

Examples

Input

2
0 2
2 5


Output

1
2 

Input

5
0 3
4 2
4 8
8 10
7 7


Output

3
7 10 3
import java.util.ArrayList;
import java.util.Scanner;

public class Segment {

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int pointNumber = scan.nextInt();

        Node root = null;
        for (int i = 0; i < pointNumber; i++) {
            int x1 = scan.nextInt();
            int x2 = scan.nextInt();

            Point point = new Point(x1, x2);

            if (point.getX1() > point.getX2())
                point.swap();

            if (i == 0)
                root = new Node(point);
            else {
                insertPoint(root, point);
            }
        }

        Node temp = root;
        StringBuilder nailCoordinate = new StringBuilder();
        ArrayList<Point> sameNailStack = new ArrayList();
        int nailCounter = 0;
        while (temp != null) {
            Point p = temp.getData();
            if (checkPointInStackRange(sameNailStack, p)) {
                sameNailStack.add(p);
                temp = temp.getNext();
            } else {
                nailCoordinate.append(getNailCoordinate(sameNailStack)).append(" ");
                nailCounter++;
                sameNailStack.clear();
            }
        }
        if (sameNailStack.size() != 0) {
            nailCoordinate.append(getNailCoordinate(sameNailStack)).append(" ");
            nailCounter++;
            sameNailStack.clear();
        }
        System.out.println(nailCounter);
        System.out.println(nailCoordinate);
    }

    private static int getNailCoordinate(ArrayList<Point> sameNailStack) {
        final Point newPoint = new Point(-10000, 10000);

        sameNailStack.forEach(point -> newPoint.setX1(Math.max(newPoint.getX1(), point.getX1()))
                .setX2(Math.min(newPoint.getX2(), point.getX2())));
//
//        int tempX1 = sameNailStack.get(0).getX1();
//        int tempX2 = sameNailStack.get(0).getX2();
//        int result = tempX1;
////        sameNailStack.remove(0);
//
//        for (int i = 0; i < sameNailStack.size(); ) {
//            if (tempX1 >= sameNailStack.get(i).getX1() && tempX1 <= sameNailStack.get(i).getX2()) {
//                result = tempX1;
//                i++;
//            } else if (tempX2 >= sameNailStack.get(i).getX1() && tempX2 <= sameNailStack.get(i).getX2()) {
//                result = tempX2;
//                i++;
//            } else {
//                tempX1 = sameNailStack.get(i).getX1();
//                tempX2 = sameNailStack.get(i).getX2();
//            }
//        }
        return newPoint.getX1();
    }

    private static boolean checkPointInStackRange(ArrayList<Point> sameNailStack, Point p) {
        if (sameNailStack.size() == 0)
            return true;

        for (Point point : sameNailStack) {
            if (((p.getX1() < point.getX1() || p.getX1() > point.getX2())
                    && (p.getX2() > point.getX1() || p.getX2() > point.getX2()))) {
                return false;
            }
        }
        return true;
    }

    private static void insertPoint(Node node, Point point) {
        // point bigger than node's data
        if (point.getX1() > node.getData().getX1()
                && point.getX2() > node.getData().getX2()) {
            if (node.getNext() == null)
                node.setNext(new Node(point));
            else
                insertPoint(node.getNext(), point);
            // point smaller than node's data
        } else if (point.getX1() < node.getData().getX1()) {
            node.setNext(new Node(node.getData(), node.getNext())).setData(point);
            // point in between node's data
        } else {

            if (node.getNext() == null)
                node.setNext(new Node(point));
            else {
                insertPoint(node.getNext(), point); // test ,, the commented is tested
//                Node tempNode = node.getNext();
//                node.setNext(new Node(point, tempNode));
            }
        }
    }

    public static class Point {

        private int x1;
        private int x2;

        public Point(int x1, int x2) {
            this.x1 = x1;
            this.x2 = x2;
        }

        public int getX1() {
            return x1;
        }

        public Point setX1(int x1) {
            this.x1 = x1;
            return this;
        }

        public int getX2() {
            return x2;
        }

        public Point setX2(int x2) {
            this.x2 = x2;
            return this;
        }

        public void swap() {
            int temp = this.x1;
            this.x1 = this.x2;
            this.x2 = temp;
        }

        @Override
        public String toString() {
            return "Point{" + x1 +
                    ", " + x2 +
                    '}';
        }

    }

    public static class Node {

        private Point data;
        private Node next;

        public Node(Point data) {
            this.data = data;
            this.next = null;
        }

        public Node(Point data, Node next) {
            this.data = data;
            this.next = next;
        }

        public Point getData() {
            return data;
        }

        public Node setData(Point data) {
            this.data = data;
            return this;
        }

        public Node getNext() {
            return next;
        }

        public Node setNext(Node next) {
            this.next = next;
            return this;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "data=" + data.toString() +
                    ", next=" + (next != null ? next.toString() : " ") +
                    '}';
        }
    }
}
