#ifndef Wh_XcjmHeader_H
#define Wh_XcjmHeader_H
//#define Memory_Unlimited_Mode_On true
//#define Init_Factorial_List_On true
//#define Init_Prime_List_On true
//#define WindowsUI_Mode_On true
//#define Urgent_Mode_On true
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
typedef long long ll;
typedef unsigned long long ull;
#ifdef Memory_Unlimited_Mode_On
//Caution: You should use "signed main(){}" with this mode on
typedef long long int;
#endif
#ifndef mo
#define mo 1000000007
#endif
#if defined(Urgent_Mode_On)&&Urgent_Mode_On
#define qr fastIO::read()
#define gc fastIO::nc()
#define pc(a) fastIO::Ostream.out(a)
#define ps pc(' ')
#define pe pc('
')
#define pt(a) fastIO::print(a)
#define pd(a) fastIO::print(a)
#else
#define qr read()
#define gc getchar()
#define pc(a) putchar(a)
#define ps putchar(' ')
#define pe putchar('
')
#define pt(a) print(a)
#define pd(a) printf("%lf",a)
#endif
#ifdef _STL_PAIR_H
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
#define mk(a,b) std::make_pair(a,b)
#endif
#if defined(WindowsUI_Mode_On)&&WindowsUI_Mode_On
#include<windows.h>
#define sys(opt) system(opt)
void gotoxy(int x,int y){
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void SetConsoleCursor(bool opt=false){
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = opt; //隐藏控制台光标
SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}
#endif
#ifndef C
#define C(b,a) mymath::Combination(mymath::min((a),(b)-(a)),(b))//choose a elements from b equivalent elements
#endif
#ifndef P
#define P(b,a) mymath::Permutation((a),(b))//choose a elements from b inequivalent elements
#endif
#if defined(Init_Factorial_List_On)&&Init_Factorial_List_On
#ifndef Factorial_List_Limit
#define Factorial_List_Limit 1000005
#endif
ll Factorial_List[Factorial_List_Limit];
ll Inv_Factorial_List[Factorial_List_Limit];
bool Has_Calculated_the_Factorial_List=false;
void Init_Factorial_List();
#endif
namespace mymath{//一些方便的数学运算
inline void Add(ll &a,ll b){
a=a+b;a%=mo;
}
inline ll add(ll a,ll b){
a=a+b;a%=mo;
return a;
}
inline void Add(ll &a,ll b,ll p){
a=a+b;a%=p;
}
inline ll add(ll a,ll b,ll p){
a=a+b;a%=p;
return a;
}
template<typename _Tp>_Tp abs(_Tp x){
return x<0?-x:x;
}
inline void Abs(double &x){x<0?x=-x:0;}
inline void Abs(ll &x){x<0?x=-x:0;}
inline void Mul(ll &a,ll b,ll p){
if(p<=3e9)
a=a*b,a%=p;
else{
#if defined(Urgent_Mode_On)&&Urgent_Mode_On
a=(a*b-(ll)((long double)a/p*b+1.0e-8)*p+p)%p;
#else
ll ret=0,k=a;
while(b){
if(b&1)Add(ret,k,p);
b>>=1;
Add(k,k,p);
}
a=ret;
#endif
}
}
inline void Mul(ll &a,ll b){
Mul(a,b,mo);
}
inline ll mul(ll a,ll b,ll p){
if(p<=3e9)
a=a*b,a%=p;
else{
#if defined(Urgent_Mode_On)&&Urgent_Mode_On
a=(a*b-(ll)((long double)a/p*b+1.0e-8)*p+p)%p;
#else
ll ret=0,k=a;
while(b){
if(b&1)Add(ret,k,p);
b>>=1;
Add(k,k,p);
}
a=ret;
#endif
}
return a;
}
inline ll mul(ll a,ll b){
return mul(a,b,mo);
}
inline void Min(ll &a,ll b){
a=a<b?a:b;
}
inline void Max(ll &a,ll b){
a=a>b?a:b;
}
template<typename _Tp> inline _Tp min(_Tp a1,_Tp a2){
return a1<a2?a1:a2;
}
inline ll min(ll a1,ll a2){return a1<a2?a1:a2;}
inline double min(double a1,double a2){return a1<a2?a1:a2;}
inline ll min(ll a1,ll a2,ll a3){
return min(a1,min(a2,a3));
}
inline ll min(ll a1,ll a2,ll a3,ll a4){
return min(a1,min(a2,a3,a4));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5){
return min(a1,min(a2,a3,a4,a5));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6){
return min(a1,min(a2,a3,a4,a5,a6));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7){
return min(a1,min(a2,a3,a4,a5,a6,a7));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8){
return min(a1,min(a2,a3,a4,a5,a6,a7,a8));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8,ll a9){
return min(a1,min(a2,a3,a4,a5,a6,a7,a8,a9));
}
inline ll min(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8,ll a9,ll a10){
return min(a1,min(a2,a3,a4,a5,a6,a7,a8,a9,a10));
}
inline ll max(ll a1,ll a2){return a1>a2?a1:a2;}
inline double max(double a1,double a2){return a1>a2?a1:a2;}
inline ll max(ll a1,ll a2,ll a3){
return max(a1,max(a2,a3));
}
inline ll max(ll a1,ll a2,ll a3,ll a4){
return max(a1,max(a2,a3,a4));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5){
return max(a1,max(a2,a3,a4,a5));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6){
return max(a1,max(a2,a3,a4,a5,a6));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7){
return max(a1,max(a2,a3,a4,a5,a6,a7));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8){
return max(a1,max(a2,a3,a4,a5,a6,a7,a8));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8,ll a9){
return max(a1,max(a2,a3,a4,a5,a6,a7,a8,a9));
}
inline ll max(ll a1,ll a2,ll a3,ll a4,ll a5,ll a6,ll a7,ll a8,ll a9,ll a10){
return max(a1,max(a2,a3,a4,a5,a6,a7,a8,a9,a10));
}
ll ksm(ll a,ll k){
ll ret=1;
while(k){
if(k&1)Mul(ret,a);
Mul(a,a);
k>>=1;
}
return ret;
}
ll ksm(ll a,ll k,ll p){
ll ret=1;
while(k){
if(k&1)Mul(ret,a,p);
Mul(a,a,p);
k>>=1;
}
return ret;
}
ll CalcInv(ll x){return ksm(x,mo-2);}
ll Combination(ll a,ll b){//组合 b选a
if(a>b||a<0||b<0)return -1;
ll ret=1;
#if defined(Init_Factorial_List_On)&&Init_Factorial_List_On
if(!Has_Calculated_the_Factorial_List)Init_Factorial_List();
Mul(ret,Factorial_List[b]);
Mul(ret,Inv_Factorial_List[b-a]);
Mul(ret,Inv_Factorial_List[a]);
return ret;
#endif
for(ll k=b;b-k<a;k--){
mymath::Mul(ret,k);
}
for(int i=2;i<=a;i++)
mymath::Mul(ret,CalcInv(i));
return ret;
}
ll Permutation(ll a,ll b){//排列 b选a
if(a>b||a<0||b<0)return -1;
ll ret=1;
#if defined(Init_Factorial_List_On)&&Init_Factorial_List_On
if(~Has_Calculated_the_Factorial_List)Init_Factorial_List();
Mul(ret,Factorial_List[b]);
Mul(ret,CalcInv(Factorial_List[b-a]));
return ret;
#endif
for(ll k=b;b-k<a;k--){
mymath::Mul(ret,k);
}
return ret;
}
}
#if !(defined(Urgent_Mode_On)&&Urgent_Mode_On)
inline ll read(){
ull x = 0;
char y = 0,c = gc;
while(c<'0'||c>'9')y=c,c=gc;
while(c>='0'&&c<='9')x=x*10-48+c,c=gc;
return y=='-'?0ll-x:(ll)x;
}
inline void print(ll x){
ull y;
if(x<0)pc('-'),y=0ull-x;else y=x;
if(y>=10)print(y/10);
pc(y%10+48);
}
/*
inline void print(int x){
ull y;
if(x<0)pc('-'),y=0ull-x;else y=x;
if(y>=10)print(y/10);
pc(y%10+48);
}
inline void print(ull x){
ull y;
if(x<0)pc('-'),y=0ull-x;else y=x;
if(y>=10)print(y/10);
pc(y%10+48);
}*/
#endif
#ifndef Prime_Check_List_Cnt
#define Prime_Check_List_Cnt 12
ll Miller_Rabin_Check_List[]={2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
#endif
bool Miller_Rabin_Check_Prime(ll x){
if(x<2)return false;
if(x==2)return true;
if(x&1==0)return false;
for(int i=0;i<Prime_Check_List_Cnt&&Miller_Rabin_Check_List[i]<x;i++){
ll k=x-1ll<<1;
while((k&1)==0){
k>>=1;
ll re=mymath::ksm(Miller_Rabin_Check_List[i],k,x);
if(re==x-1)break;
if(re==1)continue;
return false;
}
}
return true;
}
#endif
#if defined(Init_Prime_List_On)&&Init_Prime_List_On
#define Init_Prime_List_On true
#ifndef Prime_List_Limit
#define Prime_List_Limit 1000005
#endif
int Prime_List[Prime_List_Limit],Cnt_Prime_List;
bool is_Prime[Prime_List_Limit];
void Init_Prime_List(){
int N=Prime_List_Limit-4,&cnt=Cnt_Prime_List=0;
for(int i=2;i<Prime_List_Limit;i++)is_Prime[i]=true;
for(int i=2;i<N;i++){
if(is_Prime[i])Prime_List[cnt++]=i;
for(int j=0;j<cnt&&i*Prime_List[j]<N;j++){
is_Prime[i*Prime_List[j]]=false;
if(i%Prime_List[j]==0)break;
}
}
}
#endif
#if defined(Init_Factorial_List_On)&&Init_Factorial_List_On
void Init_Factorial_List(){
Has_Calculated_the_Factorial_List=true;
Factorial_List[0]=Factorial_List[1]=1;
for(ll i=2;i<Factorial_List_Limit;i++)
Factorial_List[i]=mymath::mul(Factorial_List[i-1],i);
Inv_Factorial_List[Factorial_List_Limit-1]=mymath::ksm(Factorial_List[Factorial_List_Limit-1],mo-2);
for(ll i=Factorial_List_Limit-2;i>=0;i--)
Inv_Factorial_List[i]=mymath::mul(Inv_Factorial_List[i+1],i+1);
}
#endif
//转的,有空研读下↓
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->read
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if (p1==pend){
p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
if (pend==p1){IOerror=1;return -1;}
//{printf("IO error!
");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='
'||ch=='
'||ch==' ';}
inline void read(int &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline ll read(){
ll x=0; bool sign=0; char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return -1;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
return x;
}
inline void read(ll &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=nc();blank(c);c=nc());
if (IOerror){c=-1;return;}
}
//getchar->read
inline void read1(int &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(ll &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(double &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (ch=='.'){
double tmp=1;
for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
}
if (bo)x=-x;
}
inline void read1(char *s){
char ch=getchar();
for (;blank(ch);ch=getchar());
for (;!blank(ch);ch=getchar())*s++=ch;
*s=0;
}
inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
//scanf->read
inline void read2(int &x){scanf("%d",&x);}
inline void read2(ll &x){
#ifdef _WIN32
scanf("%I64d",&x);
#else
#ifdef __linux
scanf("%lld",&x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void read2(double &x){scanf("%lf",&x);}
inline void read2(char *s){scanf("%s",s);}
inline void read2(char &c){scanf(" %c",&c);}
inline void readln2(char *s){gets(s);}
//fwrite->write
struct Ostream_fwrite{
char *buf,*p1,*pend;
Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
void out(char ch){
if (p1==pend){
fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
}
*p1++=ch;
}
void print(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('
');
}
void print(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('
');
}
void print(double x,int y){
static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
if (x<-1e-12)out('-'),x=-x;x*=mul[y];
ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
}
void println(double x,int y){print(x,y);out('
');}
void print(char *s){while (*s)out(*s++);}
void println(char *s){while (*s)out(*s++);out('
');}
void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
~Ostream_fwrite(){flush();}
}Ostream;
inline void print(int x){Ostream.print(x);}
inline void println(int x){Ostream.println(x);}
inline void print(char x){Ostream.out(x);}
inline void println(char x){Ostream.out(x);Ostream.out('
');}
inline void print(ll x){Ostream.print(x);}
inline void println(ll x){Ostream.println(x);}
inline void print(double x,int y){Ostream.print(x,y);}
inline void println(double x,int y){Ostream.println(x,y);}
inline void print(char *s){Ostream.print(s);}
inline void println(char *s){Ostream.println(s);}
inline void println(){Ostream.out('
');}
inline void flush(){Ostream.flush();}
//puts->write
char Out[OUT_SIZE],*o=Out;
inline void print1(int x){
static char buf[15];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(int x){print1(x);*o++='
';}
inline void print1(ll x){
static char buf[25];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(ll x){print1(x);*o++='
';}
inline void print1(char c){*o++=c;}
inline void println1(char c){*o++=c;*o++='
';}
inline void print1(char *s){while (*s)*o++=*s++;}
inline void println1(char *s){print1(s);*o++='
';}
inline void println1(){*o++='
';}
inline void flush1(){if (o!=Out){if (*(o-1)=='
')*--o=0;puts(Out);}}
struct puts_write{
~puts_write(){flush1();}
}_puts;
inline void print2(int x){printf("%d",x);}
inline void println2(int x){printf("%d
",x);}
inline void print2(char x){printf("%c",x);}
inline void println2(char x){printf("%c
",x);}
inline void print2(ll x){
#ifdef _WIN32
printf("%I64d",x);
#else
#ifdef __linux
printf("%lld",x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void println2(ll x){print2(x);printf("
");}
inline void println2(){printf("
");}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
namespace FileIO{
void fileio(char s[]){
char Input[500],Output[500];
sprintf(Input,"%s.in",s);
sprintf(Output,"%s.out",s);
freopen(Input,"r",stdin);
freopen(Output,"w",stdout);
}
#ifdef FileName
void fileio(){
char s[]=FileName;
char Input[500],Output[500];
sprintf(Input,"%s.in",s);
sprintf(Output,"%s.out",s);
freopen(Input,"r",stdin);
freopen(Output,"w",stdout);
}
#endif
}
#if defined N
#ifndef M
#define M N*2
#endif
struct A_List{
int top[N],nxt[M],to[M],cnt;
#if defined(Memory_Unlimited_Mode_On)&&Memory_Unlimited_Mode_On
ll val[M];
#else
int val[M];
#endif
void add2(int x,int y,int v=1){
nxt[++cnt]=top[x];top[x]=cnt;to[cnt]=y;val[cnt]=v;
nxt[++cnt]=top[y];top[y]=cnt;to[cnt]=x;val[cnt]=v;
}
void add1(int x,int y,int v=1){
nxt[++cnt]=top[x];top[x]=cnt;to[cnt]=y;val[cnt]=v;
}
#ifdef _STL_PAIR_H
void add2(pii a,int v=1){
add2(a.first,a.second,v);
}
#endif
};
struct A_List_No_Edge_Weight{
int top[N],nxt[M],to[M],cnt;
void add2(int x,int y){
nxt[++cnt]=top[x];top[x]=cnt;to[cnt]=y;
nxt[++cnt]=top[y];top[y]=cnt;to[cnt]=x;
}
void add1(int x,int y){
nxt[++cnt]=top[x];top[x]=cnt;to[cnt]=y;
}
#ifdef _STL_PAIR_H
void add2(pii a){
add2(a.first,a.second);
}
#endif
};
#endif