#pragma once
structPoint{usingT=__int128_t;Tx,y;Point():x(0),y(0){}Point(Tx_,Ty_):x(x_),y(y_){}Point&operator+=(constPoint&p){this->x+=p.x;this->y+=p.y;return*this;}Point&operator-=(constPoint&p){this->x-=p.x;this->y-=p.y;return*this;}intpos()const{if(y<0)return-1;if(y==0&&0<=x)return0;return1;}Pointoperator+(constPoint&p)const{returnPoint(*this)+=p;}Pointoperator-(constPoint&p)const{returnPoint(*this)-=p;}Pointoperator-()const{returnPoint(-this->x,-this->y);}booloperator==(constPoint&p)const{returnx==p.x&&y==p.y;}booloperator!=(constPoint&p)const{returnx!=p.x||y!=p.y;}booloperator<(constPoint&p)const{returnx==p.x?y<p.y:x<p.x;}friendistream&operator>>(istream&is,Point&p){longlongx,y;is>>x>>y;p.x=x,p.y=y;returnis;}friendostream&operator<<(ostream&os,constPoint&p){os<<(longlong)(p.x)<<" "<<(longlong)(p.y);returnos;}};usingPoints=vector<Point>;Point::Tdot(constPoint&a,constPoint&b){returna.x*b.x+a.y*b.y;}Point::Tcross(constPoint&a,constPoint&b){returna.x*b.y-a.y*b.x;}// sort by argument (-Pi ~ Pi)voidArgumentSort(Points&v){sort(begin(v),end(v),[](Pointa,Pointb){if(a.pos()!=b.pos())returna.pos()<b.pos();returncross(a,b)>0;});}// 1 ... counterclockwise / 0 straight / -1 clockwiseintccw(constPoint&a,constPoint&b,constPoint&c){Point::Tt=cross(b-a,c-a);returnt<0?-1:t==0?0:1;}// v must have sorted by x-coordinatePointsLowerHull(constPoints&ps){intN=(int)ps.size();for(inti=0;i<N-1;i++)assert(ps[i].x<=ps[i+1].x);if(N<=2)returnps;Pointsconvex(N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}convex.resize(k);returnconvex;}PointsUpperHull(constPoints&ps){intN=(int)ps.size();for(inti=0;i<N-1;i++)assert(ps[i].x<=ps[i+1].x);if(N<=2)returnps;Pointsconvex(N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])>=0)--k;}convex.resize(k);returnconvex;}PointsConvexHull(Pointsps){sort(begin(ps),end(ps));ps.erase(unique(begin(ps),end(ps)),end(ps));intN=ps.size();if(N<=2)returnps;Pointsconvex(2*N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}for(inti=N-2,t=k+1;i>=0;convex[k++]=ps[i--]){while(k>=t&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}convex.resize(k-1);returnconvex;}
#line 2 "geometry/integer-geometry.hpp"
structPoint{usingT=__int128_t;Tx,y;Point():x(0),y(0){}Point(Tx_,Ty_):x(x_),y(y_){}Point&operator+=(constPoint&p){this->x+=p.x;this->y+=p.y;return*this;}Point&operator-=(constPoint&p){this->x-=p.x;this->y-=p.y;return*this;}intpos()const{if(y<0)return-1;if(y==0&&0<=x)return0;return1;}Pointoperator+(constPoint&p)const{returnPoint(*this)+=p;}Pointoperator-(constPoint&p)const{returnPoint(*this)-=p;}Pointoperator-()const{returnPoint(-this->x,-this->y);}booloperator==(constPoint&p)const{returnx==p.x&&y==p.y;}booloperator!=(constPoint&p)const{returnx!=p.x||y!=p.y;}booloperator<(constPoint&p)const{returnx==p.x?y<p.y:x<p.x;}friendistream&operator>>(istream&is,Point&p){longlongx,y;is>>x>>y;p.x=x,p.y=y;returnis;}friendostream&operator<<(ostream&os,constPoint&p){os<<(longlong)(p.x)<<" "<<(longlong)(p.y);returnos;}};usingPoints=vector<Point>;Point::Tdot(constPoint&a,constPoint&b){returna.x*b.x+a.y*b.y;}Point::Tcross(constPoint&a,constPoint&b){returna.x*b.y-a.y*b.x;}// sort by argument (-Pi ~ Pi)voidArgumentSort(Points&v){sort(begin(v),end(v),[](Pointa,Pointb){if(a.pos()!=b.pos())returna.pos()<b.pos();returncross(a,b)>0;});}// 1 ... counterclockwise / 0 straight / -1 clockwiseintccw(constPoint&a,constPoint&b,constPoint&c){Point::Tt=cross(b-a,c-a);returnt<0?-1:t==0?0:1;}// v must have sorted by x-coordinatePointsLowerHull(constPoints&ps){intN=(int)ps.size();for(inti=0;i<N-1;i++)assert(ps[i].x<=ps[i+1].x);if(N<=2)returnps;Pointsconvex(N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}convex.resize(k);returnconvex;}PointsUpperHull(constPoints&ps){intN=(int)ps.size();for(inti=0;i<N-1;i++)assert(ps[i].x<=ps[i+1].x);if(N<=2)returnps;Pointsconvex(N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])>=0)--k;}convex.resize(k);returnconvex;}PointsConvexHull(Pointsps){sort(begin(ps),end(ps));ps.erase(unique(begin(ps),end(ps)),end(ps));intN=ps.size();if(N<=2)returnps;Pointsconvex(2*N);intk=0;for(inti=0;i<N;convex[k++]=ps[i++]){while(k>=2&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}for(inti=N-2,t=k+1;i>=0;convex[k++]=ps[i--]){while(k>=t&&ccw(convex[k-2],convex[k-1],ps[i])<=0)--k;}convex.resize(k-1);returnconvex;}