Problem: Gena doesn't like geometry, so he asks you to solve this problem for him.

A rectangle with sides parallel to coordinate axes contains n dots. Let's consider some point of the plane. Let's count the distances from this point to the given n points. Let's sort these numbers in the non-decreasing order. We'll call the beauty of the point the second element of this array. If there are two mimimum elements in this array, the beaty will be equal to this minimum.

Find the maximum beauty of a point inside the given rectangle.

Input

The first line contains three integers w, h, n (1 ≤ w, h ≤ 106, 2 ≤ n ≤ 1000) — the lengths of the rectangle sides and the number of points. Next n lines contain two integers xi, yi (0 ≤ xi ≤ w, 0 ≤ yi ≤ h) each — the coordinates of a point. It is possible that it will be coincident points.

Output

Print a single number — the maximum beauty of a point with the absolute or relative error of at most 10 - 9.

Examples

Input

5 5 4
0 0
5 0
0 5
5 5


Output

4.99999999941792340


Input

5 5 3
4 0
2 5
4 1


Output

5.65685424744772010

Note

The point which beauty we need to find must have coordinates (x, y), where 0 ≤ x ≤ w, 0 ≤ y ≤ h. Some of the n points can coincide.

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Random;
import java.io.UncheckedIOException;
import java.math.BigDecimal;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            EGenaAndSecondDistance solver = new EGenaAndSecondDistance();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class EGenaAndSecondDistance {
        double eps = 1e-12;
        CircleCoverDetect ccd = new CircleCoverDetect(eps);
        DoublePriorityQueue left = new DoublePriorityQueue(10000, DoubleComparator.NATURE_ORDER);
        DoublePriorityQueue right = new DoublePriorityQueue(10000, DoubleComparator.NATURE_ORDER);

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int w = in.readInt();
            int h = in.readInt();
            int n = in.readInt();

            Point2[] pts = new Point2[n];
            for (int i = 0; i < n; i++) {
                pts[i] = new Point2(in.readInt(), in.readInt());
            }

            Point2[] corners = new Point2[]{
                    new Point2(0, 0),
                    new Point2(w, 0),
                    new Point2(w, h),
                    new Point2(0, h)
            };
            Line2[] lines = new Line2[4];
            for (int i = 0; i < 4; i++) {
                lines[i] = new Line2(corners[i], corners[(i + 1) % 4]);
            }

            Randomized.shuffle(pts);
            double ans = 1e-9;


            for (int i = 0; i < n; i++) {
                if (!check(pts, pts[i], ans, lines)) {
                    continue;
                }
                Point2 center = pts[i];
                DoubleBinarySearch dbs = new DoubleBinarySearch(eps, eps) {

                    public boolean check(double mid) {
                        return !EGenaAndSecondDistance.this.check(pts, center, mid, lines);
                    }
                };
                double local = dbs.binarySearch(ans, h + w);
                ans = Math.max(ans, local);
            }

            out.println(ans);
        }

        public boolean check(Point2[] pts, Point2 center, double r, Line2[] borders) {
            left.clear();
            right.clear();
            ccd.reset(center, r, (a, b) -> {
                left.add(a);
                right.add(b);
            });
            for (Line2 line : borders) {
                ccd.addLine(line);
                ccd.addLine(line);
            }
            for (Point2 pt : pts) {
                ccd.addCircle(pt, r);
            }

            double cnt = 0;

            if (left.isEmpty() || left.peek() > 0) {
                return true;
            }
            while (!right.isEmpty()) {
                double min = right.peek();
                if (!left.isEmpty()) {
                    min = Math.min(left.peek(), min);
                }
                while (!left.isEmpty() && left.peek() == min) {
                    left.pop();
                    cnt++;
                }
                while (!right.isEmpty() && right.peek() == min) {
                    right.pop();
                    cnt--;
                }
                if (min == 2 * Math.PI) {
                    return false;
                }
                if (cnt < 2) {
                    return true;
                }
            }
            return true;

        }

    }

    static interface DoubleBinaryConsumer {
        void accept(double a, double b);

    }

    static class GeoConstant {
        public static final double PREC = 1e-15;

        public static boolean isZero(double x) {
            return -PREC <= x && x <= PREC;
        }

        public static int sign(double x) {
            return isZero(x) ? 0 : x < 0 ? -1 : 1;
        }

    }

    static class RandomWrapper {
        private Random random;
        public static final RandomWrapper INSTANCE = new RandomWrapper(new Random());

        public RandomWrapper() {
            this(new Random());
        }

        public RandomWrapper(Random random) {
            this.random = random;
        }

        public int nextInt(int l, int r) {
            return random.nextInt(r - l + 1) + l;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(double c) {
            cache.append(new BigDecimal(c).toPlainString());
            return this;
        }

        public FastOutput println(double c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class Randomized {
        public static <T> void shuffle(T[] data) {
            shuffle(data, 0, data.length - 1);
        }

        public static <T> void shuffle(T[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                T tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static int nextInt(int l, int r) {
            return RandomWrapper.INSTANCE.nextInt(l, r);
        }

    }

    static class DoublePriorityQueue implements Cloneable {
        private double[] data;
        private DoubleComparator comparator;
        private int size;

        public DoublePriorityQueue(int n, DoubleComparator comparator) {
            this.data = new double[n + 1];
            this.comparator = comparator;
        }

        private int left(int i) {
            return i << 1;
        }

        private int right(int i) {
            return (i << 1) | 1;
        }

        private int parent(int i) {
            return i >> 1;
        }

        public void add(double x) {
            data[++size] = x;
            shiftUp(size);
        }

        public double peek() {
            return data[1];
        }

        private void shiftUp(int index) {
            while (index != 1) {
                int pid = parent(index);
                if (comparator.compare(data[pid], data[index]) <= 0) {
                    break;
                }
                SequenceUtils.swap(data, index, pid);
                index = pid;
            }
        }

        private void shiftDown(int index) {
            while (true) {
                int lid = left(index);
                int rid = right(index);
                if (lid > size) {
                    break;
                }
                int challenger = lid;
                if (rid <= size && comparator.compare(data[rid], data[lid]) < 0) {
                    challenger = rid;
                }
                if (comparator.compare(data[challenger], data[index]) >= 0) {
                    break;
                }
                SequenceUtils.swap(data, index, challenger);
                index = challenger;
            }
        }

        public double pop() {
            double ans = data[1];
            SequenceUtils.swap(data, 1, size);
            size--;
            shiftDown(1);
            return ans;
        }

        public void clear() {
            size = 0;
        }

        public boolean isEmpty() {
            return size == 0;
        }

        public DoublePriorityQueue clone() {
            try {
                DoublePriorityQueue c = (DoublePriorityQueue) super.clone();
                c.data = data.clone();
                return c;
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public String toString() {
            StringBuilder builder = new StringBuilder();
            DoublePriorityQueue queue = clone();
            while (!queue.isEmpty()) {
                builder.append(queue.pop()).append(',');
            }
            if (builder.length() > 0) {
                builder.setLength(builder.length() - 1);
            }
            return builder.toString();
        }

    }

    static class GeometryUtils {
        public static double triangleAngle(double a, double b, double c) {
            double cosa = (b * b + c * c - a * a) / (2 * b * c);
            return Math.acos(cosa);
        }

        public static double theta(double y, double x) {
            double theta = Math.atan2(y, x);
            if (theta < 0) {
                theta += Math.PI * 2;
            }
            return theta;
        }

    }

    static abstract class DoubleBinarySearch {
        private final double relativeErrorTolerance;
        private final double absoluteErrorTolerance;

        public DoubleBinarySearch(double relativeErrorTolerance, double absoluteErrorTolerance) {
            this.relativeErrorTolerance = relativeErrorTolerance;
            this.absoluteErrorTolerance = absoluteErrorTolerance;
        }

        public abstract boolean check(double mid);

        public double binarySearch(double l, double r) {
            if (l > r) {
                throw new IllegalArgumentException();
            }
            while (r - l > absoluteErrorTolerance) {
                if ((r < 0 && (r - l) < -r * relativeErrorTolerance) || (l > 0 && (r - l) < l * relativeErrorTolerance)) {
                    break;
                }

                double mid = (l + r) / 2;
                if (check(mid)) {
                    r = mid;
                } else {
                    l = mid;
                }
            }
            return (l + r) / 2;
        }

    }

    static class Point2 implements Cloneable {
        public final double x;
        public final double y;

        public Point2(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point2() {
            this(0, 0);
        }

        public double square() {
            return dot(this, this);
        }

        public double abs() {
            return Math.sqrt(square());
        }

        public static Point2 minus(Point2 a, Point2 b) {
            return new Point2(a.x - b.x, a.y - b.y);
        }

        public static double dot(Point2 a, Point2 b) {
            return a.x * b.x + a.y * b.y;
        }

        public static double cross(Point2 a, Point2 b) {
            return a.x * b.y - a.y * b.x;
        }

        public static double dist2(Point2 a, Point2 b) {
            double dx = a.x - b.x;
            double dy = a.y - b.y;
            return dx * dx + dy * dy;
        }

        public static double dist(Point2 a, Point2 b) {
            return Math.sqrt(dist2(a, b));
        }

        public Point2 clone() {
            try {
                return (Point2) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public String toString() {
            return String.format("(%.6f, %.6f)", x, y);
        }

    }

    static class CircleCoverDetect {
        private Point2 center;
        private double cr;
        private double eps;
        private static double min = 0;
        private static double max = 2 * Math.PI;
        private DoubleBinaryConsumer consumer;

        public CircleCoverDetect(double eps) {
            this.eps = eps;
        }

        public void reset(Point2 center, double r, DoubleBinaryConsumer consumer) {
            this.center = center;
            this.cr = r;
            this.consumer = consumer;
        }

        private void add(double l, double r) {
            consumer.accept(l, r);
        }

        private void addForbidden(double theta, double angle) {
            double l = theta - angle;
            double r = theta + angle;

            if (l < min) {
                add(max + l, max);
                l = 0;
            }
            if (r > max) {
                add(0, r - max);
                r = max;
            }
            add(l, r);
        }

        public void addCircle(Point2 pt, double r) {
            double dist = Point2.dist(center, pt);
            if (dist + eps >= r + cr) {
                return;
            }
            //no intersection case
            if (dist + r - eps <= cr) {
                return;
            }
            if (dist + cr - eps <= r) {
                add(0, Math.PI * 2);
                return;
            }

            double theta = GeometryUtils.theta(pt.y - center.y, pt.x - center.x);
            double angle = GeometryUtils.triangleAngle(r, cr, dist);
            addForbidden(theta, angle);
        }

        private double valueOfRadian(double x) {
            while (x > max) {
                x -= Math.PI * 2;
            }
            while (x < min) {
                x += Math.PI * 2;
            }
            return x;
        }

        public void addLine(Line2 line) {
            int side = line.side(center);
            double dist = line.dist(center);
            if (dist + eps >= cr) {
                if (side == -1) {
                    add(min, max);
                }
                return;
            }
            double theta = valueOfRadian(GeometryUtils.theta(line.vec.y, line.vec.x) - Math.PI / 2);
            double angle = side == 0 ? Math.PI / 2 : Math.acos(dist / cr);
            if (side == -1) {
                angle = Math.PI - angle;
            }
            addForbidden(theta, angle);
        }

    }

    static class SequenceUtils {
        public static void swap(double[] data, int i, int j) {
            double tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }

    }

    static class Line2 {
        public Point2 vec;
        public double c;

        public Line2(Point2 vec, double c) {
            this.vec = vec;
            this.c = c;
        }

        public Line2(double a, double b, double c) {
            this(new Point2(b, -a), c);
        }

        public Line2(Point2 a, Point2 b) {
            this.vec = Point2.minus(b, a);
            this.c = Point2.cross(vec, a);
        }

        private double side0(Point2 pt) {
            return Point2.cross(vec, pt) - c;
        }

        public int side(Point2 pt) {
            return GeoConstant.sign(side0(pt));
        }

        public double dist(Point2 pt) {
            return Math.abs(side0(pt)) / vec.abs();
        }

        public String toString() {
            return -vec.y + "x + " + vec.x + "y = " + c;
        }

    }

    static interface DoubleComparator {
        public static final DoubleComparator NATURE_ORDER = (a, b) -> Double.compare(a, b);

        public int compare(double a, double b);

    }
}