#include<bits/stdc++.h>
using namespace std;

struct Point{
	int x,y,idx;
	bool operator<(const Point& rhs)const{
		return x==rhs.x?y<rhs.y:x<rhs.x;
	}
}P[100];

bool bad(const Point& p1,const Point& p2,const Point& p3){
	return 1LL*(p3.x-p1.x)*(p2.y-p1.y)-1LL*(p2.x-p1.x)*(p3.y-p1.y)<=0;
}
vector<Point> convex(int n){
	sort(P,P+n);
	vector<Point> res;
	for(int i=0;i<n;i++){
		while(res.size()>=2&&bad(res[res.size()-2],res[res.size()-1],P[i]))
			res.pop_back();
		res.emplace_back(P[i]);
	}
	for(int i=n-2,t=res.size();i>=0;i--){
		while(res.size()>t&&bad(res[res.size()-2],res[res.size()-1],P[i]))
			res.pop_back();
		res.emplace_back(P[i]);
	}
	res.pop_back();
	return res;
}
double ans[100];
const double pi = acos(-1);
inline double dist(int x,int y){
	return sqrt(1LL*x*x+1LL*y*y);
}
double calc(const Point& p1,const Point& p2,const Point& p3){
	long long int dot=1LL*(p3.x-p2.x)*(p2.x-p1.x)+1LL*(p3.y-p2.y)*(p2.y-p1.y);
	double tmp=dot/(double)dist(p2.x-p1.x,p2.y-p1.y)/(double)dist(p3.x-p2.x,p3.y-p2.y);
	double ang = acos(tmp);
	return ang/(2*pi);
}
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>P[i].x>>P[i].y,P[i].idx=i;
	auto res = convex(n);
	if(res.size()==2){
		ans[res[0].idx]=0.5;
		ans[res[1].idx]=0.5;
	}
	else{
		for(int j=0;j<res.size();j++){
			int i=(j+(res.size()-1))%res.size();
			int k=(j+1)%res.size();
			ans[res[j].idx] = calc(res[i],res[j],res[k]);
		}
	}
	cout<<fixed<<setprecision(10);
	for(int i=0;i<n;i++)
		cout<<ans[i]<<'\n';
}

#include <bits/stdc++.h>
using namespace std::literals::string_literals;
using i64 = long long;
using std::cout;
using std::endl;
using std::cin;

template<typename T>
std::vector<T> make_v(size_t a){return std::vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

struct UnionFind{
	std::vector<int> data;
	
	UnionFind(int n){
		data.assign(n, -1);
	}
	
	bool unite(int x, int y){
		x = find(x); y = find(y);
		if(x == y) return false;
		if(data[x] > data[y]) std::swap(x, y);
		data[x] += data[y];
		data[y] = x;
		return true;
	}
	
	bool same(int x, int y){
		return find(x) == find(y);
	}
	
	int find(int k){
		if(data[k] < 0) return k;
		return data[k] = find(data[k]);
	}
	
	int size(int k){
		return -data[find(k)];
	}
};

int main() {
	int n; scanf("%d", &n);
	std::vector<std::pair<i64, int>> X, Y;
	for(int i = 0; i < n; i++) {
		int x, y; scanf("%d%d", &x, &y);

		X.push_back({x, i});
		Y.push_back({y, i});
	}
	sort(begin(X), end(X)); sort(begin(Y), end(Y));

	std::vector<std::pair<i64, std::pair<int, int>>> edges;
	for(int i = 0; i < n - 1; i++) {
		edges.push_back({X[i + 1].first - X[i].first, {X[i].second, X[i + 1].second}});
		edges.push_back({Y[i + 1].first - Y[i].first, {Y[i].second, Y[i + 1].second}});
	}
	sort(begin(edges), end(edges));

	i64 ans = 0;
	UnionFind uf(n);
	for(auto e: edges) {
		int x = e.second.first, y = e.second.second;
		if(uf.unite(x, y)) ans += e.first;
	}
	printf("%lld\n", ans);
	return 0;
}
