#include <bits/stdc++.h>
using namespace std;
typedef complex<double> point;
const double E = 1e-9, pi = 2 * acos(0);
struct line{
    point p, v;
};
struct seg{
    point a, b;
    line toline(){
        return {a, b - a};
    }
};
int sign(double x){
    if(x < -E) return -1;
    if(x >  E) return 1;
    return 0;
}
double cross(point a, point b){
    return a.real() * b.imag() - a.imag() * b.real();
}
double cross(point a, point b, point c){
    return cross(b-a, c-a);
}
double dot(point a, point b){
    return a.real() * b.real() + a.imag() * b.imag();
}
double dot(point a, point b, point c){
    return dot(b-a, c-a);
}
bool xycmp(point a, point b){
    if(abs(a.real() - b.real()) > E) return a.real() < b.real();
    if(abs(a.imag() - b.imag()) > E) return a.imag() < b.imag();
    return false;
}
bool yxcmp(point a, point b){
    if(abs(a.imag() - b.imag()) > E) return a.imag() < b.imag();
    if(abs(a.real() - b.real()) > E) return a.real() < b.real();
    return false;
}
point proj(point a, point v){
    return v * dot(a, v) / dot(v, v);
}
int side(seg x, point a){
    return sign(cross(x.a, x.b, a));
}
bool segcross(seg x, seg y){ // True if they are not parallel and strictly cross
    return side(x, y.a) * side(x, y.b) < 0 && side(y, x.a) * side(y, x.b) < 0;
}
bool segtouch(seg x, seg y){ // True if their intersection is non empty
    bool res = side(x, y.a) * side(x, y.b) <= 0 && side(y, x.a) * side(y, x.b) <= 0;
    if(res && sign(cross(x.b - x.a, y.b - y.a)) == 0){
        res &= !(dot(x.a, x.b, y.a) < -E && dot(x.a, x.b, y.b) < -E);
        res &= !(dot(x.b, x.a, y.a) < -E && dot(x.b, x.a, y.b) < -E);
    }
    return res;
}
point closest(point p, line l){
    return l.p + proj(p - l.p, l.v);
}
point closest(point p, seg x){
    point v = x.b - x.a; double m = dot(p - x.a, v) / dot(v, v);
    if(m < 0) m = 0;
    if(m > 1) m = 1;
    return x.a + m * v;
}
point intersection(line x, line y){
    double t = cross(y.p - x.p, y.v) / cross(x.v, y.v);
    return x.p + x.v * t;
}
point circumcenter(point a, point b, point c){
    if(sign(cross(a, b, c)) == 0){
        if(norm(a - b) > norm(a - c) && norm(a - b) > norm(b - c)) return (a + b)/2.;
        if(norm(a - c) > norm(b - c)) return (a + c)/2.;
        return (b + c)/2.;
    }
    point x = (b + a)/2., dirx = (a - b) * point(0, 1);
    point y = (b + c)/2., diry = (c - b) * point(0, 1);
    return intersection((line){x, dirx}, (line){y, diry});
}
pair<point, double> minimum_covering_circle(vector<point> points){
    random_shuffle(points.begin(), points.end());
    point C;
    double rad = -10;
    for(int i = 0; i < (int)points.size(); ++i)
        if(abs(points[i] - C) > rad + E){
            C = points[i]; rad = 0.0;
            for(int j = 0; j < i; ++j)
                if(abs(points[j] - C) > rad + E){
                    C = (points[i] + points[j])/2.;
                    rad = abs(points[i] + points[j])/2.;
                    for(int k = 0; k < j; ++k)
                        if(abs(points[k] - C) > rad + E){
                            C = circumcenter(points[i], points[j], points[k]);
                            rad = abs(C - points[i]);
                        }
                }
        }
    return {C, rad};
}
vector<point> convex_hull(vector<point> points){
    sort(points.begin(), points.end(), xycmp);
    vector<point> upper, lower;
    for(int i = 0; i < (int)points.size(); ++i){
        while(upper.size() >= 2 && cross(upper.end()[-2], upper.end()[-1], points[i]) >= -E)
            upper.pop_back();
        upper.push_back(points[i]);
    }
    for(int i = (int)points.size()-1; i >= 0; --i){
        while(lower.size() >= 2 && cross(lower.end()[-2], lower.end()[-1], points[i]) >= -E)
            lower.pop_back();
        lower.push_back(points[i]);
    }
    if(lower.size() > 2) upper.insert(upper.end(), lower.begin() + 1, lower.end() - 1);
    return upper;
}
const int maxn = 1010;
int x[maxn], y[maxn];
int main(){
	int n; cin >> n;
	for(int i = 0; i < n; i++) cin >> x[i] >> y[i];
	vector<pair<int, int> > can, ncan;
	can.push_back({0, 0});
	for(int i = 0; i < n; i++){
		ncan = can;
		for(auto e : can){
			ncan.push_back({e.first + x[i], e.second + y[i]});
		}
		sort(ncan.begin(), ncan.end());
		ncan.erase(unique(ncan.begin(), ncan.end()), ncan.end());
		if(ncan.size() > 20000){
			vector<point> now, res;
			for(auto e : ncan){
				now.push_back(point(e.first, e.second));
			}
			res = convex_hull(now);
			ncan.clear();
			for(auto e : res){
				ncan.push_back({(int)e.real(), (int)e.imag()});
			}
		}
		can = ncan;
	}
	long long ans = 0;
	for(auto e : can) ans = max(ans, 1ll * e.first * e.first + 1ll * e.second * e.second);
	cout << fixed << setprecision(18) << sqrtl(ans) << endl;
	return 0;
}


Measured memory_bytes: 2384