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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<endl;
	#else
	cout<<"Possible"<<endl;
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<endl;
	#else
	cout<<"Impossible"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

template<class t>
t gcd(t a,t b){return b?gcd(b,a%b):a;}

//ARC055D
//比較関数のあたりはverifyされてない?多分大丈夫だと思うけど
template<class t>
struct frac{
	t a,b;
	frac(t aa=0,t bb=1):a(aa),b(bb){g();}
	frac&g(){
		if(a==0){
			b=1;
			return *this;
		}
		//t x=gcd(a,b);
		//a/=x;b/=x;
		if(b<0){a=-a;b=-b;}
		return *this;
	}
	frac&do_g(){
		if(a==0){
			b=1;
			return *this;
		}
		t x=gcd(a,b);
		a/=x;b/=x;
		if(b<0){a=-a;b=-b;}
		return *this;
	}
	t quo()const{return a/b-((a^b)<0&&a%b);}
	t rem()const{return a-quo()*b;}
	frac inv()const{return frac(b,a);}
	frac operator-()const{return frac(-a,b);}
	frac&operator+=(frac r){a=a*r.b+r.a*b;b*=r.b;return g();}
	frac&operator-=(frac r){a=a*r.b-r.a*b;b*=r.b;return g();}
	frac&operator*=(frac r){a*=r.a;b*=r.b;return g();}
	frac&operator/=(frac r){a*=r.b;b*=r.a;return g();}
	frac operator+(frac r)const{return frac(*this)+=r;}
	frac operator-(frac r)const{return frac(*this)-=r;}
	frac operator*(frac r)const{return frac(*this)*=r;}
	frac operator/(frac r)const{return frac(*this)/=r;}
	bool operator<(frac r)const{
		t c=quo(),d=r.quo();
		if(c!=d)return c<d;
		else return rem()*r.b<r.rem()*b;
	}
	bool operator<=(frac r)const{
		t c=quo(),d=r.quo();
		if(c!=d)return c<=d;
		else return rem()*r.b<=r.rem()*b;
	}
	bool operator>(frac r)const{
		t c=quo(),d=r.quo();
		if(c!=d)return c>d;
		else return rem()*r.b>r.rem()*b;
	}
	bool operator>=(frac r)const{
		t c=quo(),d=r.quo();
		if(c!=d)return c>=d;
		else return rem()*r.b>=r.rem()*b;
	}
	bool operator==(frac r)const{
		return quo()==r.quo()&&rem()*r.b==r.rem()*b;
	}
	bool operator!=(frac r)const{
		return !operator==(r);
	}
	long double to_real()const{
		return (long double)a/b;
	}
};
template<class t>
ostream&operator<<(ostream&os,frac<t> a){
	return os<<a.a<<"/"<<a.b;
}
template<class t>
int sgn(frac<t> a){return a.a<0?-1:(a.a>0?1:0);}
template<class t>
int cmpfrac(frac<t> a,frac<t> b){
	t p=a.a*b.b-b.a*a.b;
	return p<0?-1:(p==0?0:1);
}
template<class t>
frac<t> abs(frac<t> a){return a.a<0?-a:a;}

using int128=__int128_t;
ostream& operator<<(ostream&os,int128 i){
	if(i==0)
		return os<<0;
	static char buf[100];
	if(i<0){
		os<<"-";
		i=-i;
	}
	int p=0;
	while(i){
		buf[p++]='0'+i%10;
		i/=10;
	}
	reverse(buf,buf+p);
	buf[p]=0;
	return os<<buf;
}
int128 abs128(int128 a){
	return a<0?-a:a;
}

/*
namespace ysp{

using ld=long double;
//using ld=frac<int128>;
using cm=complex<ld>;
#define x real()
#define y imag()
const ld eps=1e-10;
//const ld eps=0;
//const ld PI=acos(ld(-1));
int sgn(ld a){return a<-eps?-1:(a>eps?1:0);}
ld rabs(cm a){return max(abs(a.x),abs(a.y));}
ld dot(cm a,cm b){return a.x*b.x+a.y*b.y;}
ld crs(cm a,cm b){return a.x*b.y-a.y*b.x;}
ld crs(cm a,cm b,cm c){return crs(b-a,c-a);}
int ccw(cm a,cm b){return sgn(crs(a,b));}
int ccw(cm a,cm b,cm c){return ccw(b-a,c-a);}
auto cmless=[](cm a,cm b){
	int s=sgn(a.x-b.x);
	if(s)return s<0;
	else return sgn(a.y-b.y)<0;
};
bool cmeq(cm a,cm b){
	return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;
};
//(-pi,0](0,pi]
int argtype(cm a){
	if(sgn(a.y)==0)return a.x<0?1:0;
	return a.y<0?0:1;
}
int argcmp(cm a,cm b){
	int at=argtype(a),bt=argtype(b);
	if(at!=bt)return at<bt?-1:1;
	return -ccw(a,b);
};
bool argless(cm a,cm b){return argcmp(a,b)<0;}
//(-2)[a,-1](0)[b,1](2)
int bet(cm a,cm b,cm c){
	cm d=b-a;
	ld e=dot(d,c-a);
	if(sgn(e)<=0)return sgn(e)-1;
	return sgn(e-norm(d))+1;
}
//AOJ0153
//0-no,1-edge,2-in
int cont(cm a,cm b,cm c,cm d){
	if(ccw(a,b,c)==-1)
		swap(b,c);
	return min({ccw(a,b,d),ccw(b,c,d),ccw(c,a,d)})+1;
}

using ln=pair<cm,cm>;
cm dir(ln a){return a.b-a.a;}
cm eval(ln a,ld b){return a.a+dir(a)*b;}
int bet(ln a,cm b){return bet(a.a,a.b,b);}
int ccw(ln a,cm b){return ccw(a.a,a.b,b);}
cm proj(ln a,cm b){
	cm c=dir(a);
	return a.a+c*dot(c,b-a.a)/norm(c);
}
cm refl(ln a,cm b){
	return ld(2)*proj(a,b)-b;
}
//AOJ1157
//0-no,1-yes(endpoint),2-yes(innner),3-overelap
//if the two line touch like this
// x----x----x
//it returns 1
int iss(ln a,ln b){
	int c1=ccw(a.a,a.b,b.a),c2=ccw(a.a,a.b,b.b);
	int d1=ccw(b.a,b.b,a.a),d2=ccw(b.a,b.b,a.b);
	if(c1||c2||d1||d2)return 1-max(c1*c2,d1*d2);
	int f=bet(a.a,a.b,b.a),g=bet(a.a,a.b,b.b);
	if(max(f,g)==-2||min(f,g)==2)return 0;
	if(max(f,g)==-1||min(f,g)==1)return 1;
	return 3;
}
//AOJ1033
//cross point of two lines
cm cll(ln a,ln b){
	return eval(a,crs(b.a,b.b,a.a)/crs(dir(a),dir(b)));
}
//AOJ2160
//反時計回り方向に伸びる垂直二等分線
ln vbis(cm a,cm b){
	cm c=(a+b)*ld(0.5),d=b-a;
	return ln(c,cm(c.x-d.y,c.y+d.x));
}

//GCJ2019R3D
//input: connected graph
//0 -> unbounded area
//         dual
//           ^
//primal(l)--|->(r)
//           |
struct planardual{
	const int n;
	struct E{
		int to,rev;
		cm dir;
		bool operator<(const E&e)const{
			return argcmp(dir,e.dir)<0;
		}
	};
	struct E2{int to,l,r;};
	vvc<E> org;
	vvc<int> idx;
	int s;
	vc<long double> areas;
	vvc<E2> g;
	planardual(const vc<cm>&ps,const vvc<int>&gg):
		n(ps.size()),org(n),idx(n),s(0){
		if(n==1){
			s=1;
			g.resize(1);
			return;
		}
		rep(i,n){
			for(auto to:gg[i])
				org[i].pb(E{to,-1,ps[to]-ps[i]});
			sort(all(org[i]));
			idx[i].resize(org[i].size(),-1);
		}
		rep(i,n)for(auto&e:org[i])
			e.rev=lower_bound(all(org[e.to]),E{-1,-1,-e.dir})-org[e.to].bg;
		vi id(n);
		iota(all(id),0);
		sort(all(id),[&](int a,int b){return cmless(ps[a],ps[b]);});
		for(auto i:id){
			rep(j,org[i].size())if(idx[i][j]==-1){
				int v=i,e=j;
				long double sum=0;
				do{
					idx[v][e]=s;
					int to=org[v][e].to;
					sum+=crs(ps[to],ps[v]);
					e=org[v][e].rev+1;
					if(e==int(org[to].size()))e=0;
					v=to;
				}while(pi(v,e)!=pi(i,j));
				s++;
				areas.pb(sum/2);
			}
		}
		g.resize(s);
		rep(i,n)rep(j,org[i].size()){
			int a=idx[i][j];
			int b=idx[org[i][j].to][org[i][j].rev];
			g[a].pb(E2{b,i,org[i][j].to});
		}
	}
};

}
*/

//using ld=long double;
using ld=frac<int128>;
using cm=complex<ld>;
#define x real()
#define y imag()
//const ld eps=1e-10;
const ld eps=0;
//const ld PI=acos(ld(-1));
//int sgn(ld a){return a<-eps?-1:(a>eps?1:0);}
ld rabs(cm a){return max(abs(a.x),abs(a.y));}
ld signed_rabs(cm a){
	if(abs(a.x)>abs(a.y))return a.x;
	else return a.y;
}
ld dot(cm a,cm b){return a.x*b.x+a.y*b.y;}
ld crs(cm a,cm b){return a.x*b.y-a.y*b.x;}
ld crs(cm a,cm b,cm c){return crs(b-a,c-a);}
int ccw(cm a,cm b){return sgn(crs(a,b));}
int ccw(cm a,cm b,cm c){return ccw(b-a,c-a);}
auto cmless=[](cm a,cm b){
	//int s=sgn(a.x-b.x);
	int s=cmpfrac(a.x,b.x);
	if(s)return s<0;
	//else return sgn(a.y-b.y)<0;
	else return cmpfrac(a.y,b.y)<0;
};
bool cmeq(cm a,cm b){
	return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;
};
//(-pi,0](0,pi]
int argtype(cm a){
	if(sgn(a.y)==0)return a.x<0?1:0;
	return a.y<0?0:1;
}
int argcmp(cm a,cm b){
	int at=argtype(a),bt=argtype(b);
	if(at!=bt)return at<bt?-1:1;
	return -ccw(a,b);
};
bool argless(cm a,cm b){return argcmp(a,b)<0;}
//(-2)[a,-1](0)[b,1](2)
int bet(cm a,cm b,cm c){
	cm d=b-a;
	ld e=dot(d,c-a);
	if(sgn(e)<=0)return sgn(e)-1;
	return sgn(e-norm(d))+1;
}
//AOJ0153
//0-no,1-edge,2-in
int cont(cm a,cm b,cm c,cm d){
	if(ccw(a,b,c)==-1)
		swap(b,c);
	return min({ccw(a,b,d),ccw(b,c,d),ccw(c,a,d)})+1;
}

using ln=pair<cm,cm>;
cm dir(ln a){return a.b-a.a;}
cm eval(ln a,ld b){return a.a+dir(a)*b;}
int bet(ln a,cm b){return bet(a.a,a.b,b);}
int ccw(ln a,cm b){return ccw(a.a,a.b,b);}
cm proj(ln a,cm b){
	cm c=dir(a);
	return a.a+c*dot(c,b-a.a)/norm(c);
}
cm refl(ln a,cm b){
	return ld(2)*proj(a,b)-b;
}
//AOJ1157
//0-no,1-yes(endpoint),2-yes(innner),3-overelap
//if the two line touch like this
// x----x----x
//it returns 1
int iss(ln a,ln b){
	int c1=ccw(a.a,a.b,b.a),c2=ccw(a.a,a.b,b.b);
	int d1=ccw(b.a,b.b,a.a),d2=ccw(b.a,b.b,a.b);
	if(c1||c2||d1||d2)return 1-max(c1*c2,d1*d2);
	int f=bet(a.a,a.b,b.a),g=bet(a.a,a.b,b.b);
	if(max(f,g)==-2||min(f,g)==2)return 0;
	if(max(f,g)==-1||min(f,g)==1)return 1;
	return 3;
}
//AOJ1033
//cross point of two lines
cm cll(ln a,ln b){
	return eval(a,crs(b.a,b.b,a.a)/crs(dir(a),dir(b)));
}
//AOJ2160
//反時計回り方向に伸びる垂直二等分線
ln vbis(cm a,cm b){
	cm c=(a+b)*ld(0.5),d=b-a;
	return ln(c,cm(c.x-d.y,c.y+d.x));
}

//GCJ2019R3D
//input: connected graph
//0 -> unbounded area
//         dual
//           ^
//primal(l)--|->(r)
//           |
struct planardual{
	const int n;
	struct E{
		int to,rev;
		cm dir;
		bool operator<(const E&e)const{
			return argcmp(dir,e.dir)<0;
		}
	};
	struct E2{int to,l,r;};
	vvc<E> org;
	vvc<int> idx;
	int s;
	vc<long double> areas;
	vvc<E2> g;
	planardual(const vc<cm>&ps,const vvc<int>&gg):
		n(ps.size()),org(n),idx(n),s(0){
		if(n==1){
			s=1;
			g.resize(1);
			return;
		}
		rep(i,n){
			for(auto to:gg[i]){
				cm dir=ps[to]-ps[i];
				assert(dir.x.b<=ten(16));
				assert(dir.y.b<=ten(16));
				int128 a=dir.x.a*dir.y.b;
				int128 b=dir.y.a*dir.x.b;
				int128 g=gcd(abs128(a),abs128(b));
				org[i].pb(E{to,-1,cm(a/g,b/g)});
			}
			sort(all(org[i]));
			idx[i].resize(org[i].size(),-1);
		}
		rep(i,n)for(auto&e:org[i])
			e.rev=lower_bound(all(org[e.to]),E{-1,-1,-e.dir})-org[e.to].bg;
		vi id(n);
		iota(all(id),0);
		sort(all(id),[&](int a,int b){return cmless(ps[a],ps[b]);});
		for(auto i:id){
			rep(j,org[i].size())if(idx[i][j]==-1){
				int v=i,e=j;
				long double sum=0;
				int cnt=0;
				vc<pi> history;
				do{
					idx[v][e]=s;
					history.eb(v,e);
					int to=org[v][e].to;
					sum+=crs(ps[to],ps[v]).to_real();
					e=org[v][e].rev+1;
					if(e==int(org[to].size()))e=0;
					v=to;
					if(++cnt>=ten(5)){
						cerr<<vc<pi>(history.ed-100,history.ed)<<endl;
						assert(false);
					}
				}while(pi(v,e)!=pi(i,j));
				s++;
				areas.pb(sum/2);
			}
		}
		g.resize(s);
		rep(i,n)rep(j,org[i].size()){
			int a=idx[i][j];
			int b=idx[org[i][j].to][org[i][j].rev];
			g[a].pb(E2{b,i,org[i][j].to});
		}
	}
};

const ld infld=inf;

bool dbg;

//a は半直線
//b は直線
/*ld param_to_cross(ln a,ln b,ld bpermit){
	ld den=crs(dir(a),dir(b)),t=infld;
	if(sgn(den)==0){
		if(ccw(a,b.a))return infld+1;
		if(bet(a,b.a)>=-1)chmin(t,signed_rabs(b.a-a.a)/signed_rabs(dir(a)));
		if(bet(a,b.b)>=-1)chmin(t,signed_rabs(b.b-a.a)/signed_rabs(dir(a)));
		if(t==infld)return infld+2;
		if(dbg)dmp(t);
	}else{
		t=crs(b.a,b.b,a.a)/den;
		if(dbg)dmp(t);
	}
	if(dbg){
		cm p=eval(a,t);
		ld z=rabs(p-b.a)/rabs(b.b-b.a);
		dmp(z);
	}
	if(sgn(t)<0)return infld+3;
	cm p=eval(a,t);
	ld z=signed_rabs(p-b.a)/signed_rabs(b.b-b.a);
	if(dbg)dmp(z);
	if(ld(0)<=z&&z<=bpermit)
		return t;
	else
		return infld+4;
}*/
ld param_to_cross_2(ln a,ln b,ld&dst){
	ld den=crs(dir(a),dir(b)),t=infld;
	if(sgn(den)==0){
		if(ccw(a,b.a))return infld+1;
		if(bet(a,b.a)>=-1)chmin(t,signed_rabs(b.a-a.a)/signed_rabs(dir(a)));
		if(bet(a,b.b)>=-1)chmin(t,signed_rabs(b.b-a.a)/signed_rabs(dir(a)));
		if(t==infld)return infld+2;
		if(dbg)dmp(t);
	}else{
		t=crs(b.a,b.b,a.a)/den;
		if(dbg)dmp(t);
	}
	if(dbg){
		cm p=eval(a,t);
		ld z=rabs(p-b.a)/rabs(b.b-b.a);
		dmp(z);
	}
	if(sgn(t)<0)return infld+3;
	cm p=eval(a,t);
	if(sgn(p.x)<0||sgn(p.y)<0)return infld;
	if(sgn(p.x-10000)>0||sgn(p.y-10000)>0)return infld;
	ld z=signed_rabs(p-b.a)/signed_rabs(b.b-b.a);
	if(dbg)dmp(z);
	if(ld(0)<=z){
		dst=z.do_g();
		return t;
	}else
		return infld+4;
}

void answer(long double a){
	cout<<a<<endl;
	exit(0);
}

const int nmax=2010;
ld*pbuf[nmax];

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	int n;cin>>n;
	
	vc<cm> p;
	rep(i,n){
		int a,b;cin>>a>>b;
		p.eb(a,b);
	}
	
	//vvc<ld> pbuf(n,vc<ld>(n,infld));
	//vc<ld> pbuf(n*n,infld);
	rep(i,n){
		pbuf[i]=new ld[n];
		rep(j,n)pbuf[i][j]=infld;
	}
	rep(i,n)rep(j,i){
		pbuf[i][j]=param_to_cross_2(ln(p[i],p[(i+1)%n]),ln(p[j],p[(j+1)%n]),pbuf[j][i]);
	}
	
	vc<ld> par(n);
	rep(i,n){
		if(ccw(p[i],p[(i+1)%n],p[(i+2)%n])>0){
			par[i]=1;
		}else{
			ln a(p[i],p[(i+1)%n]);
			par[i]=infld;
			rep(j,n)if(i!=j){
				if(ccw(p[i],p[(i+1)%n],p[j])*ccw(p[i],p[(i+1)%n],p[(j+1)%n])==1)
					continue;
				ln b(p[j],p[(j+1)%n]);
				//ld t=param_to_cross(a,b,1);
				ld t=pbuf[i][j];
				if(sgn(pbuf[j][i]-1)<=0){
					if(sgn(t-1)>0&&t<infld){
						chmin(par[i],t);
					}
				}
			}
			assert(par[i]<infld);
		}
	}
	
	dmp(par);
	
	vc<cm> q;
	vc<ln> ls;
	rep(i,n){
		ln a(p[i],p[(i+1)%n]);
		a.b=eval(a,par[i]);
		ls.pb(a);
	}
	dmp(ls);
	rep(i,n)rep(j,i)if(i!=j){
		//if(iss(ls[i],ls[j])==3){
		if(ccw(p[i],p[(i+1)%n],p[j])==0&&ccw(p[i],p[(i+1)%n],p[(j+1)%n])==0){
			if(ls[i].b==p[(j+1)%n]){
				dmp2(i,j);
				dmp2(ls[i],ls[j]);
				answer(0);
			}
		}
	}
	
	rep(i,n){
		ln a(p[i],p[(i+1)%n]);
		vc<ld> ts;
		rep(j,i){
			//ld t=param_to_cross(a,ln(p[j],p[(j+1)%n]),par[j]);
			ld t=pbuf[i][j];
			if(pbuf[j][i]<=par[j]){
				assert(sgn(t)>=0);
				if(sgn(t-par[i])<=0){
					q.eb(eval(a,t));
				}
			}
		}
	}
	
	/*const int V=ten(9);
	cm random_vec;
	auto cmp_by_dot=[&](cm a,cm b){return dot(a,random_vec)<dot(b,random_vec);};
	
	rep(_,3){
		random_vec=cm(ld(rand_int(-V,V))/V,ld(rand_int(-V,V))/V);
		sort(all(q),cmp_by_dot);
		q.erase(unique(all(q),cmeq),q.ed);
	}
	
	int s=q.size();
	auto getidx=[&](cm a){
		int i=lower_bound(all(q),a,cmp_by_dot)-q.bg;
		rng(j,max(int(0),i-10),min(s,i+10))
			if(cmeq(q[j],a))return j;
		exit(0);
	};*/
	
	sort(all(q),cmless);
	q.erase(unique(all(q),cmeq),q.ed);
	int s=q.size();
	auto getidx=[&](cm a){
		int i=lower_bound(all(q),a,cmless)-q.bg;
		assert(i<s&&cmeq(q[i],a));
		return i;
	};
	
	dmp(q);
	
	vi bound(s,-1);
	vi boundrev(s,-1);
	
	vvc<int> g(s);
	vvc<int> d(s);
	
	vc<pi> ads;
	
	cm www(ld(729108,109),ld(1057705,109));
	rep(i,n){
		ln a(p[i],p[(i+1)%n]);
		vc<ld> ts;
		rep(j,n)if(i!=j){
			if(i==47&&j==44)dbg=true;
			if(i==44&&j==47)dbg=true;
			//ld t=param_to_cross(a,ln(p[j],p[(j+1)%n]),par[j]);
			ld t=pbuf[i][j];
			if(i==47&&j==44){
				dbg=false;
				dmp(t);
				dmp(eval(a,t));
			}
			if(i==44&&j==47)dbg=false;
			if(pbuf[j][i]<=par[j]){
				assert(sgn(t)>=0);
				if(sgn(t-par[i])<=0){
					ts.pb(t);
				}
			}
		}
		sort(all(ts));
		ts.erase(unique(all(ts),[&](ld b,ld c){return sgn(b-c)==0;}),ts.ed);
		assert(ts.size()>=2);
		assert(sgn(ts.back()-par[i])==0);
		vi z;
		for(auto t:ts)
			z.pb(getidx(eval(a,t)));
		rep(j,ts.size()-1){
			int from=z[j],to=z[j+1];
			if(q[from]==www){
				dmp(p[i]);
				dmp(p[(i+1)%n]);
				dmp(q[from]);
				dmp(q[to]);
				dmp(ts[j]);
			}
			if(q[to]==www){
				dmp(p[i]);
				dmp(p[(i+1)%n]);
				dmp(q[from]);
				dmp(q[to]);
				dmp(ts[j]);
			}
			g[from].pb(to);
			g[to].pb(from);
			if(sgn(ts[j]-1)<0){
				assert(bound[from]==-1);
				assert(boundrev[to]==-1);
				bound[from]=g[from].size()-1;
				boundrev[to]=g[to].size()-1;
				d[from].pb(0);
				d[to].pb(0);
			}else{
				d[from].pb(-1);
				d[to].pb(1);
			}
			if(sgn(ts[j]-1)==0)
				ads.eb(from,z.back());
		}
	}
	
	rep(i,n)
		delete[] pbuf[i];
	
	/*
	rep(i,n){
		ln a(p[i],p[(i+1)%n]);
		vc<ld> ts;
		rep(j,n)if(i!=j){
			ld t=param_to_cross(a,ln(p[j],p[(j+1)%n]),par[j]);
			assert(sgn(t)>=0);
			if(sgn(t-par[i])<=0){
				if(i==44&&t==ld(377,327))
					dmp(j);
				ts.pb(t);
			}
		}
		sort(all(ts));
		ts.erase(unique(all(ts),[&](ld b,ld c){return sgn(b-c)==0;}),ts.ed);
		assert(ts.size()>=2);
		assert(sgn(ts.back()-par[i])==0);
		vi z;
		for(auto t:ts)
			z.pb(getidx(eval(a,t)));
		rep(j,ts.size()-1){
			int from=z[j],to=z[j+1];
			if(sgn(ts[j]-1)==0){
				int k=z.back();
				if(bound[k]==-1){
					dmp(i);
					dmp2(p[i],p[(i+1)%n]);
					dmp(q[from]);
					dmp(q[to]);
					dmp(q[k]);
					dmp(par[i]);
					assert(false);
				}
			}
		}
	}*/
	
	//cerr<<s<<" waf"<<endl;
	
	int cnt=0;
	for(auto w:ads){
		int cur=w.a;
		assert(bound[w.b]!=-1);
		//if(bound[w.b]==-1)exit(0);
		while(cur!=w.b){
			int i=bound[cur];
			//assert(i!=-1);
			int nx=g[cur][i];
			int j=boundrev[nx];
			//assert(j!=-1);
			if(g[nx][j]!=cur){
				exit(0);
			}
			assert(g[nx][j]==cur);
			d[cur][i]++;
			d[nx][j]--;
			cur=nx;
			if(++cnt>ten(7))
				//exit(0);
				assert(false);
		}
	}
	
	//cerr<<cnt<<endl;
	
	vvc<pi> tod(s);
	rep(i,s){
		rep(j,g[i].size())
			tod[i].eb(g[i][j],d[i][j]);
		sort(all(tod[i]));
	}
	auto getdif=[&](int i,int j){
		return lower_bound(all(tod[i]),pi(j,-inf))->b;
	};
	
	/*vc<ysp::cm> qtmp(s);
	rep(i,s)
		qtmp[i]=ysp::cm(q[i].x.to_real(),q[i].y.to_real());
	auto dual=ysp::planardual(qtmp,g);*/
	auto dual=planardual(q,g);
	
	//cerr<<"Dual!"<<endl;
	
	vi sum(dual.s,-1);
	
	function<void(int,int)> dfs;
	dfs=[&](int v,int cur){
		assert(sum[v]==-1);
		assert(cur>=0);
		sum[v]=cur;
		for(auto e:dual.g[v]){
			if(sum[e.to]==-1)
				dfs(e.to,cur+getdif(e.l,e.r));
		}
	};
	dfs(0,0);
	
	long double ans=0;
	rng(i,1,dual.s)
		if(sum[i]==0)
			ans+=dual.areas[i];
	
	cout<<ans<<endl;
}



Measured memory_bytes: 179884