Fair Chocolate-Cutting

You are given a flat piece of chocolate of convex polygon shape. You are to cut it into two pieces of precisely the same amount with a straight knife.

Write a program that computes, for a given convex polygon, the maximum and minimum lengths of the line segments that divide the polygon into two equal areas.

The figures below correspond to first two sample inputs. Two dashed lines in each of them correspond to the equal-area cuts of minimum and maximum lengths.

<image>
Figure F.1. Sample Chocolate Pieces and Cut Lines

Input

The input consists of a single test case of the following format.


$n$
$x_1$ $y_1$
...
$x_n$ $y_n$


The first line has an integer $n$, which is the number of vertices of the given polygon. Here, $n$ is between 3 and 5000, inclusive. Each of the following $n$ lines has two integers $x_i$ and $y_i$, which give the coordinates ($x_i, y_i$) of the $i$-th vertex of the polygon, in counterclockwise order. Both $x_i$ and $y_i$ are between 0 and 100 000, inclusive.

The polygon is guaranteed to be simple and convex. In other words, no two edges of the polygon intersect each other and interior angles at all of its vertices are less than $180^\circ$.

Output

Two lines should be output. The first line should have the minimum length of a straight line segment that partitions the polygon into two parts of the equal area. The second line should have the maximum length of such a line segment. The answer will be considered as correct if the values output have an absolute or relative error less than $10^{-6}$.

Sample Input 1


4
0 0
10 0
10 10
0 10


Sample Output 1


10
14.142135623730950488


Sample Input 2


3
0 0
6 0
3 10


Sample Output 2


4.2426406871192851464
10.0


Sample Input 3


5
0 0
99999 20000
100000 70000
33344 63344
1 50000


Sample Output 3


54475.580091580027976
120182.57592539864775


Sample Input 4


6
100 350
101 349
6400 3440
6400 3441
1200 7250
1199 7249


Sample Output 4


4559.2050019027964982
6216.7174287968524227






Example

Input

4
0 0
10 0
10 10
0 10


Output

10
14.142135623730950488
#include<bits/stdc++.h>
#define inf 1<<29
#define linf (1e16)
#define eps (1e-8)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;
#define track() cout<<"AAAAAAAAA"<<endl;

class Point{
public:
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}

  Point operator+(Point p){ return Point(x+p.x,y+p.y);}
  Point operator-(Point p){ return Point(x-p.x,y-p.y);}
  Point operator*(double k){ return Point(x*k,y*k);}
  Point operator/(double k){ return Point(x/k,y/k);}
  bool operator<(Point p)const{ return equals(x,p.x) ? y-p.y<-eps : x-p.x<-eps; }
  bool operator==(Point p)const{ return fabs(x-p.x)<eps && fabs(y-p.y)<eps;}

  double abs(){ return sqrt(norm());}
  double norm(){ return (x*x+y*y);}
};
typedef Point Vector;
typedef vector<Point> Polygon;

class Segment{
public:
  Point p1,p2;
  Segment(Point p1=Point(),Point p2=Point()):p1(p1),p2(p2){}
};
typedef Segment Line;

double norm(Vector a){ return (a.x*a.x+a.y*a.y);}
double abs(Vector a){ return sqrt(norm(a));}
double dot(Vector a,Vector b){ return (a.x*b.x+a.y*b.y);}
double cross(Vector a,Vector b){ return (a.x*b.y-a.y*b.x);}

double Area(Polygon p){
  double area=0.0;
  int n=p.size();
  for(int i=0;i<n;i++)area+=cross(p[i],p[(i+1)%n]);
  return area/2.0;
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

bool onLine(Line L,Point p){ return getDistanceLP(L,p)<eps; }
bool onSegment(Segment s,Point p){
  if(!onLine(s,p))return false;
  if(dot(s.p2-s.p1,p-s.p1)<-eps)return false;
  if(dot(s.p1-s.p2,p-s.p2)<-eps)return false;
  return true;
}

typedef pair<Point,Point> pp;

int n,m;
Polygon P;
vector<Point> D;
vector<pp> V;
double area;

Point cal(Point base,int i){
  double sum = 0.0,t = 0.0;
  while(1){
    t = cross(P[i]-base,P[(i+1)%n]-base)/2.0;
    if(area<sum+t)break;
    i = (i+1)%n;
    sum+=t;
  }
  double a = (area-sum)/t;
  Vector v = P[(i+1)%n]-P[i];
  return P[i]+v*a;
}

Point Search(Point base,Point a,Point b,double X){
  Vector v = b-a;
  v = v/abs(b-a);
  double L = 0.0, R = abs(b-a), M;
  FOR(i,0,50){
    M = (L+R)/2.0;
    Point c = a+v*M;
    if(X>cross(a-base,c-base)/2.0)L = M;
    else R = M;
  }
  return a+v*M;
}

double Minimum(){
  double res = inf;
  FOR(i,0,m){
    int j = (i+1)%m;
    Vector v = V[j].f-V[i].f;
    double dis = abs(v);
    double X = cross(V[j].f-V[i].f,V[i].s-V[i].f)/2.0;
    v = v/dis;
    double L=0.0,R=dis;
    FOR(k,0,50){
      double m1=(L*phi+R)/(1.0+phi);
      double m2=(L+R*phi)/(1.0+phi);
      Point p1 = V[i].f+v*m1;
      Point p2 = V[i].f+v*m2;
      double y1 = cross(V[j].f-p1,V[i].s-p1)/2.0;
      double y2 = cross(V[j].f-p2,V[i].s-p2)/2.0;
      Point p3 = Search(p1,V[i].s,V[j].s,X-y1);
      Point p4 = Search(p2,V[i].s,V[j].s,X-y2);
      double res1 = abs(p1-p3);
      double res2 = abs(p2-p4);
      if(res1<res2)R=m2;
      else L=m1;
      res = min(res,res1);
    }
  }
  return res;
}

double Maximum(){
  double res = 0.0;
  FOR(i,0,V.size())res = max(res,abs(V[i].f-V[i].s));
  return res;
}

void solve(){
  area = Area(P)/2.0;
  FOR(i,0,n)D.pb(cal(P[i],(i+1)%n));
  FOR(i,0,n){
    Segment S = Segment(P[i],P[(i+1)%n]);
    vector<pair<double,pp> > tmp;
    V.pb(mp(P[i],D[i]));
    FOR(j,0,n){
      if(D[j]==P[i])continue;
      if(D[j]==P[(i+1)%n])continue;
      if(onSegment(S,D[j]))tmp.pb(mp(abs(P[i]-D[j]),mp(D[j],P[j])));
    }
    sort(all(tmp));
    FOR(j,0,tmp.size())V.pb(tmp[j].s);
  }
  m = V.size();
  pd(Minimum());
  pd(Maximum());
  return;
}

int main()
{
  cin>>n;
  P.resize(n);
  FOR(i,0,n)cin>>P[i].x>>P[i].y;
  solve();
  return 0;
}

