#ifndef NO_HEAD_FILE
#ifndef PDQSORT_H//一个排序 
#define PDQSORT_H
#include<bits/stdc++.h>
#if __cplusplus>=201103L
#include<cstdint>
#include<type_traits>
#define PDQSORT_PREFER_MOVE(x) std::move(x)
#else
#define PDQSORT_PREFER_MOVE(x) (x)
#endif
using namespace std;
namespace pdqsort_detail{
	enum{
		insertion_sort_threshold=24,
		ninther_threshold=128,
		partial_insertion_sort_limit=8,
		block_size=64,
		cacheline_size=64
	};
#if __cplusplus>=201103L
	template<class T>struct is_default_compare:std::false_type{};
	template<class T>struct is_default_compare<std::less<T>>:std::true_type{};
	template<class T>struct is_default_compare<std::greater<T>>:std::true_type{};
#endif
	template<class T>
	inline int log2(T n){
		int log=0;
		while(n>>=1)++log;
		return log;
	}
	template<class Iter,class Compare>
	inline void insertion_sort(Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		if(begin==end)return;
		for(Iter cur=begin+1;cur!=end;++cur){
			Iter sift=cur,sift_1=cur-1;
			if(comp(*sift,*sift_1)){
				T tmp=PDQSORT_PREFER_MOVE(*sift);
				do{*sift--=PDQSORT_PREFER_MOVE(*sift_1);}
				while(sift!=begin&&comp(tmp,*--sift_1));
				*sift=PDQSORT_PREFER_MOVE(tmp);
			}
		}
	}
	template<class Iter,class Compare>
	inline void unguarded_insertion_sort(Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		if(begin==end)return;
		for(Iter cur=begin+1;cur!=end;++cur){
			Iter sift=cur,sift_1=cur-1;
			if(comp(*sift,*sift_1)){
				T tmp=PDQSORT_PREFER_MOVE(*sift);
				do{*sift--=PDQSORT_PREFER_MOVE(*sift_1);}
				while(comp(tmp,*--sift_1));
				*sift=PDQSORT_PREFER_MOVE(tmp);
			}
		}
	}
	template<class Iter,class Compare>
	inline bool partial_insertion_sort(Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		if(begin==end)return 1;
		std::size_t limit=0;
		for(Iter cur=begin+1;cur!=end;++cur){
			Iter sift=cur,sift_1=cur-1;
			if(comp(*sift,*sift_1)){
				T tmp=PDQSORT_PREFER_MOVE(*sift);
				do{*sift--=PDQSORT_PREFER_MOVE(*sift_1);}
				while(sift!=begin&&comp(tmp,*--sift_1));
				*sift=PDQSORT_PREFER_MOVE(tmp);
				limit+=cur-sift;
			}
			if(limit>partial_insertion_sort_limit)return 0;
		}
		return 1;
	}
	template<class Iter,class Compare>
	inline void sort2(Iter a,Iter b,Compare comp){
		if(comp(*b,*a))std::iter_swap(a,b);
	}
	template<class Iter,class Compare>
	inline void sort3(Iter a,Iter b,Iter c,Compare comp){
		sort2(a,b,comp);sort2(b,c,comp);sort2(a,b,comp);
	}
	template<class T>inline T*align_cacheline(T*p){
#if defined(UINTPTR_MAX)&&__cplusplus>=201103L
		std::uintptr_t ip=reinterpret_cast<std::uintptr_t>(p);
#else
		std::size_t ip=reinterpret_cast<std::size_t>(p);
#endif
		ip=(ip+cacheline_size-1)&-cacheline_size;
		return reinterpret_cast<T*>(ip);
	}
	template<class Iter>inline void swap_offsets(Iter first,Iter last,
	unsigned char*offsets_l,unsigned char*offsets_r,size_t num,bool use_swaps){
		typedef typename std::iterator_traits<Iter>::value_type T;
		if(use_swaps)for(size_t i=0;i<num;++i){
			std::iter_swap(first+offsets_l[i],last-offsets_r[i]);
		}else if(num>0){
			Iter l=first+offsets_l[0],r=last-offsets_r[0];
			T tmp(PDQSORT_PREFER_MOVE(*l));*l=PDQSORT_PREFER_MOVE(*r);
			for(size_t i=1;i<num;++i){
				l=first+offsets_l[i];*r=PDQSORT_PREFER_MOVE(*l);
				r=last-offsets_r[i];*l=PDQSORT_PREFER_MOVE(*r);
			}
			*r=PDQSORT_PREFER_MOVE(tmp);
		}
	}
	template<class Iter,class Compare>
	inline std::pair<Iter,bool>
	partition_right_branchless(Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		T pivot(PDQSORT_PREFER_MOVE(*begin));
		Iter first=begin,last=end;
		while(comp(*++first,pivot));
		if(first-1==begin)while(first<last&&!comp(*--last,pivot));
		else while(!comp(*--last,pivot));
		bool already_partitioned=first>=last;
		if(!already_partitioned){
			std::iter_swap(first,last);++first;
			unsigned char offsets_l_storage[block_size+cacheline_size];
			unsigned char offsets_r_storage[block_size+cacheline_size];
			unsigned char*offsets_l=align_cacheline(offsets_l_storage);
			unsigned char*offsets_r=align_cacheline(offsets_r_storage);
			Iter offsets_l_base=first,offsets_r_base=last;
			size_t num_l,num_r,start_l,start_r;
			num_l=num_r=start_l=start_r=0;
			while(first<last){
				size_t num_unknown=last-first;
				size_t left_split=!num_l?(!num_r?num_unknown/2:num_unknown):0;
				size_t right_split=!num_r?num_unknown-left_split:0;
				if(left_split>=block_size){
					for(size_t i=0;i<block_size;){
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
						offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
					}
				}else for(size_t i=0;i<left_split;){
					offsets_l[num_l]=i++;num_l+=!comp(*first,pivot);++first;
				}
				if(right_split>=block_size){
					for(size_t i=0;i<block_size;){
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
						offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
					}
				}else for(size_t i=0;i<right_split;){
					offsets_r[num_r]=++i;num_r+=comp(*--last,pivot);
				}
				size_t num=std::min(num_l,num_r);
				swap_offsets(offsets_l_base,offsets_r_base,offsets_l+start_l,
				offsets_r+start_r,num,num_l==num_r);
				num_l-=num,num_r-=num;
				start_l+=num,start_r+=num;
				if(!num_l){
					start_l=0;
					offsets_l_base=first;
				}
				if(!num_r){
					start_r=0;
					offsets_r_base=last;
				}
			}
			if(num_l){
				offsets_l+=start_l;
				while(num_l--)std::iter_swap
				(offsets_l_base+offsets_l[num_l],--last);
				first=last;
			}
			if(num_r){
				offsets_r+=start_r;
				while(num_r--)std::iter_swap
				(offsets_r_base-offsets_r[num_r],first),++first;
				last=first;
			}
		}
		Iter pivot_pos=first-1;
		*begin=PDQSORT_PREFER_MOVE(*pivot_pos);
		*pivot_pos=PDQSORT_PREFER_MOVE(pivot);
		return std::make_pair(pivot_pos, already_partitioned);
	}
	template<class Iter,class Compare>
	inline std::pair<Iter,bool>partition_right(
	Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		T pivot(PDQSORT_PREFER_MOVE(*begin));
		Iter first=begin,last=end;
		while(comp(*++first,pivot));
		if(first-1==begin)while(first<last&&!comp(*--last,pivot));
		else while(!comp(*--last,pivot));
		bool already_partitioned=first>=last;
		while(first<last){
			std::iter_swap(first,last);
			while(comp(*++first,pivot));
			while(!comp(*--last,pivot));
		}
		Iter pivot_pos=first-1;
		*begin=PDQSORT_PREFER_MOVE(*pivot_pos);
		*pivot_pos=PDQSORT_PREFER_MOVE(pivot);
		return std::make_pair(pivot_pos,already_partitioned);
	}
	template<class Iter,class Compare>
	inline Iter partition_left(Iter begin,Iter end,Compare comp){
		typedef typename std::iterator_traits<Iter>::value_type T;
		T pivot(PDQSORT_PREFER_MOVE(*begin));
		Iter first=begin,last=end;
		while(comp(pivot,*--last));
		if(last+1==end)while(first<last&&!comp(pivot,*++first));
		else while(!comp(pivot,*++first));
		while(first<last){
			std::iter_swap(first,last);
			while(comp(pivot,*--last));
			while(!comp(pivot,*++first));
		}
		Iter pivot_pos=last;
		*begin=PDQSORT_PREFER_MOVE(*pivot_pos);
		*pivot_pos=PDQSORT_PREFER_MOVE(pivot);
		return pivot_pos;
	}
	template<class Iter, class Compare, bool Branchless>
	inline void pdqsort_loop(Iter begin,Iter end,Compare comp,int bad_allowed
	,bool leftmost=1){
		typedef typename std::iterator_traits<Iter>::difference_type diff_t;
		while(1){
			diff_t size=end-begin;
			if(size<insertion_sort_threshold){
				if(leftmost)insertion_sort(begin,end,comp);
				else unguarded_insertion_sort(begin,end,comp);
				return;
			}
			diff_t s2=size/2;
			if(size>ninther_threshold){
				sort3(begin,begin+s2,end-1,comp);
				sort3(begin+1,begin+(s2-1),end-2,comp);
				sort3(begin+2,begin+(s2+1),end-3,comp);
				sort3(begin+(s2-1),begin+s2,begin+(s2+1),comp);
				std::iter_swap(begin,begin+s2);
			}else sort3(begin+s2,begin,end-1,comp);
			if(!leftmost&&!comp(*(begin-1),*begin)){
				begin=partition_left(begin,end,comp)+1;
				continue;
			}
			std::pair<Iter,bool>part_result=Branchless?
			partition_right_branchless(begin,end,comp)
			:partition_right(begin,end,comp);
			Iter pivot_pos=part_result.first;
			bool already_partitioned=part_result.second;
			diff_t l_size,r_size=end-(pivot_pos+1);
			bool highly_unbalanced=l_size<size/8||r_size<size/8;
			if(highly_unbalanced){
				if(--bad_allowed==0){
					std::make_heap(begin,end,comp);
					std::sort_heap(begin,end,comp);
					return;
				}
				if(l_size>=insertion_sort_threshold){
					std::iter_swap(begin,begin+l_size/4);
					std::iter_swap(pivot_pos-1,pivot_pos-l_size/4);
					if(l_size > ninther_threshold){
						std::iter_swap(begin+1,begin+(l_size/4+1));
						std::iter_swap(begin+2,begin+(l_size/4+2));
						std::iter_swap(pivot_pos-2,pivot_pos-(l_size/4+1));
						std::iter_swap(pivot_pos-3,pivot_pos-(l_size/4+2));
					}
				}
				if(r_size>=insertion_sort_threshold){
					std::iter_swap(pivot_pos+1,pivot_pos+(1+r_size/4));
					std::iter_swap(end-1,end-r_size/4);
					if(r_size>ninther_threshold){
						std::iter_swap(pivot_pos+2,pivot_pos+(2+r_size/4));
						std::iter_swap(pivot_pos+3,pivot_pos+(3+r_size/4));
						std::iter_swap(end-2,end-(1+r_size/4));
						std::iter_swap(end-3,end-(2+r_size/4));
					}
				}
			}else{
				if(already_partitioned&&partial_insertion_sort(begin,pivot_pos
				,comp)&&partial_insertion_sort(pivot_pos+1,end,comp))return;
			}
			pdqsort_loop<Iter,Compare,Branchless>(begin,pivot_pos,comp,bad_allowed,leftmost);
			begin=pivot_pos+1,leftmost=0;
		}
	}
}
template<class Iter,class Compare>
inline void pdqsort(Iter begin,Iter end,Compare comp){
	if(begin==end)return;
#if __cplusplus>=201103L
	pdqsort_detail::pdqsort_loop<Iter,Compare,
		pdqsort_detail::is_default_compare<typename std::decay<Compare>::type>::value&&
		std::is_arithmetic<typename std::iterator_traits<Iter>::value_type>
		::value>(begin,end,comp,pdqsort_detail::log2(end-begin));
#else
	pdqsort_detail::pdqsort_loop<Iter,Compare,0>(
	begin,end,comp,pdqsort_detail::log2(end-begin));
#endif
}
template<class Iter>
inline void pdqsort(Iter begin,Iter end){
	typedef typename std::iterator_traits<Iter>::value_type T;
	pdqsort(begin,end,std::less<T>());
}
template<class Iter,class Compare>
inline void pdqsort_branchless(Iter begin,Iter end,Compare comp){
	if(begin==end)return;
	pdqsort_detail::pdqsort_loop<Iter,Compare,1>(
	begin,end,comp,pdqsort_detail::log2(end-begin));
}
template<class Iter>
inline void pdqsort_branchless(Iter begin,Iter end){
	typedef typename std::iterator_traits<Iter>::value_type T;
	pdqsort_branchless(begin,end,std::less<T>());
}
#undef PDQSORT_PREFER_MOVE
#endif
using namespace std;
#endif //Maybe it don't need head files.
#pragma GCC Optimize 1
#pragma GCC Optimize 2
#pragma GCC Optimize 3
#ifndef TRAIN_HEAD //It's so long!
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(3)
#pragma GCC optimize(2)
#pragma GCC optimize(1)
#pragma GCC optimize("Og")
#pragma GCC optimize("Os")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#endif
#define inl __inline__ __attribute__((always_inline))
namespace fastIO{
#ifdef __cplusplus
	extern "C"{
#endif
#define get getchar
#define put putchar
#define ioFast1 ios::sync_with_stdio(0)
#define ioFast2 cin.tie(0),cout.tie(0)//Only cin,cout
#define ioFast ioFast1,ioFast2
	inl int read(){//It can be faster ^_^
		register int f=0,a=0,c;
		for(;!isdigit(c=get());c^45||++f);
		for(a=c&15;isdigit(c=get());a=a*10+(c&15));
		f&&(a=-a);return a;
	}
	inl void write(int x){
		register short n=0,ch[10];
		if(!x){putchar(48);return;}
		if(x<0)putchar(45),x=-x;
		for(;x;ch[n++]=x%10,x/=10);
		while(n--)putchar(ch[n]+48);
	}
#ifdef __cplusplus
	}
#endif
}
namespace Small_Func{
#define sswap(a,b) {typeof(a)t=a;a=b;b=t;}
	auto mmax=[](int a,int b){return a>b?a:b;};//C++11
	auto mmin=[](int a,int b){return a<b?a:b;};
//#define mmax(a,b) ((a)>(b)?(a):(b))
//#define mmin(a,b) ((a)<(b)?(a):(b))
#define Sqrt __builtin_sqrt
	inl int isPrime(int x){
		if(x<2)return 0;
		for(int i=2;i<=Sqrt(x);i++){
			if(x%i==0)return 0;
		}
		return 1;
	}
	inl int  _abs(int x){return x>0?x:-x;}
	int sum(int x,...){
		int s=0;va_list p;va_start(p,x);
		for(int i=0;i<x;i++)s+=va_arg(p,int);
		return s;
	}
#ifdef __cplusplus
	template<int p,int i>struct is_prime{//整活内容 
		enum{prim=p%i&&is_prime<(i>2?p:0),i-1>::prim};
	};
	template<>struct is_prime<0,0>{enum{prim=1};};
	template<>struct is_prime<0,1>{enum{prim=1};};
	template<int i>struct prime_print{
		prime_print<i-1>pp;
		void print(){pp.print();if(is_prime<i,i-1>::prim)cout<<" "<<i;}
	};
	template<>struct prime_print<2>{
		void print(){cout<<2;}
	};
#define Isprime(a) ((a)==2?1:is_prime<(a),(a)-1>::prim)
#endif
}
namespace Geometry{//Studying
	using::fabs;
	using db=double;//or"typedef double db;"
					//or"#define db double;"
	const db pi=acos(-1),eps=1e-8;
	inl int sgn(db x){
		if(fabs(x)<eps)return 0;
		return x<0?-1:1;
	}
	inl int dcmp(db a,db b){
		if(fabs(a-b)<eps)return 0;
		return a<b?-1:1;
	}
	struct Point{
		double x,y;
		Point(){}
		Point(double x,double y):x(x),y(y){}
	};
	inl double Distance(Point a,Point b){return hypot(a.x-b.x,a.y-b.y);}
	typedef Point Vector;
	inl Point operator+(Point a,Point b){return Point(a.x+b.x,a.y+b.y);}
	inl Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
	inl Point operator*(Point a,db k){return Point(a.x*k,a.y*k);}
	inl Point operator/(Point a,db k){return Point(a.x/k,a.y/k);}
	inl bool operator==(Point a,Point b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
	inl bool operator!=(Point a,Point b){return !(a==b);}
	inl db Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
	inl db Len2(Vector a){return Dot(a,a);}
	inl db Len(Vector a){return sqrt(Len2(a));}
	inl db Angle(Vector a,Vector b){return acos(Dot(a,b)/Len(a)/Len(b));}
	inl db Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
	inl db Area2(Point a,Point b,Point c){return Cross(b-a,c-a);}
	inl Vector Rotate(Vector a,double rad){
		return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
	}
	inl Vector Normal(Vector a){return Vector(-a.y/Len(a),a.x/Len(a));}
	inl bool Parallel(Vector a,Vector b){return sgn(Cross(a,b))==0;}
	struct Line{
		Point p1,p2;
		Line(){}
		Line(Point p1,Point p2):p1(p1),p2(p2){}
		Line(Point p,double angle){
			p1=p;
			if(sgn(angle-pi/2)==0)p2=p1+Point(0,1);
			else p2=p1+Point(1,tan(angle));
		}
		Line(double a,double b,double c){//ax+by+c=0
			if(sgn(a)==0){
				p1=Point(0,-c/b);
				p2=Point(1,-c/b);
			}
			else if(sgn(b)==0){
				p1=Point(-c/a,0);
				p2=Point(-c/a,1);
			}
			else{
				p1=Point(0,-c/b);
				p2=Point(1,(-c-a)/b);
			}
		}
	};
	using Segment=Line;
	int Point_line_relation(Point p,Line v){
		int c=sgn(Cross(p-v.p1,v.p2-v.p1));
		if(c<0)return 1;//left
		if(c>0)return 2;//right
		return 0;//on the line
	}
	bool Point_on_seg(Point p,Line v){//0:p isn't on v ; 1:p is on v
		return sgn(Cross(p-v.p1,v.p2-v.p1))==0&&sgn(Dot(p-v.p1,p-v.p2))<=0;
	}
	double Dis_point_line(Point p,Line v){
		return fabs(Cross(p-v.p1,v.p2-v.p1))/Distance(v.p1,v.p2);
	}
	Point Point_line_proj(Point p,Line v){
		double k=Dot(v.p2-v.p1,p-v.p1)/Len2(v.p2-v.p1);
		return v.p1+(v.p2-v.p1)*k;
	}
	Point Point_line_symmetry(Point p,Line v){
		Point q=Point_line_proj(p,v);
		return Point(2*q.x-p.x,2*q.y-p.y);
	}
	double Dis_point_seg(Point p,Segment v){
		if(sgn(Dot(p-v.p1,v.p2-v.p1))<0||sgn(Dot(p-v.p2,v.p1-v.p2))<0)
			return min(Distance(p,v.p1),Distance(p,v.p2));
		return Dis_point_line(p,v);
	}
	int Line_relation(Line v1,Line v2){
		if(sgn(Cross(v1.p2-v1.p1,v2.p2-v2.p1))==0){
			if(Point_line_relation(v1.p1,v2)==0)return 1;//1:重合 
			return 0;									//0:平行 
		}
		return 2;										//2:相交 
	}
	Point Cross_point(Point a,Point b,Point c,Point d){
		double s1=Cross(b-a,c-a),s2=Cross(b-a,d-a);
		return Point(c.x*s2-d.x*s1,c.y*s2-d.y*s1)/(s2-s1);
	}
	bool Cross_segment(Point a,Point b,Point c,Point d){
		double c1=Cross(b-a,c-a),c2=Cross(b-a,d-a);
		double d1=Cross(d-c,a-c),d2=Cross(d-c,b-c);
		return sgn(c1)*sgn(c2)<0&&sgn(d1)*sgn(d2)<0;//1:相交 0:不相交 
	}
	int Point_in_polygon(Point pt,Point*p,int n){
		for(int i=0;i<n;i++)if(p[i]==pt)return 3;//3:点在多边形顶点上 
		for(int i=1;i<n;i++){
			Line v=Line(p[i],p[(i+1)%n]);
			if(Point_on_seg(pt,v))return 2;//3:点在多边形边上 
		}
		int num=0;
		for(int i=0;i<n;i++){
			int j=(i+1)%n;
			int c=sgn(Cross(pt-p[j],p[i]-p[j]));
			int u=sgn(p[i].y-pt.y),v=sgn(p[j].y-pt.y);
			if(c>0&&u<0&&v>=0)num++;
			if(c<0&&u>=0&&v<0)num--;
		}
		return num!=0;		//1:点在内部 0:点在外部 
	}
	double Polygon_area(Point*p,int n){
		double area=0;
		for(int i=0;i<n;i++)
			area+=Cross(p[i],p[(i+1)%n]);
		return area/2;
	}
	int Convex_hull(Point*p,int n,Point*ch){
		n=unique(p,p+n)-p;
		sort(p,p+n,[](Point a,Point b){
			return sgn(a.x-b.x)<0||sgn(a.x-b.x)==0&&sgn(a.y-b.y)<0;
		});
		int v=0;
		for(int i=0;i<n;i++){
			while(v>1&&sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-1]))<=0)v--;
			ch[v++]=p[i];
		}
		int j=v;
		for(int i=n-2;i>=0;i--){
			while(v>j&&sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-1]))<=0)v--;
			ch[v++]=p[i];
		}
		if(n>1)v--;return v;
	}
	//...
}
namespace Template{//Studying
	//...
}
namespace MTL{//My Template Library
	using namespace Template;
	template<class T>class Array{
//		private:
			int n;
			T*num;
		public:
			static const int maxn=1e5;
			Array(){num=new T[maxn];}
			Array(int n):n(n){num=new T[n];}
			int getlen(){return n;}
			T*begin(){return num;}
			T*end(){return num+n;}
			void setlen(int _){n=_;delete[]num;num=new T[n];}
			T&operator[](int i){return num[i];}
			~Array(){delete[]num;}
			bool operator==(Array a){
				if(a.n!=this->n)return 0;
				for(int i=0;i<this->n;i++){
					if(this->num[i]!=a.num[i])return 0;
				}
				return 1;
			}
			bool operator!=(Array a){
				if(a.n!=this->n)return 1;
				for(int i=0;i<this->n;i++){
					if(this->num[i]!=a.num[i])return 1;
				}
				return 0;
			}
			template<typename Cmp>
			void sort(Cmp cmp){
				sort(this->begin(),this->end(),cmp);
			}
			T*find(T x){
				for(T*i=num;i<num+n;i++){
					if(*i==x)return i;
				}
				return this->end();
			}
			Array operator+(Array a){
				Array b(n+a.n);
				for(int i=0;i<n;i++)b[i]=num[i];
				for(int i=0;i<a.n;i++)b[i+n]=a.num[i];
				return b;
			}
			//...
	};
	template<class T>
	Array<T>operator+=(Array<T>&a,Array<T>b){
		a=a+b;return a;
	}
}
//...
namespace Lit{
	#define pt st.top();st.pop()
	map<string,int>mp,lab;
	struct arr{
		string name;
		int len,a[1005];
	}ar[1005],ppq;
	int mad;
	int num(string u){
		stack<int>st;string t;
		for(int i=0;i<u.size();i++){
			if(u[i]!=' ')t+=u[i];
			if(u[i]==' '||i==u.size()-1){
				if(t=="+"){int x=pt;int y=pt;st.push(x+y);}
				else if(t=="-"){int x=pt;int y=pt;st.push(y-x);}
				else if(t=="*"){int x=pt;int y=pt;st.push(x*y);}
				else if(t=="/"){int x=pt;int y=pt;st.push(y/x);}
				else if(t=="%"){int x=pt;int y=pt;st.push(y%x);}
				else if(t=="&"){int x=pt;int y=pt;st.push(y&x);}
				else if(t=="|"){int x=pt;int y=pt;st.push(y|x);}
				else if(t=="^"){int x=pt;int y=pt;st.push(y^x);}
				else if(t=="!"){int x=pt;st.push(!x);}
				else if(t=="~"){int x=pt;st.push(~x);}
				else if(t==">"){int x=pt;int y=pt;st.push(y>x);}
				else if(t=="<"){int x=pt;int y=pt;st.push(y<x);}
				else if(t==">="){int x=pt;int y=pt;st.push(y>=x);}
				else if(t=="<="){int x=pt;int y=pt;st.push(y<=x);}
				else if(t=="=="){int x=pt;int y=pt;st.push(y==x);}
				else if(t=="!="){int x=pt;int y=pt;st.push(y!=x);}
				else if(t=="&&"){int x=pt;int y=pt;st.push(y&&x);}
				else if(t=="||"){int x=pt;int y=pt;st.push(y||x);}
				else if(t[0]>='0'&&t[0]<='9')st.push(atoi(t.c_str()));
				else if(t.find('[')!=string::npos){
					int pos=t.find('['),jj;
					string q=t.substr(0,pos);
					jj=atoi(t.substr(pos+1).c_str());
					for(int i=1;i<=mad;i++){
						if(ar[i].name==q){
							st.push(ar[i].a[jj]);
							break;
						}
					}
				}
				else st.push(mp[t]);
				t="";
			}
		}
		return st.top();
	}
	int cnt,nu[10005],pos,p;
	string s[1005];
	void run(int x){
		for(int i=x;i<=cnt;i++){
			if(s[i].substr(0,3)=="def"){
				string t="";
				for(int j=4;j<s[i].size();j++){
					if(s[i][j]!=' ')t+=s[i][j];
					if(s[i][j]==' '||j==s[i].size()-1)mp[t]=0,t="";
				}
			}
			else if(s[i].substr(0,3)=="daf"){
				string t="";int j=4;
				for(;s[i][j]!=' ';j++)t+=s[i][j];
				int lp=num(s[i].substr(j+1));
				ppq.name=t,ppq.len=lp;ar[++mad]=ppq;
			}
			else if(s[i].substr(0,5)=="print"){
				if(s[i][5]==' ')cout<<num(s[i].substr(6));
				else if(s[i][5]=='\"')cout<<s[i].substr(6);
				else cout<<(char)num(s[i].substr(6));
			}
			else if(s[i].substr(0,4)=="scan"){
				if(s[i].find('[')==string::npos)
				mp[s[i].substr(5)]=nu[++p];
				else{
					string t=s[i].substr(5);
					int pos=t.find('['),jj;
					string q=t.substr(0,pos);
					jj=atoi(t.substr(pos+1).c_str());
					for(int k=1;k<=mad;k++){
						if(ar[k].name==q){
							ar[k].a[jj]=nu[++p];
							break;
						}
					}
				}
			}
			else if(s[i].substr(0,2)=="eq"){
				string t="";int j=3;
				for(;s[i][j]!=' ';j++)t+=s[i][j];
				if(t.find('[')!=string::npos){
					int pos=t.find('['),jj;
					string q=t.substr(0,pos);
					jj=atoi(t.substr(pos+1).c_str());
					for(int k=1;k<=mad;k++){
						if(ar[k].name==q){
							ar[k].a[jj]=num(s[i].substr(j+1));
							break;
						}
					}
				}
				else mp[t]=num(s[i].substr(j+1));
			}
			else if(s[i].substr(0,4)=="goto"){
				run(lab[s[i].substr(5)]+1);
				return;
			}
			else if(s[i].substr(0,2)=="if"){
				string t=s[i].substr(3);
				int ppp=num(t),j=i+1;
				for(;s[j]!="endf";j++);
				if(ppp)run(i+1);
				else run(j+1);
				return;
			}
		}
	}
	void _main(){
		puts("--------<Lit Programming Language>--------");
		puts("Thank you for using this Programming Language!");
		puts("It\'s a little Programming Language, It\'s name is Lit.");
		puts("--------------<CODE>-------------");
		for(int i=1;;i++){
			printf("%3d. | ",i);
			getline(cin,s[++cnt]);
			if(s[cnt]=="end"){
				cnt--;
				break;
			}
		}
		puts("--------------<INPUT>-------------");
		for(int i=1;i<=cnt;i++){
			if(s[i].substr(0,3)=="lab")lab[s[i].substr(4)]=i;
			if(s[i].substr(0,4)=="scan")cin>>nu[++pos];
		}
		puts("--------------<OUTPUT>--------------");
		run(1);
		puts("\n--------------<END>--------------");
	}
}
namespace Algorithm{
	using namespace Small_Func;
	using namespace Geometry;
	using namespace Lit;
	//...
}
namespace MyStd{
	using namespace MTL;
	using namespace fastIO;
	using namespace Algorithm;
	template<typename...>struct TypeList;
	template<typename Head,typename...Tails>
	struct TypeList<Head,Tails...>{
		using head=Head;
		using tails=TypeList<Tails...>;
	};
	template<>struct TypeList<>{};
	template<typename TList>struct Length;
	template<>
	struct Length<TypeList<>>{
		static constexpr int value=0;
	};
	template<typename Head,typename...Types>
	struct Length<TypeList<Head,Types...>>{
		static constexpr int value=Length<TypeList<Types...>>::value+1;
	};
	template<typename TList,unsigned int index>struct TypeAt;
	template<typename Head,typename...Args>
	struct TypeAt<TypeList<Head,Args...>,0>{
		using type=Head;
	};
	template<typename Head,typename...Args,unsigned int i>
	struct TypeAt<TypeList<Head,Args...>,i>{
		static_assert(i<sizeof...(Args)+1,"i out of range");
		using type=typename TypeAt<TypeList<Args...>,i-1>::type;
	};
	template<typename TList,typename T>struct IndexOf;
	template<typename Head,typename...Tails,typename T>
	struct IndexOf<TypeList<Head,Tails...>,T>{
		private:
			using Result=IndexOf<TypeList<Tails...>,T>;
		public:
			static constexpr int value=is_same<Head,T>::value?0:
				(Result::value==-1?-1:Result::value+1);
	};
	template<typename T>
	struct IndexOf<TypeList<>,T>{
		static constexpr int value=-1;
	};
	template<typename,typename>struct Append;
	template<typename...TList,typename T>
	struct Append<TypeList<TList...>,T>{
		using type=TypeList<TList...,T>;
	};
	template<typename T,typename...TList>
	struct Append<T,TypeList<TList...>>{
		using type=TypeList<T,TList...>;
	};
	template<typename...TListLeft,typename...TListRight>
	struct Append<TypeList<TListLeft...>,TypeList<TListRight...>>{
		using type=TypeList<TListLeft...,TListRight...>;
	};
	template<typename TList,typename T>struct Erase;
	template<typename Head,typename...Tails,typename T>
	struct Erase<TypeList<Head,Tails...>,T>{
		using type=typename Append<Head,typename Erase<TypeList<Tails...>,T>::type>::type;
	};
	template<typename...Tails,typename T>
	struct Erase<TypeList<T,Tails...>,T>{
		using type=TypeList<Tails...>;
	};
	template<typename T>
	struct Erase<TypeList<>,T>{
		using type=TypeList<>;
	};
	template<typename TList,typename T>struct EraseAll;
	template<typename Head,typename...Tails,typename T>
	struct EraseAll<TypeList<Head,Tails...>,T>{
		using type=typename Append<Head,typename EraseAll<TypeList<Tails...>,T>::type>::type;
	};
	template<typename...Tails,typename T>
	struct EraseAll<TypeList<T,Tails...>,T>{
		using type=typename EraseAll<TypeList<Tails...>,T>::type;
	};
	template<typename T>
	struct EraseAll<TypeList<>,T>{
		using type=TypeList<>;
	};
	template<typename TList>struct NoDuplicates;
	template<>
	struct NoDuplicates<TypeList<>>{
		using type=TypeList<>;
	};
	template<typename Head,typename...Tails>
	struct NoDuplicates<TypeList<Head, Tails...>>{
		private:
			using L1=typename NoDuplicates<TypeList<Tails...>>::type;
			using L2=typename Erase<L1,Head>::type;
		public:
			using type=typename Append<Head,L2>::type;
	};
	template<typename TList,typename Old,typename New>struct Replace;
	template<typename T,typename U>
	struct Replace<TypeList<>,T,U>{
		using type=TypeList<>;
	};
	template<typename...Tails,typename T,typename U>
	struct Replace<TypeList<T,Tails...>,T,U>{
		using type=typename Append<U,TypeList<Tails...>>::type;
	};
	template<typename Head,typename...Tails,typename T,typename U>
	struct Replace<TypeList<Head,Tails...>,T,U>{
		using type=typename Append<Head,typename Replace<TypeList<Tails...>,T,U>::type>::type;
	};
	//The end of TypeList
	template<class T,class...U>
	class Tuple{
		T a;Tuple<U...>b;
	public:
		template<class P>
		P&get(){
			if(is_same<P,T>::value)return(P&)a;
			return b.get<P>();
		}
		template<int i>
		typename TypeAt<TypeList<T,U...>,i>::type&get(){
			if(i)return(typename TypeAt<TypeList<T,U...>,i>::type&)b.get<i-1>();
			return a;
		}
	};
	template<class T>
	class Tuple<T>{
		T a;
	public:
		template<class P>P&get(){return(P&)a;}
		template<int i>T&get(){return a;}
	};
	//The end of Tuple
}
#ifndef DEF_STD
using namespace MyStd;
#endif
signed __cdecl main(
	int argc,
	const char**argv,
	const char**envp){
	//some code:
#ifndef LITLANG
	_main();
#endif
	return system("pause");
}