import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.*;

public class easy_gk_ok_rounding {
    private static final double EPS = 1e-5;
    static Scanner in;
    static PrintWriter out;

    final List<Segment> minmin = new ArrayList<>();
    final List<Segment> minmax = new ArrayList<>();
    final List<Segment> maxmin = new ArrayList<>();
    final List<Segment> maxmax = new ArrayList<>();
    double minX, minY, maxX, maxY;

    static class Segment {
        final int minx, maxx, miny, maxy;

        Segment(int minx, int miny, int maxx, int maxy) {
            this.minx = minx;
            this.miny = miny;
            this.maxx = maxx;
            this.maxy = maxy;
        }

        double y(double x) {
            return (miny * (maxx - x) - maxy * (minx - x)) / (maxx - minx);
        }
    }

    void run() throws Exception {
        int n = in.nextInt();

        int[] x = new int[n + 1];
        int[] y = new int[n + 1];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        x[n] = x[0];
        y[n] = y[0];

        solve(n, x, y);
        Locale.setDefault(Locale.US);
        out.format("%.6f %.6f %.6f %.6f%n", minX, minY, maxX, maxY);
    }

    void solve(int n, int[] x, int[] y) {
        classifySegments(n, x, y);

        double l = 0;
        double r = maxmax.get(maxmax.size() - 1).maxx - minmin.get(0).minx;
        while (r - l > EPS) {
            double m1 = l + (r - l) / 3;
            double m2 = r - (r - l) / 3;
            if (area(m1) < area(m2)) {
                l = m1;
            } else {
                r = m2;
            }
        }
        area((l + r) / 2);
    }

    void classifySegments(int n, int[] x, int[] y) {
        int i = 0;
        while (y[(i + 1) % n] <= y[i] || y[i] > y[(i - 1 + n) % n]) i = (i + 1) % n;

        minmin.add(new Segment(x[i], y[i], x[i] + 1, y[i]));
        while (y[(i + 1) % n] > y[i] && x[(i + 1) % n] < x[i]) {
            minmin.add(new Segment(x[(i + 1) % n], y[(i + 1) % n], x[i], y[i]));
            i = (i + 1) % n;
        }
        Collections.reverse(minmin);

        while (x[(i + 1) % n] == x[i]) i = (i + 1) % n;

        while (y[(i + 1) % n] > y[i] && x[(i + 1) % n] > x[i]) {
            minmax.add(new Segment(x[i], y[i], x[(i + 1) % n], y[(i + 1) % n]));
            i = (i + 1) % n;
        }
        minmax.add(new Segment(x[i], y[i], x[i] + 1, y[i]));

        while (y[(i + 1) % n] == y[i]) i = (i + 1) % n;

        maxmax.add(new Segment(x[i] - 1, y[i], x[i], y[i]));
        while (y[(i + 1) % n] < y[i] && x[(i + 1) % n] > x[i]) {
            maxmax.add(new Segment(x[i], y[i], x[(i + 1) % n], y[(i + 1) % n]));
            i = (i + 1) % n;
        }

        while (x[(i + 1) % n] == x[i]) i = (i + 1) % n;
        while (y[(i + 1) % n] < y[i] && x[(i + 1) % n] < x[i]) {
            maxmin.add(new Segment(x[(i + 1) % n], y[(i + 1) % n], x[i], y[i]));
            i = (i + 1) % n;
        }
        maxmin.add(new Segment(x[i] - 1, y[i], x[i], y[i]));
        Collections.reverse(maxmin);
    }

    double area(double width) {
        double l = minmin.get(0).minx + width / 2;
        double r = maxmax.get(maxmax.size() - 1).maxx - width / 2;
        while (r - l > EPS) {
            double m1 = l + (r - l) / 3;
            double m2 = r - (r - l) / 3;
            if (section(width, m1) < section(width, m2)) {
                l = m1;
            } else {
                r = m2;
            }
        }
        return section(width, (l + r) / 2) * width;
    }

    double section(double width, double x) {
        minX = x - width / 2;
        maxX = x + width / 2;
        minY = Math.max(intersect(minmin, minX), intersect(maxmin, maxX));
        maxY = Math.min(intersect(minmax, minX), intersect(maxmax, maxX));
        return maxY - minY;
    }

    double intersect(List<Segment> segments, double x) {
        if (x <= segments.get(0).minx) {
            return segments.get(0).miny;
        }
        if (x >= segments.get(segments.size() - 1).maxx) {
            return segments.get(segments.size() - 1).maxy;
        }
        int l = 0;
        int r = segments.size() - 1;
        while (true) {
            int m = (l + r) / 2;
            Segment segment = segments.get(m);
            if (segment.maxx < x) {
                l = m + 1;
            } else if (x < segment.minx) {
                r = m - 1;
            } else {
                return segment.y(x);
            }
        }
    }

    static class Scanner {
        final BufferedReader reader;
        StringTokenizer tokenizer = new StringTokenizer("");

        public Scanner(File file) throws Exception {
            reader = new BufferedReader(new FileReader(file));
        }

        public int nextInt() throws Exception {
            while (!tokenizer.hasMoreTokens()) {
                tokenizer = new StringTokenizer(reader.readLine());
            }
            return Integer.parseInt(tokenizer.nextToken());
        }
    }


    public static void main(String[] args) throws Exception {
        in = new Scanner(new File("easy.in"));
        out = new PrintWriter("easy.out");

        new easy_gk_ok_rounding().run();

        out.close();
    }
}
