#include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

using R = long double; // Rにmint渡せるようにする
using P = complex<R>;
using L = pair<P,P>;
using G = vector<P>;
struct C {
    P c; R r;
    C() {}
    C(const P &a, const R &b) : c(a), r(b) {}
};
struct S : public L {
    S() {}
    S(const P &a, const P &b) : L(a,b) {}
};

const R EPS = 1e-8;
const R PI = atan(1)*4;

inline int sgn(const R& r) { return (r>EPS) - (r<-EPS); }
inline R dot(const P& a, const P& b) {
    return real(a)*real(b) + imag(a)*imag(b);
}
inline R det(const P& a, const P& b) {
    return real(a)*imag(b) - imag(a)*real(b);
}
inline P rotate(const P& p, const R& arg) {
    return P(cos(arg)*p.real()-sin(arg)*p.imag(),
             sin(arg)*p.real()+cos(arg)*p.imag());
}
inline P vec(const L& l) {return l.second - l.first;}
namespace std {
	bool operator < (const P& a, const P& b) {
		return sgn(real(a-b)) ? real(a-b) < 0 : sgn(imag(a-b)) < 0;
	}
	bool operator == (const P& a, const P& b) {
		return sgn(real(a-b)) == 0 && sgn(imag(a-b)) == 0;
	}
    bool cmp_y (const P& a, const P& b) {
        return sgn(imag(a-b)) ? imag(a-b) < 0 : sgn(real(a-b)) < 0;
    }
}

// P,L,Sについて入力
inline istream& operator>>(istream& is, P& p) {
    R x, y;
    is >> x >> y;
    p = P(x, y);
    return is;
}
inline istream& operator>>(istream& is, L& l) {
    P a, b;
    is >> a >> b;
    l = L(a, b);
    return is;
}
inline istream& operator>>(istream& is, S& s) {
    P a, b;
    is >> a >> b;
    s = S(a, b);
    return is;
}

// 線分abから見たcの位置
enum CCW{LEFT=1, RIGHT=2, BACK=4, FRONT=8, ON_SEG=16};
int ccw(P a, P b, P c) {
	P p = (c-a)/(b-a);
	if(sgn(imag(p)) > 0) return LEFT;
	if(sgn(imag(p)) < 0) return RIGHT;
	if(sgn(real(p)) < 0) return BACK;
	if(sgn(real(p)-1) > 0) return FRONT;
	return ON_SEG;
}

// 射影
P inline projection(const L &l, const P &p) {
    R t = dot(p-l.first, l.first-l.second) / norm(l.first-l.second);
    return l.first + t*(l.first-l.second);
}

R dist(const L& l, const P& p) {
    P q = projection(l, p);
    return abs(p-q);
}

// 交差
int intersect(const C& c, const L& l) {
    R d = dist(l, c.c);
    // cout << l << " " << d << endl;
    if(sgn(c.r-d) > 0) return 2; // 交差している
    else if(sgn(c.r-d) == 0) return 1; // 接している
    return 0; // 交差しない
}
int intersect(const C& a, const C& b) {
	R dist = norm(a.c-b.c), r1 = (a.r+b.r)*(a.r+b.r), r2 = (a.r-b.r)*(a.r-b.r);
	if(sgn(r1-dist) < 0)  return 4;	// 円が離れている
	if(sgn(r1-dist) == 0) return 3;	// 外接
	if(sgn(r2-dist) < 0 && sgn(dist-r1) < 0) return 2; // 交差
	if(sgn(dist-r2) == 0) return 1; // 内接
	return 0;	// 内部に含む
}

struct visualizer {
    struct Col { int r, g, b; };
    FILE* fp;
    R off, f;
    visualizer(string s, R d, R u) : off(d), f(1000/(u-d)) {
        fp = fopen(s.c_str(), "w");
        fprintf(
            fp,
            "<html><head><script>"
            "onload = function draw() {"
            "var cv = document.getElementById('c');"
            "var ct = cv.getContext('2d');"
        );
    }
    R norm(R x) { return (x - off) * f; }
    void set_col(Col c) {
        fprintf(fp, "ct.fillStyle = \"rgb(%d, %d, %d)\";", c.r, c.g, c.b);
        fprintf(fp, "ct.strokeStyle = \"rgb(%d, %d, %d)\";", c.r, c.g, c.b);
    }
    void line(L l, Col col = {0, 0, 0}) {
        set_col(col);
        fprintf(fp,
        "ct.beginPath();"
        "ct.moveTo(%Lf, %Lf);"
        "ct.lineTo(%Lf, %Lf);"
        "ct.closePath();"
        "ct.stroke();",
        norm(l.first.real()), norm(l.first.imag()), norm(l.second.real()), norm(l.second.imag()));
    }
    void point(P p, Col col = {0, 0, 0}) {
        set_col(col);
        fprintf(fp,
            "ct.beginPath();"
            "ct.arc(%Lf, %Lf, 2, 0, Math.PI * 2, true);"
            "ct.fill();",
            norm(p.real()), norm(p.imag())
        );
    }
    ~visualizer() {
        fprintf(
            fp,
            "}</script></head><body>"
            "<canvas id=\"c\" width=\"1000\" height=\"1000\">"
            "</canvas></body></html>"
        );
        fclose(fp);
    }
};

signed main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    ll h, w, n;
    cin >> w >> h >> n;
    vector<P> v(n);
    REP(i, n) cin >> v[i];

    // visualizer vis("test.html", 0, max(h, w));
    // REP(i, n) vis.point(v[i], {255,0,0});
    // vis.line(L(P(0,0),P(0,h)));
    // vis.line(L(P(0,0),P(w,0)));
    // vis.line(L(P(w,h),P(0,h)));
    // vis.line(L(P(w,h),P(w,0)));
    // return 0;

    auto check = [&](R mid) {
        vector<C> c(n);
        REP(i, n) c[i] = C(v[i], mid);
        vector<vector<ll>> g(n+2);
        REP(i, n) FOR(j, i+1, n) {
            if(intersect(c[i], c[j]) == 2) {
                g[i].push_back(j);
                g[j].push_back(i);
            }
        }
        REP(i, n) {
            L left(P(0,0),P(0,h));
            if(intersect(c[i], left) == 2) {
                g[i].push_back(n);
                g[n].push_back(i);
            }
            L right(P(w,0),P(w,h));
            if(intersect(c[i], right) == 2) {
                g[n+1].push_back(i);
                g[i].push_back(n+1);
            }
        }

        queue<int> que;
        que.push(n);
        vector<int> dist(n+2, INF);
        dist[n] = 0;
        while(que.size()) {
            int t = que.front(); que.pop();
            for(auto to: g[t]) {
                if(dist[to] == INF) {
                    dist[to] = dist[t] + 1;
                    que.push(to);
                }
            }
        }

        // cout << dist << endl;
        return dist[n+1] == INF;
    };

    // cout << check(4000000) << endl;

    R lb = 0, ub = 2e9;
    REP(i, 100) {
        R mid = (lb+ub)/2;
        // cout << lb << " " << mid << " " << ub << endl;
        if(check(mid)) lb = mid;
        else ub = mid;
    }

    cout << fixed << setprecision(5) << lb << endl;

    return 0;
}



Measured memory_bytes: 5276