import java.io.*; import java.util.*; public class hedge_mb_events { static class Point { final int x, y; Point(int x, int y) { this.x = x; this.y = y; } Point subtract(Point that) { return new Point(x - that.x, y - that.y); } int vMul(Point that) { return x * that.y - y * that.x; } int sMul(Point that) { return x * that.x + y * that.y; } public String toString() { return "(" + x + "," + y + ")"; } } static class Event implements Comparable { final int num, den; final int type; Event(int num, int den, int type) { this.type = type; if (den < 0) { num = -num; den = -den; } /* int a = den, b = num; while (a != 0) { int d = b % a; b = a; a = d; } this.num = num / b; this.den = den / b; */ this.num = num; this.den = den; } public int compareTo(Event that) { int cmp = Long.compare((long) (num) * that.den, (long) (den) * that.num); return cmp == 0 ? type - that.type : cmp; } public String toString() { return num + "/" + den + "@" + type + "=" + toDouble(); } public double toDouble() { return (double) (num) / den; } } static Point[] readPolygon(BufferedReader in) throws IOException { int n = Integer.parseInt(in.readLine()); Point[] p = new Point[n]; for (int i = 0; i < n; ++i) { String line = in.readLine(); int ws = line.indexOf(' '); p[i] = new Point(Integer.parseInt(line.substring(0, ws)), Integer.parseInt(line.substring(ws + 1))); } long area = 0; for (int i = 0; i < n; ++i) { area += p[i].vMul(p[(i + 1) % n]); } if (area < 0) { for (int i = 0, j = n - 1; i < j; ++i, --j) { Point tmp = p[i]; p[i] = p[j]; p[j] = tmp; } } return p; } static int[] vMuls(Point[] p) { int n = p.length; int[] rv = new int[n]; for (int i = 0; i < n; ++i) { rv[i] = p[i].vMul(p[(i + 1) % n]); } return rv; } static Event solve(Point[] pNew, Point[] pOld) { int nNew = pNew.length; int nOld = pOld.length; int[] vmulNew = vMuls(pNew); int[] vmulOld = vMuls(pOld); List events = new ArrayList<>(); for (int i = 0; i < nNew; ++i) { if (vmulNew[i] == 0) { continue; } int signI = Integer.signum(vmulNew[i]); for (int j = 0; j < nOld; ++j) { if (vmulOld[j] == 0) { continue; } int signJ = Integer.signum(vmulOld[j]); if (signI != signJ) continue; // old points pj, qj Point pj = pOld[j], qj = pOld[(j + 1) % nOld]; // new points pi, qi Point pi = pNew[i], qi = pNew[(i + 1) % nNew]; int vPIQI = vmulNew[i]; int vPJQJ = vmulOld[j]; int vPIPJ = pi.vMul(pj); int vPIQJ = pi.vMul(qj); int vQIPJ = qi.vMul(pj); int vQIQJ = qi.vMul(qj); int vectVmul = vPIQJ + vQIPJ - vPIPJ - vQIQJ; int pEventSign = vectVmul == 0 || Integer.signum(vectVmul) == signI ? 3 * signI : 2 * signI; int qEventSign = vectVmul == 0 || Integer.signum(vectVmul) == -signI ? 3 * signI : 2 * signI; // testing pi against pj // testing pi against pj--qj if ((vPIPJ == 0 || Integer.signum(vPIPJ) == -signI) && Integer.signum(vPIQJ) == signI) { events.add(new Event(vPJQJ, vPIQJ - vPIPJ, pEventSign)); } // testing qi against qj // testing qi against pj--qj if ((vQIQJ == 0 || Integer.signum(vQIQJ) == signI) && Integer.signum(vQIPJ) == -signI) { events.add(new Event(vPJQJ, vQIQJ - vQIPJ, qEventSign)); } // testing pi--qi against pj if (Integer.signum(vPIPJ) == signI && Integer.signum(vQIPJ) == -signI) { events.add(new Event(vPIPJ - vQIPJ, vPIQI, pEventSign)); } // testing pi--qi against qj if (Integer.signum(vQIQJ) == -signI && Integer.signum(vPIQJ) == signI) { events.add(new Event(vPIQJ - vQIQJ, vPIQI, qEventSign)); } } } Collections.sort(events); int level = 0; int minReachedLevel = 0; Event last = null; Event last0 = null; for (Event e : events) { if (e.type == 3 && level == minReachedLevel && (last0 == null || last0.compareTo(e) < 0)) { last = e; } if (Math.abs(e.type) == 2) { last0 = e; } level += e.type / 2; minReachedLevel = Math.min(minReachedLevel, level); } return last; } public static void main(String[] args) throws IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) { Point[] pNew = readPolygon(in); Point[] pOld = readPolygon(in); Event solution = solve(pNew, pOld); System.out.println(solution.toDouble()); } } }