#include<bits/stdc++.h> using namespace std; #define REP(i,a,b) for(i=a;i<b;i++) #define rep(i,n) REP(i,0,n) #define mygc(c) (c)=getchar_unlocked() #define mypc(c) putchar_unlocked(c) #define ll long long #define ull unsigned ll void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);} void reader(ll *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);} void reader(double *x){scanf("%lf",x);} int reader(char c[]){int i,s=0;for(;;){mygc(i);if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF) break;}c[s++]=i;for(;;){mygc(i);if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF) break;c[s++]=i;}c[s]='\0';return s;} template <class T, class S> void reader(T *x, S *y){reader(x);reader(y);} template <class T, class S, class U> void reader(T *x, S *y, U *z){reader(x);reader(y);reader(z);} template <class T, class S, class U, class V> void reader(T *x, S *y, U *z, V *w){reader(x);reader(y);reader(z);reader(w);} void writer(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);} void writer(ll x, char c){int s=0,m=0;char f[20];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);} void writer(double x, char c){printf("%.15f",x);mypc(c);} void writer(const char c[]){int i;for(i=0;c[i]!='\0';i++)mypc(c[i]);} void writer(const char x[], char c){int i;for(i=0;x[i]!='\0';i++)mypc(x[i]);mypc(c);} template<class T> void writerLn(T x){writer(x,'\n');} template<class T, class S> void writerLn(T x, S y){writer(x,' ');writer(y,'\n');} template<class T, class S, class U> void writerLn(T x, S y, U z){writer(x,' ');writer(y,' ');writer(z,'\n');} template<class T> void writerArr(T x[], int n){int i;if(!n){mypc('\n');return;}rep(i,n-1)writer(x[i],' ');writer(x[n-1],'\n');} char memarr[17000000]; void *mem = memarr; #define MD 1000000007 int user_code = 1; set<string> g_flags; struct insertfunctions{ vector<string> name; std::set<string> doit, already; map<string,string> func, place, parent; map<string,vector<string> > need; map<string,vector<string> > del; void set(){ { string n = "optimize"; string c = "#pragma GCC optimize (\"Ofast\")\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "stdc"; string c = "#include<bits/stdc++.h>\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sys_time"; string c = "#include<sys/time.h>\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "namespace"; string c = "using namespace std;\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "define_MD"; string c = "#define MD (1000000007U)\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "define_for_Mint"; string c = "#define MINT_W (32U)\n#define MINT_R (294967268U)\n#define MINT_RR (582344008U)\n#define MINT_MDNINV (2226617417U)\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "define_PI"; string c = "#define PI 3.14159265358979323846\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "workmemory"; string c = "inplace_L void *wmem; char memarr[96000000];"; string p = "first"; vector<string> d; d.push_back((string)"workmemory_init"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "workmemory_init"; string c = "wmem = memarr;"; string p = "main_first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "min_L"; string c = "template<class S, class T> inline S min_L(S a,T b){return a<=b?a:b;}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "max_L"; string c = "template<class S, class T> inline S max_L(S a,T b){return a>=b?a:b;}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "walloc1d"; string c = "template<class T>\ninline void walloc1d(T **arr, int x, void **mem = &wmem){\n static int skip[16] = {0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};\n (*mem) = (void*)( ((char*)(*mem)) + skip[((ull)(*mem)) & 15] );\n (*arr)=(T*)(*mem);\n (*mem)=((*arr)+x);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "walloc2d"; string c = "template<class T>\ninline void walloc2d(T ***arr, int x, int y, void **mem = &wmem){\n int i;\n walloc1d(arr, x, mem);\n rep(i,x) walloc1d(&((*arr)[i]), y, mem);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "malloc1d"; string c = "template<class T>\nvoid malloc1d(T **arr, int x){\n (*arr) = (T*)malloc(x*sizeof(T));\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "free1d"; string c = "template<class T>\nvoid free1d(T *arr){\n free(arr);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "malloc2d"; string c = "template<class T>\nvoid malloc2d(T ***arr, int x, int y){\n int i;\n (*arr) = (T**)malloc(x*sizeof(T*));\n (*arr)[0] = (T*)malloc(x*y*sizeof(T));\n REP(i,1,x)(*arr)[i]=(*arr)[i-1]+y;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "free2d"; string c = "template<class T>\nvoid free2d(T **arr){\n free(arr[0]);\n free(arr);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortA_1"; string c = "template<class T1>\nvoid sortA_L(int N, T1 a[], void *mem = wmem){\n sort(a, a+N);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortA_2"; string c = "template<class T1, class T2>\nvoid sortA_L(int N, T1 a[], T2 b[], void *mem = wmem){\n int i;\n pair<T1, T2> *arr;\n walloc1d(&arr, N, &mem);\n rep(i,N) arr[i].first = a[i], arr[i].second = b[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first, b[i] = arr[i].second;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortA_3"; string c = "template<class T1, class T2, class T3>\nvoid sortA_L(int N, T1 a[], T2 b[], T3 c[], void *mem = wmem){\n int i;\n pair<T1, pair<T2, T3> > *arr;\n walloc1d(&arr, N, &mem);\n rep(i,N) arr[i].first = a[i], arr[i].second.first = b[i], arr[i].second.second = c[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first, b[i] = arr[i].second.first, c[i] = arr[i].second.second;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortA_4"; string c = "template<class T1, class T2, class T3, class T4>\nvoid sortA_L(int N, T1 a[], T2 b[], T3 c[], T4 d[], void *mem = wmem){\n int i;\n pair<pair<T1, T2>, pair<T3, T4> > *arr;\n walloc1d(&arr, N, &mem);\n rep(i,N) arr[i].first.first = a[i], arr[i].first.second = b[i], arr[i].second.first = c[i], arr[i].second.second = d[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first.first, b[i] = arr[i].first.second, c[i] = arr[i].second.first, d[i] = arr[i].second.second;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "rsortA_1"; string c = "template<class T1>\nvoid rsortA_L(int N, T1 a[], void *mem = wmem){\n sortA(N, a, mem);\n reverse(a, a+N);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"sortA_1"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "rsortA_2"; string c = "template<class T1, class T2>\nvoid rsortA_L(int N, T1 a[], T2 b[], void *mem = wmem){\n sortA(N, a, b, mem);\n reverse(a, a+N);\n reverse(b, b+N);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"sortA_2"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "rsortA_3"; string c = "template<class T1, class T2, class T3>\nvoid rsortA_L(int N, T1 a[], T2 b[], T3 c[], void *mem = wmem){\n sortA(N, a, b, c, mem);\n reverse(a, a+N);\n reverse(b, b+N);\n reverse(c, c+N);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"sortA_3"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "rsortA_4"; string c = "template<class T1, class T2, class T3, class T4>\nvoid rsortA_L(int N, T1 a[], T2 b[], T3 c[], T4 d[], void *mem = wmem){\n sortA(N, a, b, c, d, mem);\n reverse(a, a+N);\n reverse(b, b+N);\n reverse(c, c+N);\n reverse(d, d+N);\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"sortA_4"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortF_unsigned"; string c = "void sortF_L(int N, unsigned A[], void *mem = wmem){\n int i, m, bt;\n unsigned *arr, c;\n int *sz;\n\n if(N < 256){\n sort(A, A+N);\n return;\n }\n\n bt = sizeof(unsigned) * 8;\n walloc1d(&arr, N, &mem);\n walloc1d(&sz, N, &mem);\n\n for(m=0;m<bt;m+=8){\n rep(i,257) sz[i] = 0;\n rep(i,N) sz[ 1+((A[i]>>m)&255u) ]++;\n rep(i,1,257) sz[i] += sz[i-1];\n rep(i,N){\n c = ((A[i]>>m)&255u);\n arr[sz[c]++] = A[i];\n }\n swap(A, arr);\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortF_int"; string c = "void sortF_L(int N, int A[], void *mem = wmem){\n int i, x, y, z;\n int *arr;\n unsigned *send;\n\n if(N < 256){\n sort(A, A+N);\n return;\n }\n\n send = (unsigned*)A;\n sortF_L(N, send, mem);\n if(A[0] < 0 || A[N-1] >= 0) return;\n \n x = 0;\n y = N;\n while(x < y){\n z = (x+y) / 2;\n if(A[z] < 0) y = z; else x = z+1;\n }\n\n walloc1d(&arr, N, &mem);\n z = 0;\n rep(i,x,N) arr[z++] = A[i];\n rep(i,x) arr[z++] = A[i];\n rep(i,N) A[i] = arr[i];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"sortF_unsigned"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortF_ull"; string c = "void sortF_L(int N, ull A[], void *mem = wmem){\n int i, m, bt;\n ull *arr;\n unsigned c;\n int *sz;\n\n if(N < 512){\n sort(A, A+N);\n return;\n }\n\n bt = sizeof(ull) * 8;\n \n walloc1d(&arr, N, &mem);\n walloc1d(&sz, N, &mem);\n\n for(m=0;m<bt;m+=8){\n rep(i,257) sz[i] = 0;\n rep(i,N) sz[ 1+((A[i]>>m)&255u) ]++;\n rep(i,1,257) sz[i] += sz[i-1];\n rep(i,N){\n c = ((A[i]>>m)&255u);\n arr[sz[c]++] = A[i];\n }\n swap(A, arr);\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "sortF_ll"; string c = "void sortF_L(int N, ll A[], void *mem = wmem){\n int i, x, y, z;\n ll *arr;\n ull *send;\n\n if(N < 512){\n sort(A, A+N);\n return;\n }\n\n send = (ull*)A;\n sortF_L(N, send, mem);\n if(A[0] < 0 || A[N-1] >= 0) return;\n \n x = 0;\n y = N;\n while(x < y){\n z = (x+y) / 2;\n if(A[z] < 0) y = z; else x = z+1;\n }\n\n walloc1d(&arr, N, &mem);\n z = 0;\n rep(i,x,N) arr[z++] = A[i];\n rep(i,x) arr[z++] = A[i];\n rep(i,N) A[i] = arr[i];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"sortF_ull"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Timer"; string c = "struct Timer{\n double x;\n double gettimeofday_sec(void){\n timeval t;\n gettimeofday(&t, 0);\n return t.tv_sec + t.tv_usec * 1e-6;\n }\n void set(void){\n x = gettimeofday_sec();\n }\n double get(void){\n return gettimeofday_sec() - x;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"sys_time"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Rand"; string c = "struct Rand{\n unsigned x,y,z,w;\n\n Rand(void){\n x=123456789, y=362436069, z=521288629, w=(unsigned)time(NULL);\n }\n Rand(unsigned seed){\n x=123456789, y=362436069, z=521288629, w=seed;\n }\n inline unsigned get(void){\n unsigned t;\n t = (x^(x<<11));\n x=y; y=z; z=w;\n w = (w^(w>>19))^(t^(t>>8));\n return w;\n }\n inline double getUni(void){\n return get()/4294967296.0;\n }\n inline int get(int a){\n return (int)(a*getUni());\n }\n inline int get(int a, int b){\n return a+(int)((b-a+1)*getUni());\n }\n inline ll get(ll a){\n return(ll)(a*getUni());\n }\n inline ll get(ll a, ll b){\n return a+(ll)((b-a+1)*getUni());\n }\n inline double get(double a, double b){\n return a+(b-a)*getUni();\n }\n inline int getExp(int a){\n return(int)(exp(getUni()*log(a+1.0))-1.0);\n }\n inline int getExp(int a, int b){\n return a+(int)(exp(getUni()*log((b-a+1)+1.0))-1.0);\n }\n};\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Modint"; string c = "struct Modint{\n unsigned val;\n\n Modint(){}\n Modint(int a){val = ord(a);}\n Modint(unsigned a){val = ord(a);}\n Modint(ll a){val = ord(a);}\n Modint(ull a){val = ord(a);}\n\n inline unsigned ord(unsigned a){\n return a%MD;\n }\n\n inline unsigned ord(int a){\n a %= MD;\n if(a < 0) a += MD;\n return a;\n }\n\n inline unsigned ord(ull a){\n return a%MD;\n }\n\n inline unsigned ord(ll a){\n a %= MD;\n if(a < 0) a += MD;\n return a;\n }\n\n inline unsigned get(){\n return val;\n }\n\n inline Modint &operator+=(Modint a){\n val += a.val;\n if(val >= MD) val -= MD;\n return *this;\n }\n inline Modint &operator-=(Modint a){\n if(val < a.val) val = val + MD - a.val;\n else val -= a.val;\n return *this;\n }\n inline Modint &operator*=(Modint a){\n val = ((ull)val*a.val)%MD;\n return *this;\n }\n inline Modint &operator/=(Modint a){\n return *this *= a.inverse();\n }\n\n inline Modint operator+(Modint a){ return Modint(*this)+=a; }\n inline Modint operator-(Modint a){ return Modint(*this)-=a; }\n inline Modint operator*(Modint a){ return Modint(*this)*=a; }\n inline Modint operator/(Modint a){ return Modint(*this)/=a; }\n\n inline Modint operator+(int a){ return Modint(*this)+=Modint(a); }\n inline Modint operator-(int a){ return Modint(*this)-=Modint(a); }\n inline Modint operator*(int a){ return Modint(*this)*=Modint(a); }\n inline Modint operator/(int a){ return Modint(*this)/=Modint(a); }\n inline Modint operator+(ll a){ return Modint(*this)+=Modint(a); }\n inline Modint operator-(ll a){ return Modint(*this)-=Modint(a); }\n inline Modint operator*(ll a){ return Modint(*this)*=Modint(a); }\n inline Modint operator/(ll a){ return Modint(*this)/=Modint(a); }\n\n inline Modint operator-(void){ Modint res; if(val) res.val=MD-val; else res.val=0; return res; }\n \n inline operator bool(void){\n return val!=0;\n }\n inline operator int(void){\n return get();\n }\n inline operator ll(void){\n return get();\n }\n\n inline Modint inverse(){\n int a = val, b = MD, u = 1, v = 0, t;\n Modint res;\n while(b){\n t = a / b;\n a -= t * b; swap(a, b);\n u -= t * v; swap(u, v);\n }\n if(u < 0) u += MD;\n res.val = u;\n return res;\n }\n\n inline Modint pw(ull b){\n Modint a(*this), res;\n res.val = 1;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n }\n\n inline bool operator==(int a){return ord(a)==val;}\n inline bool operator!=(int a){return ord(a)!=val;}\n};\ninline Modint operator+(int a, Modint b){return Modint(a)+=b;}\ninline Modint operator-(int a, Modint b){return Modint(a)-=b;}\ninline Modint operator*(int a, Modint b){return Modint(a)*=b;}\ninline Modint operator/(int a, Modint b){return Modint(a)/=b;}\ninline Modint operator+(ll a, Modint b){return Modint(a)+=b;}\ninline Modint operator-(ll a, Modint b){return Modint(a)-=b;}\ninline Modint operator*(ll a, Modint b){return Modint(a)*=b;}\ninline Modint operator/(ll a, Modint b){return Modint(a)/=b;}\n"; string p = "first"; vector<string> d; d.push_back((string)"define_MD"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "modint"; string c = "struct modint{\n static unsigned md;\n unsigned val;\n\n modint(){}\n modint(int a){val = ord(a);}\n modint(unsigned a){val = ord(a);}\n modint(ll a){val = ord(a);}\n modint(ull a){val = ord(a);}\n\n void setmod(unsigned m){\n md = m;\n }\n\n unsigned ord(unsigned a){\n return a%md;\n }\n\n unsigned ord(int a){\n a %= md;\n if(a < 0) a += md;\n return a;\n }\n\n unsigned ord(ull a){\n return a%md;\n }\n\n unsigned ord(ll a){\n a %= md;\n if(a < 0) a += md;\n return a;\n }\n\n unsigned get(){\n return val;\n }\n\n modint &operator+=(modint a){\n val += a.val;\n if(val >= md) val -= md;\n return *this;\n }\n modint &operator-=(modint a){\n if(val < a.val) val = val + md - a.val;\n else val -= a.val;\n return *this;\n }\n modint &operator*=(modint a){\n val = ((ull)val*a.val)%md;\n return *this;\n }\n modint &operator/=(modint a){\n return *this *= a.inverse();\n }\n\n modint operator+(modint a){ return modint(*this)+=a; }\n modint operator-(modint a){ return modint(*this)-=a; }\n modint operator*(modint a){ return modint(*this)*=a; }\n modint operator/(modint a){ return modint(*this)/=a; }\n\n modint operator+(int a){ return modint(*this)+=modint(a); }\n modint operator-(int a){ return modint(*this)-=modint(a); }\n modint operator*(int a){ return modint(*this)*=modint(a); }\n modint operator/(int a){ return modint(*this)/=modint(a); }\n modint operator+(ll a){ return modint(*this)+=modint(a); }\n modint operator-(ll a){ return modint(*this)-=modint(a); }\n modint operator*(ll a){ return modint(*this)*=modint(a); }\n modint operator/(ll a){ return modint(*this)/=modint(a); }\n\n modint operator-(void){ modint res; if(val) res.val=md-val; else res.val=0; return res; }\n \n operator bool(void){\n return val!=0;\n }\n operator int(void){\n return get();\n }\n operator ll(void){\n return get();\n }\n\n modint inverse(){\n int a = val, b = md, u = 1, v = 0, t;\n modint res;\n while(b){\n t = a / b;\n a -= t * b; swap(a, b);\n u -= t * v; swap(u, v);\n }\n if(u < 0) u += md;\n res.val = u;\n return res;\n }\n\n modint pw(ull b){\n modint a(*this), res;\n res.val = 1;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n }\n\n bool operator==(int a){return ord(a)==val;}\n bool operator!=(int a){return ord(a)!=val;}\n};\nunsigned modint::md;\nmodint operator+(int a, modint b){return modint(a)+=b;}\nmodint operator-(int a, modint b){return modint(a)-=b;}\nmodint operator*(int a, modint b){return modint(a)*=b;}\nmodint operator/(int a, modint b){return modint(a)/=b;}\nmodint operator+(ll a, modint b){return modint(a)+=b;}\nmodint operator-(ll a, modint b){return modint(a)-=b;}\nmodint operator*(ll a, modint b){return modint(a)*=b;}\nmodint operator/(ll a, modint b){return modint(a)/=b;}\n"; string p = "first"; vector<string> d; d.push_back((string)"modint_init"); d.push_back((string)"define_MD"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "modint_init"; string c = "{modint x; x.setmod(MD);}"; string p = "main_first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Mint"; string c = "struct Mint{\n unsigned val;\n\n Mint(){}\n Mint(int a){val = mulR(a);}\n Mint(unsigned a){val = mulR(a);}\n Mint(ll a){val = mulR(a);}\n Mint(ull a){val = mulR(a);}\n\n inline unsigned mulR(unsigned a){\n return (ull)a*MINT_R%MD;\n }\n\n inline unsigned mulR(int a){\n if(a < 0) a = a%((int)MD)+(int)MD;\n return mulR((unsigned)a);\n }\n\n inline unsigned mulR(ull a){\n return mulR((unsigned)(a%MD));\n }\n\n inline unsigned mulR(ll a){\n a %= MD;\n if(a < 0) a += MD;\n return mulR((unsigned)a);\n }\n\n inline unsigned reduce(unsigned T){\n unsigned m = T * MINT_MDNINV;\n unsigned t = (unsigned)((T + (ull)m*MD) >> MINT_W);\n if(t >= MD) t -= MD;\n return t;\n }\n\n inline unsigned reduce(ull T){\n unsigned m = (unsigned)T * MINT_MDNINV;\n unsigned t = (unsigned)((T + (ull)m*MD) >> MINT_W);\n if(t >= MD) t -= MD;\n return t;\n }\n\n inline unsigned get(){\n return reduce(val);\n }\n\n inline Mint &operator+=(Mint a){\n val += a.val;\n if(val >= MD) val -= MD;\n return *this;\n }\n inline Mint &operator-=(Mint a){\n if(val < a.val) val = val + MD - a.val;\n else val -= a.val;\n return *this;\n }\n inline Mint &operator*=(Mint a){\n val = reduce((ull)val*a.val);\n return *this;\n }\n inline Mint &operator/=(Mint a){\n return *this *= a.inverse();\n }\n\n inline Mint operator+(Mint a){ return Mint(*this)+=a; }\n inline Mint operator-(Mint a){ return Mint(*this)-=a; }\n inline Mint operator*(Mint a){ return Mint(*this)*=a; }\n inline Mint operator/(Mint a){ return Mint(*this)/=a; }\n\n inline Mint operator+(int a){ return Mint(*this)+=Mint(a); }\n inline Mint operator-(int a){ return Mint(*this)-=Mint(a); }\n inline Mint operator*(int a){ return Mint(*this)*=Mint(a); }\n inline Mint operator/(int a){ return Mint(*this)/=Mint(a); }\n inline Mint operator+(ll a){ return Mint(*this)+=Mint(a); }\n inline Mint operator-(ll a){ return Mint(*this)-=Mint(a); }\n inline Mint operator*(ll a){ return Mint(*this)*=Mint(a); }\n inline Mint operator/(ll a){ return Mint(*this)/=Mint(a); }\n\n inline Mint operator-(void){ Mint res; if(val) res.val=MD-val; else res.val=0; return res; }\n \n inline operator bool(void){\n return val!=0;\n }\n inline operator int(void){\n return get();\n }\n inline operator ll(void){\n return get();\n }\n\n inline Mint inverse(){\n int a = val, b = MD, u = 1, v = 0, t;\n Mint res;\n while(b){\n t = a / b;\n a -= t * b; swap(a, b);\n u -= t * v; swap(u, v);\n }\n if(u < 0) u += MD;\n res.val = (ull)u*MINT_RR % MD;\n return res;\n }\n\n inline Mint pw(ull b){\n Mint a(*this), res;\n res.val = MINT_R;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n }\n\n inline bool operator==(int a){return mulR(a)==val;}\n inline bool operator!=(int a){return mulR(a)!=val;}\n};\ninline Mint operator+(int a, Mint b){return Mint(a)+=b;}\ninline Mint operator-(int a, Mint b){return Mint(a)-=b;}\ninline Mint operator*(int a, Mint b){return Mint(a)*=b;}\ninline Mint operator/(int a, Mint b){return Mint(a)/=b;}\ninline Mint operator+(ll a, Mint b){return Mint(a)+=b;}\ninline Mint operator-(ll a, Mint b){return Mint(a)-=b;}\ninline Mint operator*(ll a, Mint b){return Mint(a)*=b;}\ninline Mint operator/(ll a, Mint b){return Mint(a)/=b;}\n"; string p = "first"; vector<string> d; d.push_back((string)"define_MD"); d.push_back((string)"define_for_Mint"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "mint"; string c = "struct mint{\n static unsigned md, W, R, Rinv, mdninv, RR;\n unsigned val;\n\n mint(){}\n mint(int a){val = mulR(a);}\n mint(unsigned a){val = mulR(a);}\n mint(ll a){val = mulR(a);}\n mint(ull a){val = mulR(a);}\n\n int get_inv(ll a, int md){ll t=a,s=md,u=1,v=0,e;while(s){e=t/s;t-=e*s;u-=e*v;swap(t,s);swap(u,v);}if(u<0)u+=md;return u;}\n\n void setmod(unsigned m){\n int i;\n unsigned t;\n W = 32;\n md = m;\n R = (1ULL << W) % md;\n RR = (ull)R*R % md;\n switch(m){\n case 104857601:\n Rinv = 2560000;\n mdninv = 104857599;\n break;\n case 998244353:\n Rinv = 232013824;\n mdninv = 998244351;\n break;\n case 1000000007:\n Rinv = 518424770;\n mdninv = 2226617417U;\n break;\n case 1000000009:\n Rinv = 171601999;\n mdninv = 737024967;\n break;\n case 1004535809:\n Rinv = 234947584;\n mdninv = 1004535807;\n break;\n case 1007681537:\n Rinv = 236421376;\n mdninv = 1007681535;\n break;\n case 1012924417:\n Rinv = 238887936;\n mdninv = 1012924415;\n break;\n case 1045430273:\n Rinv = 254466304;\n mdninv = 1045430271;\n break;\n case 1051721729:\n Rinv = 257538304;\n mdninv = 1051721727;\n break;\n default:\n Rinv = get_inv(R, md);\n mdninv = 0;\n t = 0;\n rep(i,(int)W){\n if(t%2==0) t+=md, mdninv |= (1U<<i);\n t /= 2;\n }\n }\n }\n\n unsigned mulR(unsigned a){\n return (ull)a*R%md;\n }\n\n unsigned mulR(int a){\n if(a < 0) a = a%((int)md)+(int)md;\n return mulR((unsigned)a);\n }\n\n unsigned mulR(ull a){\n return mulR((unsigned)(a%md));\n }\n\n unsigned mulR(ll a){\n a %= md;\n if(a < 0) a += md;\n return mulR((unsigned)a);\n }\n\n unsigned reduce(unsigned T){\n unsigned m = T * mdninv;\n unsigned t = (unsigned)((T + (ull)m*md) >> W);\n if(t >= md) t -= md;\n return t;\n }\n\n unsigned reduce(ull T){\n unsigned m = (unsigned)T * mdninv;\n unsigned t = (unsigned)((T + (ull)m*md) >> W);\n if(t >= md) t -= md;\n return t;\n }\n\n unsigned get(){\n return reduce(val);\n }\n\n mint &operator+=(mint a){\n val += a.val;\n if(val >= md) val -= md;\n return *this;\n }\n mint &operator-=(mint a){\n if(val < a.val) val = val + md - a.val;\n else val -= a.val;\n return *this;\n }\n mint &operator*=(mint a){\n val = reduce((ull)val*a.val);\n return *this;\n }\n mint &operator/=(mint a){\n return *this *= a.inverse();\n }\n\n mint operator+(mint a){ return mint(*this)+=a; }\n mint operator-(mint a){ return mint(*this)-=a; }\n mint operator*(mint a){ return mint(*this)*=a; }\n mint operator/(mint a){ return mint(*this)/=a; }\n\n mint operator+(int a){ return mint(*this)+=mint(a); }\n mint operator-(int a){ return mint(*this)-=mint(a); }\n mint operator*(int a){ return mint(*this)*=mint(a); }\n mint operator/(int a){ return mint(*this)/=mint(a); }\n mint operator+(ll a){ return mint(*this)+=mint(a); }\n mint operator-(ll a){ return mint(*this)-=mint(a); }\n mint operator*(ll a){ return mint(*this)*=mint(a); }\n mint operator/(ll a){ return mint(*this)/=mint(a); }\n\n mint operator-(void){ mint res; if(val) res.val=md-val; else res.val=0; return res; }\n \n operator bool(void){\n return val!=0;\n }\n operator int(void){\n return get();\n }\n operator ll(void){\n return get();\n }\n\n mint inverse(){\n int a = val, b = md, u = 1, v = 0, t;\n mint res;\n while(b){\n t = a / b;\n a -= t * b; swap(a, b);\n u -= t * v; swap(u, v);\n }\n if(u < 0) u += md;\n res.val = (ull)u*RR % md;\n return res;\n }\n\n mint pw(ull b){\n mint a(*this), res;\n res.val = R;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n }\n\n bool operator==(int a){return mulR(a)==val;}\n bool operator!=(int a){return mulR(a)!=val;}\n};\nunsigned mint::md, mint::W, mint::R, mint::Rinv, mint::mdninv, mint::RR;\nmint operator+(int a, mint b){return mint(a)+=b;}\nmint operator-(int a, mint b){return mint(a)-=b;}\nmint operator*(int a, mint b){return mint(a)*=b;}\nmint operator/(int a, mint b){return mint(a)/=b;}\nmint operator+(ll a, mint b){return mint(a)+=b;}\nmint operator-(ll a, mint b){return mint(a)-=b;}\nmint operator*(ll a, mint b){return mint(a)*=b;}\nmint operator/(ll a, mint b){return mint(a)/=b;}\n"; string p = "first"; vector<string> d; d.push_back((string)"mint_init"); d.push_back((string)"define_MD"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "mint_init"; string c = "{mint x; x.setmod(MD);}"; string p = "main_first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "readerFile"; string c = "inplace_L FILE *readerfp = stdin;\ninplace_L int readermode = 0;\nvoid readerFile(){\n if(readermode) fclose(readerfp);\n readerfp = stdin;\n readermode = 0;\n}\nvoid readerFile(string filename, string mode = \"r\"){\n if(readermode) fclose(readerfp);\n readerfp = fopen(filename.c_str(), mode.c_str());\n readermode = 1;\n}\nvoid readerFile(FILE *fp){\n if(readermode) fclose(readerfp);\n readerfp = fp;\n readermode = 0;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reader_int"; string c = "inline void rd(int &x){\n int k, m=0;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if(k=='-'){\n m=1;\n break;\n }\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n if(m){\n x=-x;\n }\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reader_unsigned"; string c = "inline void rd(unsigned &x){\n int k;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reader_ll"; string c = "inline void rd(ll &x){\n int k, m=0;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if(k=='-'){\n m=1;\n break;\n }\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n if(m){\n x=-x;\n }\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reader_ull"; string c = "inline void rd(ull &x){\n int k;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reader_Modint"; string c = "inline void rd(Modint &x){int i; rd(i); x=i;}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "modint"; } { string n = "reader_modint"; string c = "inline void rd(modint &x){int i; rd(i); x=i;}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "modint"; } { string n = "reader_Mint"; string c = "inline void rd(Mint &x){int i; rd(i); x=i;}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "mint"; } { string n = "reader_mint"; string c = "inline void rd(mint &x){int i; rd(i); x=i;}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "mint"; } { string n = "reader_double"; string c = "inline void rd(double &x){scanf(\"%lf\",&x);}"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "reader_char"; string c = "inline void rd(char &c){\n int i;\n for(;;){\n i = getchar_unlocked();\n if(i!=' '&&i!='\\n'&&i!='\\r'&&i!='\\t'&&i!=EOF) break;\n }\n c = i;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "reader_char_array"; string c = "inline int rd(char c[]){\n int i, sz = 0;\n for(;;){\n i = getchar_unlocked();\n if(i!=' '&&i!='\\n'&&i!='\\r'&&i!='\\t'&&i!=EOF) break;\n }\n c[sz++] = i;\n for(;;){\n i = getchar_unlocked();\n if(i==' '||i=='\\n'||i=='\\r'||i=='\\t'||i==EOF) break;\n c[sz++] = i;\n }\n c[sz]='\\0';\n return sz;\n}"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "reader_string"; string c = "inline void rd(string &x){\n char *buf = (char *)wmem;\n rd(buf);\n x = buf;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_char_array"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "rdLine"; string c = "inline int rdLine_L(char c[]){\n int i, sz = 0;\n for(;;){\n i = getchar_unlocked();\n if(i=='\\r') continue;\n if(i=='\\n') break;\n if(i==EOF){\n if(sz==0){\n c[sz] = '\\0';\n return -1;\n }\n break;\n }\n c[sz++] = i;\n }\n c[sz]='\\0';\n return sz;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "rd_int"; string c = "inline int rd_int(void){int x; rd(x); return x;}\n"; string p = "first"; vector<string> d; d.push_back((string)"reader_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writerFile"; string c = "inplace_L FILE *writerfp = stdout;\ninplace_L int writermode = 0;\nvoid writerFile(){\n if(writermode) fclose(writerfp);\n writerfp = stdout;\n readermode = 0;\n}\nvoid writerFile(string filename, string mode = \"w\"){\n if(writermode) fclose(writerfp);\n writerfp = fopen(filename.c_str(), mode.c_str());\n writermode = 1;\n}\nvoid writerFile(FILE *fp){\n if(writermode) fclose(writerfp);\n writerfp = fp;\n writermode = 0;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "writer_all"; string c = ""; string p = "first"; vector<string> d; d.push_back((string)"writer_char"); d.push_back((string)"writer_int"); d.push_back((string)"writer_unsigned"); d.push_back((string)"writer_ll"); d.push_back((string)"writer_ull"); d.push_back((string)"writer_Modint"); d.push_back((string)"writer_Mint"); d.push_back((string)"writer_modint"); d.push_back((string)"writer_mint"); d.push_back((string)"writer_double"); d.push_back((string)"writer_char_array"); d.push_back((string)"writer_string"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_char"; string c = "inline void wt_L(char a){\n putchar_unlocked(a);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_int"; string c = "inline void wt_L(int x){\n int s=0, m=0;\n char f[10];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(f[s]+'0');\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_int_withBase"; string c = "inline void wt_L(int x, int b){\n int s=0, m=0;\n char f[35];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%b, x/=b;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"[f[s]]);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_unsigned"; string c = "inline void wt_L(unsigned x){\n int s=0;\n char f[10];\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n while(s--) putchar_unlocked(f[s]+'0');\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_ll"; string c = "inline void wt_L(ll x){\n int s=0, m=0;\n char f[20];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(f[s]+'0');\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_ll_withBase"; string c = "inline void wt_L(ll x, int b){\n int s=0, m=0;\n char f[70];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%b, x/=b;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"[f[s]]);\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "writer_ull"; string c = "inline void wt_L(ull x){\n int s=0;\n char f[21];\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n while(s--) putchar_unlocked(f[s]+'0');\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_Modint"; string c = "inline void wt_L(Modint x){int i; i = (int)x; wt_L(i);}"; string p = "first"; vector<string> d; d.push_back((string)"writer_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "Modint"; } { string n = "writer_modint"; string c = "inline void wt_L(modint x){int i; i = (int)x; wt_L(i);}"; string p = "first"; vector<string> d; d.push_back((string)"writer_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "modint"; } { string n = "writer_Mint"; string c = "inline void wt_L(Mint x){int i; i = (int)x; wt_L(i);}"; string p = "first"; vector<string> d; d.push_back((string)"writer_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "Mint"; } { string n = "writer_mint"; string c = "inline void wt_L(mint x){int i; i = (int)x; wt_L(i);}"; string p = "first"; vector<string> d; d.push_back((string)"writer_int"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "mint"; } { string n = "writer_double"; string c = "inline void wt_L(double x){printf(\"%.15f\",x);}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_char_array"; string c = "inline void wt_L(const char c[]){\n int i=0;\n for(i=0;c[i]!='\\0';i++) putchar_unlocked(c[i]);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "writer_string"; string c = "inline void wt_L(string &x){\n int i=0;\n for(i=0;x[i]!='\\0';i++){\n putchar_unlocked(x[i]);\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"writer_char_array"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Matrix"; string c = "template<class T>\nstruct Matrix {\n int r, c, mem;\n T *dat;\n\n Matrix(){r=c=mem = 0;}\n Matrix(const int rr, const int cc){\n if(rr == 0 || cc == 0){\n r = c = 0;\n } else {\n r = rr;\n c = cc;\n }\n mem = r * c;\n if(mem > 0) dat = new T[mem];\n }\n Matrix(const Matrix<T> &a){\n int i;\n r = a.r;\n c = a.c;\n mem = r * c;\n dat = new T[mem];\n rep(i,mem) dat[i] = a.dat[i];\n }\n \n ~Matrix(){\n if(mem) delete [] dat;\n }\n\n void changeSize(const int rr, const int cc){\n if(rr==0 || cc==0){\n r = c = 0;\n } else {\n r = rr;\n c = cc;\n }\n if(mem < r*c){\n if(mem) delete [] dat;\n mem = r*c;\n dat = new T[mem];\n }\n }\n\n Matrix<T>& operator=(const Matrix<T> &a){\n int i, j;\n r = a.r;\n c = a.c;\n j = r * c;\n changeSize(r,c);\n rep(i,j) dat[i] = a.dat[i];\n return *this;\n }\n\n Matrix<T>& operator=(const int a){\n int i, j;\n j = r * c;\n rep(i,j) dat[i] = 0;\n j = min(r,c);\n rep(i,j) dat[i*c+i] = a;\n return *this;\n }\n\n Matrix<T>& operator+=(const Matrix<T> &a){\n int i, j;\n if(r==0 || r!=a.r || c!=a.c){\n changeSize(0,0);\n return *this;\n }\n j = r*c;\n rep(i,j) dat[i] += a.dat[i];\n return *this;\n }\n Matrix<T> operator+(const Matrix<T> &a){\n return Matrix<T>(*this) += a;\n }\n\n Matrix<T>& operator-=(const Matrix<T> &a){\n int i, j;\n if(r==0 || r!=a.r || c!=a.c){\n changeSize(0,0);\n return *this;\n }\n j = r*c;\n rep(i,j) dat[i] -= a.dat[i];\n return *this;\n }\n Matrix<T> operator-(const Matrix<T> &a){\n return Matrix<T>(*this) -= a;\n }\n\n Matrix<T>& operator*=(const Matrix<T> &a){\n int i, j, k, x;\n T *m;\n if(r==0 || c!=a.r){\n changeSize(0,0);\n return *this;\n }\n m = (T*)wmem;\n x = r * a.c;\n rep(i,x) m[i] = 0;\n rep(i,r) rep(k,c) rep(j,a.c) m[i*a.c+j] += dat[i*c+k] * a.dat[k*a.c+j];\n changeSize(r, a.c);\n rep(i,x) dat[i] = m[i];\n return *this;\n }\n Matrix<T> operator*(const Matrix<T> &a){\n return Matrix<T>(*this) *= a;\n }\n\n Matrix<T>& operator*=(const int a){\n int i, j;\n j = r * c;\n rep(i,j) dat[i] *= a;\n return *this;\n }\n Matrix<T>& operator*=(const ll a){\n int i, j;\n j = r * c;\n rep(i,j) dat[i] *= a;\n return *this;\n }\n Matrix<T>& operator*=(const double a){\n int i, j;\n j = r * c;\n rep(i,j) dat[i] *= a;\n return *this;\n }\n\n\n inline T* operator[](const int a){\n return dat+a*c;\n }\n};\ntemplate<class T> Matrix<T> operator*(const int a, const Matrix<T> &b){return Matrix<T>(b)*=a;}\ntemplate<class T> Matrix<T> operator*(const Matrix<T> &b, const int a){return Matrix<T>(b)*=a;}\ntemplate<class T> Matrix<T> operator*(const ll a, const Matrix<T> &b){return Matrix<T>(b)*=a;}\ntemplate<class T> Matrix<T> operator*(const Matrix<T> &b, const ll a){return Matrix<T>(b)*=a;}\ntemplate<class T> Matrix<T> operator*(const double a, const Matrix<T> &b){return Matrix<T>(b)*=a;}\ntemplate<class T> Matrix<T> operator*(const Matrix<T> &b, const double a){return Matrix<T>(b)*=a;}\n\n\ntemplate<class T, class S> inline Matrix<T> pow_L(Matrix<T> a, S b){\n int i, j;\n Matrix<T> res;\n res.changeSize(a.r, a.c);\n res = 1;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Permutation"; string c = "struct Permutation {\n int n, mem;\n int *dat;\n\n Permutation(){n = mem = 0;}\n Permutation(const int nn){\n n = mem = nn;\n if(mem > 0) dat = new int[mem];\n }\n Permutation(const Permutation &a){\n int i;\n mem = n = a.n;\n dat = new int[mem];\n rep(i,mem) dat[i] = a.dat[i];\n }\n \n ~Permutation(){\n if(mem) delete [] dat;\n }\n\n void changeSize(const int nn){\n n = nn;\n if(mem < n){\n if(mem) delete [] dat;\n mem = n;\n dat = new int[mem];\n }\n }\n\n Permutation& operator=(const Permutation &a){\n int i;\n changeSize(a.n);\n n = a.n;\n rep(i,n) dat[i] = a.dat[i];\n return *this;\n }\n\n Permutation& operator=(const int a){\n int i;\n rep(i,n) dat[i] = i;\n return *this;\n }\n\n Permutation& operator*=(const Permutation &a){\n int i, *m;\n void *mv = wmem;\n \n if(n==0 || n!=a.n){\n changeSize(0);\n return *this;\n }\n walloc1d(&m, n, &mv);\n rep(i,n) m[i] = dat[a.dat[i]];\n rep(i,n) dat[i] = m[i];\n return *this;\n }\n Permutation operator*(const Permutation &a){\n return Permutation(*this) *= a;\n }\n\n bool operator==(const Permutation &a){\n int i;\n if(n != a.n) return false;\n rep(i,n) if(dat[i] != a.dat[i]) return false;\n return true;\n }\n\n template<class T>\n void apply(T A[]){\n int i;\n T *B; void *mv = wmem;\n walloc1d(&B, n, &mv);\n rep(i,n) B[dat[i]] = A[i];\n rep(i,n) A[i] = B[i];\n }\n\n template<class T>\n void apply(T A[], T B[]){\n int i;\n rep(i,n) B[dat[i]] = A[i];\n }\n\n int cycle_len(int res[] = NULL){\n int i, j, k, sz = 0;\n int *vis;\n void *mv = wmem;\n\n if(res==NULL) walloc1d(&res, n, &mv);\n walloc1d(&vis, n, &mv);\n\n rep(i,n) vis[i] = 0;\n rep(i,n) if(!vis[i]){\n k = 0;\n j = i;\n while(vis[j]==0){\n vis[j] = 1;\n j = dat[j];\n k++;\n }\n res[sz++] = k;\n }\n return sz;\n }\n\n inline int& operator[](const int a){\n return dat[a];\n }\n};\n\n\ntemplate<class T> inline Permutation pow_L(Permutation a, T b){\n Permutation res;\n res.changeSize(a.n);\n res = 1;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "LIS_length"; string c = "template<class T>\nint LIS_length(int n, T a[], void *mem = wmem){\n int i, k, res;\n T *arr;\n\n if(n==0) return 0;\n walloc1d(&arr, n, &mem);\n arr[0] = a[0];\n res = 1;\n REP(i,1,n){\n k = lower_bound(arr, arr+res, a[i]) - arr;\n arr[k] = a[i];\n if(res==k) res++;\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "weaklyLIS_length"; string c = "template<class T>\nint weaklyLIS_length(int n, T a[], void *mem = wmem){\n int i, k, res;\n T *arr;\n\n if(n==0) return 0;\n walloc1d(&arr, n, &mem);\n arr[0] = a[0];\n res = 1;\n REP(i,1,n){\n k = upper_bound(arr, arr+res, a[i]) - arr;\n arr[k] = a[i];\n if(res==k) res++;\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "BIT_popcount"; string c = "inline int BIT_popcount_L(const int x){\n return __builtin_popcount(x);\n}\ninline int BIT_popcount_L(const ll x){\n return __builtin_popcountll(x);\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "BIT_ctz"; string c = "inline int BIT_ctz_L(const int x){\n return __builtin_ctz(x);\n}\ninline int BIT_ctz_L(const ll x){\n return __builtin_ctzll(x);\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Digit"; string c = "template<class T> inline int Digit_L(T n){\n int res = 0;\n while(n) res++, n /= 10;\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Digit_base"; string c = "template<class T, class S> inline int Digit_L(T n, S b){\n int res = 0;\n while(n) res++, n /= b;\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "sod"; string c = "template<class T> inline int sod_L(T n){\n int res = 0;\n while(n) res += n%10, n /= 10;\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "sod_base"; string c = "template<class T, class S> inline S sod_L(T n, S b){\n S res = 0;\n while(n) res += n%b, n /= b;\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "isPrime"; string c = "template<class T>\n inline int isPrime_L(T n){\n T i;\n if(n<=1) return 0;\n if(n<=3) return 1;\n if(n%2==0) return 0;\n for(i=3;i*i<=n;i+=2) if(n%i==0) return 0;\n return 1;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Prime"; string c = "int Prime_L(int N, int res[], void *mem=wmem){\n int i, a, b;\n int sz = 1;\n const int r = 23000;\n bool *isprime;\n int *sf, ss = 1;\n\n walloc1d(&isprime, r, &mem);\n walloc1d(&sf, r, &mem);\n isprime = (bool*)mem;\n sf = (int*)(isprime + r);\n\n N /= 2;\n res[0] = 2;\n b = min(r, N);\n rep(i,1,b) isprime[i] = 1;\n rep(i,1,b) if(isprime[i]){\n res[sz++] = 2i+1;\n sf[ss] = 2i*(i+1);\n if(sf[ss] < N){\n while(sf[ss] < r) isprime[sf[ss]] = 0, sf[ss] += res[ss];\n ss++;\n }\n }\n\n for(a=r; a<N; a+=r){\n b = min(a + r, N);\n isprime -= r;\n rep(i,a,b) isprime[i] = 1;\n rep(i,1,ss){\n while(sf[i] < b) isprime[sf[i]] = 0, sf[i] += res[i];\n }\n rep(i,a,b) if(isprime[i]) res[sz++] = 2i+1;\n }\n\n return sz;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "intervalSieve"; string c = "template<class T>\nvoid intervalSieve(ll st, int len, T res[], int ps, int p[]){\n int i;\n ll k = 2-st;\n\n rep(i,len) res[i] = 1;\n rep(i,k) res[i] = 0;\n\n rep(i,ps){\n k = (ll)p[i]*p[i];\n if(k >= st+len) break;\n if(k < st) k = (st+p[i]-1) / p[i] * p[i];\n while(k < st+len){\n res[k-st] = 0;\n k += p[i];\n }\n }\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Factor1"; string c = "template<class T> int Factor_L(T N){\n T i;\n int sz = 0;\n \n if(N%2==0){\n while(N%2==0) N /= 2;\n sz++;\n }\n for(i=3;i*i<=N;i+=2) if(N%i==0){\n while(N%i==0) N /= i;\n sz++;\n }\n if(N > 1) sz++;\n return sz;\n}\n\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Factor2"; string c = "template<class T> int Factor_L(T N, T fac[]){\n T i;\n int sz = 0;\n \n if(N%2==0){\n fac[sz] = 2;\n N /= 2;\n while(N%2==0) N /= 2;\n sz++;\n }\n for(i=3;i*i<=N;i+=2) if(N%i==0){\n fac[sz] = i;\n N /= i;\n while(N%i==0) N /= i;\n sz++;\n }\n if(N > 1){\n fac[sz] = N;\n sz++;\n }\n return sz;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Factor3"; string c = "template<class T> int Factor_L(T N, T fac[], int fs[]){\n T i;\n int sz = 0;\n\n if(N%2==0){\n fac[sz] = 2;\n fs[sz] = 1;\n N /= 2;\n while(N%2==0){\n N /= 2;\n fs[sz]++;\n }\n sz++;\n }\n for(i=3;i*i<=N;i+=2) if(N%i==0){\n fac[sz] = i;\n fs[sz] = 1;\n N /= i;\n while(N%i==0){\n N /= i;\n fs[sz]++;\n }\n sz++;\n }\n if(N > 1){\n fac[sz] = N;\n fs[sz] = 1;\n sz++;\n }\n return sz;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "FactorM"; string c = "template<class T> int FactorM_L(T N, T fac[]){\n T i;\n int sz = 0;\n \n while(N%2==0){\n fac[sz] = 2;\n N /= 2;\n sz++;\n }\n for(i=3;i*i<=N;i+=2) while(N%i==0){\n fac[sz] = i;\n N /= i;\n sz++;\n }\n if(N > 1){\n fac[sz] = N;\n sz++;\n }\n return sz;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Divisor"; string c = "template<class T> int Divisor_L(T N, T res[], void *mem = wmem){\n int i, j, k, s, sz = 0;\n T *fc;\n int *fs, fsz;\n\n walloc1d(&fc, 100, &mem);\n walloc1d(&fs, 100, &mem);\n \n fsz = Factor(N, fc, fs);\n\n res[sz++] = 1;\n rep(i,fsz){\n s = sz;\n k = s * fs[i];\n rep(j,k) res[sz++] = res[j] * fc[i];\n }\n\n sort(res, res+sz);\n return sz;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); d.push_back((string)"Factor3"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "DivisorSum"; string c = "ll DivisorSum_L(ll n, void *mem = wmem){\n int i;\n ll res, t, s;\n int fs, *fn;\n ll *fc;\n\n if(n<=0) return 0;\n\n walloc1d(&fc, 30);\n walloc1d(&fn, 30);\n fs = Factor(n, fc, fn);\n\n res = 1;\n rep(i,fs){\n s = t = 1;\n rep(j,fn[i]){\n t *= fc[i];\n s += t;\n }\n res *= s;\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); d.push_back((string)"Factor3"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Moebius"; string c = "template<class T>\nint Moebius_L(T n){\n T i;\n int res = 1;\n\n if(n%4==0) return 0;\n if(n%2==0) n /= 2, res = -res;\n\n for(i=3;i*i<=n;i+=2){\n if(n%i==0) n /= i, res = -res;\n if(n%i==0) return 0;\n }\n if(n > 1) res = -res;\n\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "pow2"; string c = "template<class T> inline T pow2_L(T a){ return a*a; }"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "pow3"; string c = "template<class T> inline T pow3_L(T a){ return a*a*a; }"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "pow4"; string c = "template<class T> inline T pow4_L(T a){ return a*a*a*a; }"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "pow"; string c = "template<class T, class S> inline T pow_L(T a, S b){\n T res = 1;\n res = 1;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n}\ninline double pow_L(double a, double b){\n return pow(a,b);\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "gcd"; string c = "template<class T> inline T GCD_L(T a,T b){T r; while(a)r=b,b=a,a=r%a; return b;}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "lcm"; string c = "template<class T> inline T LCM_L(T a,T b){return a/GCD_L(a,b)*b;}"; string p = "first"; vector<string> d; d.push_back((string)"gcd"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "multiset_popFirst"; string c = "template<class T> inline T popFirst(multiset<T> &a){\n T res = *(a.begin());\n a.erase(a.begin());\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "multiset_getFirst"; string c = "template<class T> inline T getFirst(multiset<T> &a){\n return *(a.begin());\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "multiset_popLast"; string c = "template<class T> inline T popLast(multiset<T> &a){\n T res;\n typename multiset<T>::iterator it;\n it = a.end();\n it--;\n res = *it;\n a.erase(it);\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "multiset_getLast"; string c = "template<class T> inline T getLast(multiset<T> &a){\n typename multiset<T>::iterator it;\n it = a.end();\n it--;\n return *it;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "set_popFirst"; string c = "template<class T> inline T popFirst(set<T> &a){\n T res = *(a.begin());\n a.erase(a.begin());\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "set_getFirst"; string c = "template<class T> inline T getFirst(set<T> &a){\n return *(a.begin());\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "set_popLast"; string c = "template<class T> inline T popLast(set<T> &a){\n T res;\n typename set<T>::iterator it;\n it = a.end();\n it--;\n res = *it;\n a.erase(it);\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "set_getLast"; string c = "template<class T> inline T getLast(set<T> &a){\n typename set<T>::iterator it;\n it = a.end();\n it--;\n return *it;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "combination_mint"; string c = "struct combination_mint{\n mint *fac, *ifac;\n\n void init(int n, void **mem = &wmem){\n int i;\n \n walloc1d(&fac, n, mem);\n walloc1d(&ifac, n, mem);\n \n fac[0] = 1;\n rep(i,1,n) fac[i] = fac[i-1] * i;\n ifac[n-1] = 1 / fac[n-1];\n for(i=n-2;i>=0;i--) ifac[i] = ifac[i+1] * (i+1);\n }\n\n mint C(int a, int b){\n if(b < 0 || b > a) return 0;\n return fac[a]*ifac[b]*ifac[a-b];\n }\n\n mint P(int a, int b){\n if(b < 0 || b > a) return 0;\n return fac[a]*ifac[a-b];\n }\n\n mint H(int a, int b){\n if(a==0 && b==0) return 1;\n if(a<=0 || b<0) return 0;\n return C(a+b-1, b);\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"mint"); d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "reduceFraction"; string c = "template<class T> void reduceFraction(T&a, T&b){T g=GCD_L(a,b);a/=g;b/=g;}"; string p = "first"; vector<string> d; d.push_back((string)"gcd"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "runLength"; string c = "template<class T>\nint runLength(int N, T *arr, T *val, int *len){\n int i, rN;\n if(N==0) return 0;\n rN = 1;\n val[0] = arr[0];\n len[0] = 1;\n rep(i,1,N){\n if(val[rN-1] == arr[i]){\n len[rN-1]++;\n } else {\n val[rN] = arr[i];\n len[rN] = 1;\n rN++;\n }\n }\n return rN;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "arrcmp"; string c = "template<class S, class T> inline int arrcmp(int As, S A[], int Bs, T B[]){\n int i;\n for(i=0;;i++){\n if(i==As==Bs) break;\n if(i==As) return -1;\n if(i==Bs) return 1;\n if(A[i] < B[i]) return -1;\n if(A[i] > B[i]) return 1;\n }\n return 0;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "arrErase"; string c = "template<class S>\nvoid arrErase(int k, int &sz, S a[]){\n int i;\n sz--;\n rep(i,k,sz) a[i] = a[i+1];\n}\n\ntemplate<class S, class T>\nvoid arrErase(int k, int &sz, S a[], T b[]){\n int i;\n sz--;\n rep(i,k,sz) a[i] = a[i+1];\n rep(i,k,sz) b[i] = b[i+1];\n}\n\ntemplate<class S, class T, class U>\nvoid arrErase(int k, int &sz, S a[], T b[], U c[]){\n int i;\n sz--;\n rep(i,k,sz) a[i] = a[i+1];\n rep(i,k,sz) b[i] = b[i+1];\n rep(i,k,sz) c[i] = c[i+1];\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "arrInsert"; string c = "template<class S>\nvoid arrInsert(const int k, int &sz, S a[], const S aval){\n int i;\n sz++;\n for(i=sz-1;i>k;i--) a[i] = a[i-1];\n a[k] = aval;\n}\n\ntemplate<class S, class T>\nvoid arrInsert(const int k, int &sz, S a[], const S aval, T b[], const T bval){\n int i;\n sz++;\n for(i=sz-1;i>k;i--) a[i] = a[i-1];\n for(i=sz-1;i>k;i--) b[i] = b[i-1];\n a[k] = aval;\n b[k] = bval;\n}\n\ntemplate<class S, class T, class U>\nvoid arrInsert(const int k, int &sz, S a[], const S aval, T b[], const T bval, U c[], const U cval){\n int i;\n sz++;\n for(i=sz-1;i>k;i--) a[i] = a[i-1];\n for(i=sz-1;i>k;i--) b[i] = b[i-1];\n for(i=sz-1;i>k;i--) c[i] = c[i-1];\n a[k] = aval;\n b[k] = bval;\n c[k] = cval;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "divup"; string c = "template<class S, class T> inline S divup_L(S a, T b){ return (a+b-1)/b; }"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "moddw"; string c = "template<class S, class T> inline S moddw_L(S a, const T b){\n a %= b;\n if(a < 0) a += b;\n return a;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "chmin"; string c = "template<class S, class T> inline S chmin(S &a, T b){if(a>b)a=b;return a;}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "chmax"; string c = "template<class S, class T> inline S chmax(S &a, T b){if(a<b)a=b;return a;}"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "arrRot"; string c = "template<class T>\nvoid arrRot(int k, int N, T A[], T B[] = NULL, void *mem = wmem){\n int fg = 0;\n k %%= N;\n if(B==NULL){\n walloc1d(&B, N, &mem);\n fg = 1;\n }\n rep(i,k,N) B[i-k] = A[i];\n rep(i,k) B[N-k+i] = A[i];\n if(fg) rep(i,N) A[i] = B[i];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); d.push_back((string)"moddw"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Polynomial"; string c = "template<class T>\nstruct Polynomial {\n int d, mem;\n T *c;\n\n Polynomial(){\n mem = 1;\n c = new T[mem];\n d = 0;\n c[0] = 0;\n }\n\n Polynomial(const Polynomial<T> &a){\n d = a.d;\n mem = d + 1;\n c = new T[mem];\n rep(i,d+1) c[i] = a.c[i];\n }\n\n ~Polynomial(){\n delete [] c;\n }\n\n void expand(int z){\n T *cc;\n if(z <= mem) return;\n z >?= 2 mem;\n cc = new T[z];\n rep(i,d+1) cc[i] = c[i];\n delete [] c;\n c = cc;\n }\n\n inline void change(const int dg, const T cf){\n expand(dg+1);\n while(d < dg) c[++d] = 0;\n c[dg] = cf;\n while(d && c[d]==0) d--;\n }\n\n inline int deg(void){\n return d;\n }\n\n inline T coef(const int k){\n if(k > d) return 0;\n return c[k];\n }\n\n Polynomial<T>& operator=(const Polynomial<T> &a){\n d = a.d;\n mem = d + 1;\n c = new T[mem];\n rep(i,d+1) c[i] = a.c[i];\n return *this;\n }\n\n Polynomial<T>& operator+=(const Polynomial<T> &a){\n int i, k;\n k = max(d, a.d);\n expand(k+1);\n while(d < k) c[++d] = 0;\n rep(i,a.d+1) c[i] += a.c[i];\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator+(const Polynomial<T> &a){\n return Polynomial<T>(*this) += a;\n }\n\n Polynomial<T>& operator-=(const Polynomial<T> &a){\n int i, k;\n k = max(d, a.d);\n expand(k+1);\n while(d < k) c[++d] = 0;\n rep(i,a.d+1) c[i] -= a.c[i];\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator-(const Polynomial<T> &a){\n return Polynomial<T>(*this) -= a;\n }\n\n Polynomial<T>& operator*=(const Polynomial<T> &a){\n int i, j, k;\n T *cc;\n void *mem = wmem;\n \n k = d + a.d;\n expand(k+1);\n walloc1d(&cc, k+1, &mem);\n\n rep(i,k+1) cc[i] = 0;\n rep(i,d+1) rep(j,a.d+1) cc[i+j] += c[i] * a.c[j];\n\n rep(i,k+1) c[i] = cc[i];\n d = k;\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator*(const Polynomial<T> &a){\n return Polynomial<T>(*this) *= a;\n }\n\n Polynomial<T>& operator/=(const Polynomial<T> &a){\n int i, j, k;\n T *cc, e;\n void *mem = wmem;\n\n walloc1d(&cc, d-a.d, &mem);\n\n for(i=d; i>=a.d; i--){\n cc[i-a.d] = e = c[i] / a.c[a.d];\n rep(j, a.d+1) c[i-j] -= e * a.c[a.d-j];\n }\n\n d -= a.d;\n rep(i,d+1) c[i] = cc[i];\n return *this;\n }\n Polynomial<T> operator/(const Polynomial<T> &a){\n return Polynomial<T>(*this) /= a;\n }\n\n Polynomial<T>& operator%=(const Polynomial<T> &a){\n int i, j, k;\n T *cc, e;\n void *mem = wmem;\n\n walloc1d(&cc, d-a.d, &mem);\n\n for(i=d; i>=a.d; i--){\n cc[i-a.d] = e = c[i] / a.c[a.d];\n rep(j, a.d+1) c[i-j] -= e * a.c[a.d-j];\n }\n\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator%(const Polynomial<T> &a){\n return Polynomial<T>(*this) %= a;\n }\n\n\n Polynomial<T>& operator*=(const T &a){\n rep(i,d+1) c[i] *= a;\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator*(const T &a){\n return Polynomial<T>(*this) *= a;\n }\n\n Polynomial<T>& operator/=(const T &a){\n rep(i,d+1) c[i] /= a;\n while(d && c[d]==0) d--;\n return *this;\n }\n Polynomial<T> operator/(const T &a){\n return Polynomial<T>(*this) /= a;\n }\n\n inline T operator()(const T x){\n int i;\n T res;\n res = 0;\n for(i=d;i>=0;i--) res = res * x + c[i];\n return res;\n }\n\n};\n\ntemplate<class T> Polynomial<T> operator*(const T a, const Polynomial<T> &b){return Polynomial<T>(b)*=a;}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"chmax"); d.push_back((string)"max_L"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "SuffixArray"; string c = "template<class T> void SuffixArray(T *s, int N, int K, int *SA, int *LCP = NULL, void *mem = wmem) {\n int i, j, d, m, *s1;\n int name, prev, pos;\n char *t, *lms;\n int *cnt, *cnt1, *cnt2;\n \n walloc1d(&t, N+1, &mem);\n walloc1d(&lms, N+1, &mem);\n walloc1d(&cnt, K+1, &mem);\n walloc1d(&cnt1, K+1, &mem);\n walloc1d(&cnt2, K+1, &mem);\n\n N++;\n\n s[N-1] = 0;\n\n t[N-1] = 1;\n t[N-2] = 0;\n for(i=N-3;i>=0;i--){\n if(s[i] < s[i+1] || (s[i]==s[i+1] && t[i+1])) t[i] = 1; else t[i] = 0;\n }\n lms[0] = 0;\n REP(i,1,N){\n if(t[i] && !t[i-1]) lms[i] = 1; else lms[i] = 0;\n }\n\n rep(i,K+1) cnt1[i] = 0;\n rep(i,N) cnt1[s[i]]++;\n j = 0;\n rep(i,K+1){\n j += cnt1[i];\n cnt2[i] = j - cnt1[i];\n cnt1[i] = j;\n }\n\n rep(i,K+1) cnt[i] = cnt1[i];\n for(i=0; i<N; i++) SA[i] = -1;\n for(i=1; i<N; i++) if(lms[i]) SA[--cnt[s[i]]]=i;\n \n rep(i,K+1) cnt[i] = cnt2[i];\n rep(i,N){\n j = SA[i]-1;\n if(j>=0 && !t[j]) SA[cnt[s[j]]++] = j;\n }\n\n rep(i,K+1) cnt[i] = cnt1[i];\n for(i=N-1;i>=0;i--){\n j = SA[i] - 1;\n if(j>=0 && t[j]) SA[--cnt[s[j]]] = j;\n }\n\n m = 0;\n rep(i,N) if(lms[SA[i]]) SA[m++] = SA[i];\n REP(i,m,N) SA[i] = -1;\n \n name=0;\n prev=-1;\n rep(i,m){\n pos = SA[i];\n rep(d,N){\n if(prev==-1 || s[pos+d]!=s[prev+d] || t[pos+d]!=t[prev+d]){\n name++;\n prev=pos;\n break;\n } else if(d>0 && (lms[pos+d] || lms[prev+d])){\n break;\n }\n }\n pos /= 2;\n SA[m+pos]=name-1;\n }\n for(i=N-1, j=N-1; i>=m; i--) if(SA[i]>=0) SA[j--]=SA[i];\n\n s1 = SA+N-m;\n if(name<m){\n SuffixArray(s1, m-1, name-1, SA, NULL, mem);\n } else {\n for(i=0; i<m; i++) SA[s1[i]] = i;\n }\n\n rep(i,K+1) cnt[i] = cnt1[i];\n \n for(i=1, j=0; i<N; i++) if(lms[i]) s1[j++]=i;\n for(i=0; i<m; i++) SA[i]=s1[SA[i]];\n for(i=m; i<N; i++) SA[i]=-1;\n for(i=m-1; i>=0; i--) {\n j=SA[i]; SA[i]=-1;\n SA[--cnt[s[j]]]=j;\n }\n\n rep(i,N){\n j = SA[i]-1;\n if(j>=0 && !t[j]) SA[cnt2[s[j]]++] = j;\n }\n\n for(i=N-1;i>=0;i--){\n j = SA[i] - 1;\n if(j>=0 && t[j]) SA[--cnt1[s[j]]] = j;\n }\n\n if(LCP != NULL){\n cnt = (int*)t;\n d = 0;\n rep(i,N) cnt[SA[i]] = i;\n rep(i,N){\n if(cnt[i]){\n for(j=SA[cnt[i]-1]; j+d<N-1&&i+d<N-1&&s[j+d]==s[i+d];d++);\n LCP[cnt[i]]=d;\n } else {\n LCP[cnt[i]] = -1;\n }\n if(d>0) d--;\n }\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "unionFind"; string c = "struct unionFind{\n int *d, N, M;\n inline void malloc(const int n){\n d = (int*)std::malloc(n*sizeof(int));\n M = n;\n }\n inline void free(void){\n std::free(d);\n }\n inline void walloc(const int n, void **mem=&wmem){\n walloc1d(&d, n, mem);\n M = n;\n }\n inline void init(const int n){\n int i;\n N = n;\n rep(i,n) d[i] = -1;\n }\n inline void init(void){\n init(M);\n }\n inline int get(int a){\n int t = a, k;\n while(d[t]>=0) t=d[t];\n while(d[a]>=0) k=d[a], d[a]=t, a=k;\n return a;\n }\n inline int connect(int a, int b){\n if(d[a]>=0) a=get(a);\n if(d[b]>=0) b=get(b);\n if(a==b) return 0;\n if(d[a] < d[b]) d[a] += d[b], d[b] = a;\n else d[b] += d[a], d[a] = b;\n return 1;\n }\n inline int operator()(int a){\n return get(a);\n }\n inline int operator()(int a, int b){\n return connect(a,b);\n }\n inline int& operator[](const int a){\n return d[a];\n }\n inline int size(int a){\n a = get(a);\n return -d[a];\n }\n inline int sizeList(int res[]){\n int i, sz=0;\n rep(i,N) if(d[i]<0) res[sz++] = -d[i];\n return sz;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "fibonacci_mod"; string c = "int fibonacci_mod_L(ull n, int md){\n ull a=1, b=0, c=1, ma=1, mb=1, mc=0, ta, tb, tc;\n while(n){\n if(n%2){\n ta = a*ma + b*mb;\n tb = a*mb + b*mc;\n tc = b*mb + c*mc;\n a = ta % md;\n b = tb % md;\n c = tc % md;\n }\n ta = ma*ma + mb*mb;\n tb = ma*mb + mb*mc;\n tc = mb*mb + mc*mc;\n ma = ta % md;\n mb = tb % md;\n mc = tc % md;\n n/=2;\n }\n return b;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Isqrt_f"; string c = "inline ll Isqrt_f_L(const ll n){\n ll r = sqrt(n);\n r = max(r-2, 0);\n while( (r+1)**2 <= n ) r++;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow2"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Isqrt_c"; string c = "inline ll Isqrt_c_L(const ll n){\n ll r = sqrt(n);\n r = max(r-2, 0);\n while( r**2 < n ) r++;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow2"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Isqrt_s"; string c = "inline ll Isqrt_s_L(const ll n){\n ll r = sqrt(n);\n r = max(r-2, 0);\n while( (r+1)**2 <= n ) r++;\n if(r*r!=n) r = -1;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow2"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Icbrt_f"; string c = "inline ll Icbrt_f_L(const ll n){\n ll r = pow(n, 1.0/3);\n r = max(r-2, 0);\n while( (r+1)**3 <= n ) r++;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow3"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Icbrt_c"; string c = "inline ll Icbrt_c_L(const ll n){\n ll r = pow(n, 1.0/3);\n r = max(r-2, 0);\n while( r**3 < n ) r++;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow3"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Icbrt_s"; string c = "inline ll Icbrt_s_L(const ll n){\n ll r = pow(n, 1.0/3);\n r = max(r-2, 0);\n while( (r+1)**3 <= n ) r++;\n if(r**3!=n) r = -1;\n return r;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"pow3"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Unique1"; string c = "template<class T>\nvoid Unique_L(int &N, T A[], int sorted=0){\n int i, k;\n if(!sorted) sort(A, A+N);\n k = 0;\n rep(i,N) if(k==0 || A[k-1]!=A[i]) A[k++] = A[i];\n N = k;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Unique2"; string c = "template<class T, class S>\nvoid Unique_L(int &N, T A[], S B[], int sorted=0){\n int i, k = 0;\n if(!sorted) sortA(N, A, B);\n rep(i,N){\n if(!k || A[k-1]!=A[i]){\n A[k] = A[i];\n B[k] = B[i];\n k++;\n } else {\n B[k-1] += B[i];\n }\n }\n N=k;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"sortA_2"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "coordcomp_1"; string c = "template<class T>\nint coordcomp_L(int n, T arr[], int res[] = NULL, void *mem = wmem){\n int i, k = 0;\n pair<T,int> *r;\n\n walloc1d(&r, n, &mem);\n\n rep(i,n) r[i].first = arr[i], r[i].second = i;\n sort(r, r+n);\n\n if(res != NULL){\n rep(i,n){\n if(i && r[i].first != r[i-1].first) k++;\n res[r[i].second] = k;\n }\n } else {\n rep(i,n){\n if(i && r[i].first != r[i-1].first) k++;\n arr[r[i].second] = k;\n }\n }\n return k+1;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "coordcomp_2"; string c = "template<class T>\nint coordcomp_L(int n1, T arr1[], int n2, T arr2[], int res1[] = NULL, int res2[] = NULL, void *mem = wmem){\n int i, k = 0;\n pair<T,int> *r;\n\n walloc1d(&r, n1+n2, &mem);\n\n rep(i,n1) r[i].first = arr1[i], r[i].second = i;\n rep(i,n2) r[n1+i].first = arr2[i], r[n1+i].second = n1+i;\n sort(r, r+n1+n2);\n\n rep(i,n1+n2){\n if(i && r[i].first != r[i-1].first) k++;\n if(r[i].second < n1){\n if(res1!=NULL) res1[r[i].second] = k;\n else arr1[r[i].second] = k;\n } else {\n if(res2!=NULL) res2[r[i].second-n1] = k;\n else arr2[r[i].second-n1] = k;\n }\n }\n\n return k+1;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Heap"; string c = "template<class T>\nstruct Heap {\n int size;\n T *val;\n\n void malloc(const int N){\n val = (T*) std::malloc(N*sizeof(T));\n size = 0;\n }\n\n void walloc(const int N, void **mem = &wmem){\n walloc1d(&val, N, mem);\n size = 0;\n }\n\n void free(){\n std::free(val);\n }\n\n void init(){\n size = 0;\n }\n\n void up(){\n int n = size - 1, m;\n while(n){\n m = (n-1) / 2;\n if(val[m] <= val[n]) break;\n swap(val[m], val[n]);\n n = m;\n }\n }\n \n void down(){\n int n = 0, m;\n for(;;){\n m=2n+1;\n if(m>=size) break;\n if(m+1<size && val[m] > val[m+1]) m++;\n if(val[m] >= val[n]) break;\n swap(val[m], val[n]);\n n = m;\n }\n }\n\n T top(){\n return val[0];\n }\n\n T pop(){\n T res = val[0];\n size--;\n if(size > 0) val[0] = val[size], down();\n return res;\n }\n\n T push(const T x){\n val[size++] = x;\n up();\n return x;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Heap_max"; string c = "template<class T>\nstruct Heap_max {\n int size;\n T *val;\n\n void malloc(const int N){\n val = (T*) std::malloc(N*sizeof(T));\n size = 0;\n }\n\n void walloc(const int N, void **mem = &wmem){\n walloc1d(&val, N, mem);\n size = 0;\n }\n\n void free(){\n std::free(val);\n }\n\n void init(){\n size = 0;\n }\n\n void up(){\n int n = size - 1, m;\n while(n){\n m = (n-1) / 2;\n if(val[m] >= val[n]) break;\n swap(val[m], val[n]);\n n = m;\n }\n }\n \n void down(){\n int n = 0, m;\n for(;;){\n m=2n+1;\n if(m>=size) break;\n if(m+1<size && val[m] < val[m+1]) m++;\n if(val[m] <= val[n]) break;\n swap(val[m], val[n]);\n n=m;\n }\n }\n\n T top(){\n return val[0];\n }\n\n T pop(){\n T res = val[0];\n size--;\n if(size > 0) val[0] = val[size], down();\n return res;\n }\n\n T push(const T x){\n val[size++] = x;\n up();\n return x;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "LHeap"; string c = "template <class T>\nstruct LHeap {\n int *hp, *place, size;\n T *val;\n\n void malloc(int N){\n hp = (int*)std::malloc(N*sizeof(int));\n place=(int*)std::malloc(N*sizeof(int));\n val=(T*)std::malloc(N*sizeof(T));\n }\n void walloc(int N, void **mem=&wmem){\n walloc1d(&hp, N, mem);\n walloc1d(&place, N, mem);\n walloc1d(&val, N, mem);\n }\n void free(){\n std::free(hp);\n std::free(place);\n std::free(val);\n }\n void init(int N){\n int i;\n size=0;\n rep(i,N) place[i]=-1;\n }\n void up(int n){\n int m;\n while(n){\n m=(n-1)/2;\n if(val[hp[m]]<=val[hp[n]])break;\n swap(hp[m],hp[n]);\n swap(place[hp[m]],place[hp[n]]);\n n=m;\n }\n }\n void down(int n){\n int m;\n for(;;){\n m=2*n+1;\n if(m>=size)break;\n if(m+1<size&&val[hp[m]]>val[hp[m+1]])m++;\n if(val[hp[m]]>=val[hp[n]])break;\n swap(hp[m],hp[n]);\n swap(place[hp[m]],place[hp[n]]);\n n=m;\n }\n }\n void change(int n, T v){\n T f = val[n];\n val[n] = v;\n if(place[n]==-1){\n place[n] = size;\n hp[size++] = n;\n up(place[n]);\n } else {\n if(f < v) down(place[n]);\n else if(f > v) up(place[n]);\n }\n }\n int pop(void){\n int res = hp[0];\n place[res] = -1;\n size--;\n if(size){\n hp[0]=hp[size];\n place[hp[0]]=0;\n down(0);\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "DijkstraHeap"; string c = "template <class T>\nstruct DijkstraHeap {\n int *hp, *place, size;\n char *visited; T *val;\n\n void malloc(int N){\n hp = (int*)std::malloc(N*sizeof(int));\n place = (int*)std::malloc(N*sizeof(int));\n visited = (char*)std::malloc(N*sizeof(char));\n val = (T*)std::malloc(N*sizeof(T));\n }\n void free(){\n std::free(hp);\n std::free(place);\n std::free(visited);\n std::free(val);\n }\n void walloc(int N, void **mem=&wmem){\n walloc1d(&hp, N, mem);\n walloc1d(&place, N, mem);\n walloc1d(&visited, N, mem);\n walloc1d(&val, N, mem);\n }\n void init(int N){\n int i;\n size = 0;\n rep(i,N) place[i]=-1;\n rep(i,N) visited[i]=0;\n }\n void up(int n){\n int m;\n while(n){\n m=(n-1)/2;\n if(val[hp[m]]<=val[hp[n]])break;\n swap(hp[m],hp[n]);\n swap(place[hp[m]],place[hp[n]]);\n n=m;\n }\n }\n void down(int n){\n int m;\n for(;;){\n m=2*n+1;\n if(m>=size)break;\n if(m+1<size&&val[hp[m]]>val[hp[m+1]])m++;\n if(val[hp[m]]>=val[hp[n]]) break;\n swap(hp[m],hp[n]);\n swap(place[hp[m]],place[hp[n]]);\n n=m;\n }\n }\n void change(int n, T v){\n if(visited[n]||(place[n]>=0&&val[n]<=v))return;\n val[n]=v;\n if(place[n]==-1)place[n]=size,hp[size++]=n,up(place[n]);\n else up(place[n]);\n }\n int pop(void){\n int res=hp[0];\n place[res]=-1;\n size--;\n if(size)hp[0]=hp[size],place[hp[0]]=0,down(0);\n visited[res]=1;\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "fenwick"; string c = "template<class T>\nstruct fenwick{\n int size, memory;\n T *data;\n\n void malloc(int mem){\n memory = mem;\n data = (T*)std::malloc(sizeof(T)*mem);\n }\n\n void walloc(int mem, void **workMemory=&wmem){\n memory = mem;\n walloc1d(&data, mem, workMemory);\n }\n\n void free(void){\n memory = 0;\n free(data);\n }\n\n void init(int N){\n size = N;\n memset(data,0,sizeof(T)*N);\n }\n\n void add(int k, T val){\n while(k < size) data[k] += val, k |= k+1;\n }\n\n T get(int k){\n T res = 0;\n while(k>=0) res += data[k], k = (k&(k+1))-1;\n return res;\n }\n\n T range(int a, int b){\n if(b==-1)b=size-1;\n return get(b) - get(a-1);\n }\n\n int kth(T k){\n int i=0, j=size, c;\n T v;\n while(i<j){\n c = (i+j)/2;\n v = get(c);\n if(v <= k) i=c+1; else j=c;\n }\n return i==size?-1:i;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree"; string c = "template<class T>\nstruct segtree{\n int N, logN;\n T *sum, *mn;\n int *mnind;\n\n T *fixval; char *fixed;\n T *addval;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n\n sum = new T[2*i];\n mn = new T[2*i];\n mnind = new int[2*i];\n fixval = new T[i];\n addval = new T[i];\n fixed = new char[i];\n\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n\n walloc1d(&sum, 2i, mem);\n walloc1d(&mn, 2i, mem);\n walloc1d(&mnind, 2i, mem);\n walloc1d(&fixval, i, mem);\n walloc1d(&addval, i, mem);\n walloc1d(&fixed, i, mem);\n\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] sum;\n delete [] mn;\n delete [] mnind;\n delete [] fixval;\n delete [] addval;\n delete [] fixed;\n }\n\n T& operator[](int i){\n return sum[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) sum[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n rep(i,N) mn[N+i] = sum[N+i], mnind[N+i] = i;\n for(i=N-1;i;i--){\n sum[i] = sum[2*i] + sum[2*i+1];\n if(mn[2*i] <= mn[2*i+1]){\n mn[i] = mn[2*i];\n mnind[i] = mnind[2*i];\n } else {\n mn[i] = mn[2*i+1];\n mnind[i] = mnind[2*i+1];\n }\n }\n REP(i,1,N) fixed[i] = 0;\n REP(i,1,N) addval[i] = 0;\n }\n \n inline void push_one(int a, int sz, int st){\n if(fixed[a]){\n if(sz > 1){\n fixed[a*2] = fixed[a*2+1] = 1;\n fixval[a*2] = fixval[a*2+1] = fixval[a];\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n mn[a*2] = mn[a*2+1] = fixval[a];\n mnind[a*2] = st;\n mnind[a*2+1] = st + sz;\n } else {\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n mn[a*2] = mn[a*2+1] = fixval[a];\n mnind[a*2] = st;\n mnind[a*2+1] = st + sz;\n }\n fixed[a] = 0;\n addval[a] = 0;\n return;\n }\n if(addval[a] != 0){\n if(sz > 1){\n if(fixed[a*2]) fixval[a*2] += addval[a];\n else addval[a*2] += addval[a];\n if(fixed[a*2+1]) fixval[a*2+1] += addval[a];\n else addval[a*2+1] += addval[a];\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n mn[a*2] += addval[a];\n mn[a*2+1] += addval[a];\n } else {\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n mn[a*2] += addval[a];\n mn[a*2+1] += addval[a];\n }\n addval[a] = 0;\n return;\n }\n }\n \n inline void push(int a){\n int i, aa = a - N, nd, sz, st;\n for(i=logN;i;i--){\n nd = a>>i;\n sz = 1<<(i-1);\n st = 2 * sz * (aa>>i);\n push_one(nd, sz, st);\n }\n }\n \n inline void build(int a){\n int sz = 1, st = a - N;\n while(a > 1){\n if(a%2) st += sz;\n a /= 2;\n sz *= 2;\n if(fixed[a]){\n sum[a] = sz * fixval[a];\n mn[a] = fixval[a];\n } else {\n sum[a] = sum[a*2] + sum[a*2+1];\n if(mn[a*2] <= mn[a*2+1]){\n mn[a] = mn[a*2];\n mnind[a] = mnind[a*2];\n } else {\n mn[a] = mn[a*2+1];\n mnind[a] = mnind[a*2+1];\n }\n if(addval[a] != 0){\n mn[a] += addval[a];\n sum[a] += sz * addval[a];\n }\n }\n }\n }\n \n inline void change(int a, int b, T val){\n int sz = 1, aa, bb, st_a = a, st_b = b;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] = mn[a] = val;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n sum[b] = mn[b] = val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n fixed[a]=1, fixval[a]=val;\n sum[a] = sz * val;\n mn[a] = val;\n mnind[a] = st_a;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n fixed[b]=1, fixval[b]=val;\n sum[b] = sz * val;\n mn[b] = val;\n mnind[b] = st_b;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline void add(int a, int b, T val){\n int sz = 1, aa, bb;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] += val;\n mn[a] += val;\n a++;\n }\n if(b%2){\n b--;\n sum[b] += val;\n mn[b] += val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n if(fixed[a]) fixval[a] += val; else addval[a] += val;\n sum[a] += sz * val;\n mn[a] += val;\n a++;\n }\n if(b%2){\n b--;\n if(fixed[b]) fixval[b] += val; else addval[b] += val;\n sum[b] += sz * val;\n mn[b] += val;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline pair<T,int> getMin(int a, int b){\n pair<T,int> res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, make_pair(mn[a], mnind[a]));\n } else {\n res = make_pair(mn[a], mnind[a]);\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(make_pair(mn[b], mnind[b]), tmp);\n } else {\n tmp = make_pair(mn[b], mnind[b]);\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n\n inline T getMinVal(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, mn[a]);\n } else {\n res = mn[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(mn[b], tmp);\n } else {\n tmp = mn[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n\n inline int getMinInd(int a, int b){\n return getMin(a,b).second;\n }\n\n inline T getSum(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n while(a < b){\n if(a%2){\n if(fga){\n res = res + sum[a];\n } else {\n res = sum[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = sum[b] + tmp;\n } else {\n tmp = sum[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = res + tmp;\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_Point_Minval"; string c = "template<class T>\nstruct segtree_Point_Minval{\n int N, logN;\n T *mn;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n mn = new T[2*i];\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n walloc1d(&mn, 2i, mem);\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] mn;\n }\n\n T& operator[](int i){\n return mn[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) mn[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n for(i=N-1;i;i--){\n mn[i] = min(mn[2i], mn[2i+1]);\n }\n }\n \n inline void build(int a){\n while(a > 1){\n a /= 2;\n mn[a] = min(mn[2a], mn[2a+1]);\n }\n }\n \n inline void change(int a, T val){\n mn[a+N] = val;\n build(a+N);\n }\n \n inline void add(int a, T val){\n mn[a+N] += val;\n build(a+N);\n }\n \n inline T getMinVal(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n\n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, mn[a]);\n } else {\n res = mn[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(mn[b], tmp);\n } else {\n tmp = mn[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_Point_Min"; string c = "template<class T>\nstruct segtree_Point_Min{\n int N, logN;\n T *mn;\n int *mnind;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n mn = new T[2*i];\n mnind = new int[2*i];\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n walloc1d(&mn, 2i, mem);\n walloc1d(&mnind, 2i, mem);\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] mn;\n delete [] mnind;\n }\n\n T& operator[](int i){\n return mn[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) mn[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n rep(i,N) mnind[N+i] = i;\n for(i=N-1;i;i--){\n if(mn[2*i] <= mn[2*i+1]){\n mn[i] = mn[2*i];\n mnind[i] = mnind[2*i];\n } else {\n mn[i] = mn[2*i+1];\n mnind[i] = mnind[2*i+1];\n }\n }\n }\n \n inline void build(int a){\n while(a > 1){\n a /= 2;\n if(mn[a*2] <= mn[a*2+1]){\n mn[a] = mn[a*2];\n mnind[a] = mnind[a*2];\n } else {\n mn[a] = mn[a*2+1];\n mnind[a] = mnind[a*2+1];\n }\n }\n }\n \n inline void change(int a, T val){\n mn[a+N] = val;\n build(a+N);\n }\n \n inline void add(int a, T val){\n mn[a+N] += val;\n build(a+N);\n }\n \n inline pair<T,int> getMin(int a, int b){\n pair<T,int> res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, make_pair(mn[a], mnind[a]));\n } else {\n res = make_pair(mn[a], mnind[a]);\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(make_pair(mn[b], mnind[b]), tmp);\n } else {\n tmp = make_pair(mn[b], mnind[b]);\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n\n inline T getMinVal(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, mn[a]);\n } else {\n res = mn[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(mn[b], tmp);\n } else {\n tmp = mn[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n \n inline int getMinInd(int a, int b){\n return getMin(a,b).second;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_Point_SumMin"; string c = "template<class T>\nstruct segtree_Point_SumMin{\n int N, logN;\n T *sum, *mn;\n int *mnind;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n \n sum = new T[2*i];\n mn = new T[2*i];\n mnind = new int[2*i];\n\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n\n walloc1d(&sum, 2i, mem);\n walloc1d(&mn, 2i, mem);\n walloc1d(&mnind, 2i, mem);\n\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] sum;\n delete [] mn;\n delete [] mnind;\n }\n\n T& operator[](int i){\n return sum[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) sum[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n rep(i,N) mn[N+i] = sum[N+i], mnind[N+i] = i;\n for(i=N-1;i;i--){\n sum[i] = sum[2*i] + sum[2*i+1];\n if(mn[2*i] <= mn[2*i+1]){\n mn[i] = mn[2*i];\n mnind[i] = mnind[2*i];\n } else {\n mn[i] = mn[2*i+1];\n mnind[i] = mnind[2*i+1];\n }\n }\n }\n \n inline void build(int a){\n while(a > 1){\n a /= 2;\n sum[a] = sum[a*2] + sum[a*2+1];\n if(mn[a*2] <= mn[a*2+1]){\n mn[a] = mn[a*2];\n mnind[a] = mnind[a*2];\n } else {\n mn[a] = mn[a*2+1];\n mnind[a] = mnind[a*2+1];\n }\n }\n }\n \n inline void change(int a, T val){\n sum[a+N] = mn[a+N] = val;\n build(a+N);\n }\n \n inline void add(int a, T val){\n sum[a+N] = (mn[a+N] += val);\n build(a+N);\n }\n \n inline pair<T,int> getMin(int a, int b){\n pair<T,int> res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, make_pair(mn[a], mnind[a]));\n } else {\n res = make_pair(mn[a], mnind[a]);\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(make_pair(mn[b], mnind[b]), tmp);\n } else {\n tmp = make_pair(mn[b], mnind[b]);\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n\n inline T getMinVal(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, mn[a]);\n } else {\n res = mn[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(mn[b], tmp);\n } else {\n tmp = mn[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n \n inline int getMinInd(int a, int b){\n return getMin(a,b).second;\n }\n\n inline T getSum(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = res + sum[a];\n } else {\n res = sum[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = sum[b] + tmp;\n } else {\n tmp = sum[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = res + tmp;\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_Point_Prod"; string c = "template<class T>\nstruct segtree_Point_Prod{\n int N, logN;\n T *mul;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n mul = new T[2*i];\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n walloc1d(&mul, 2i, mem);\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] mul;\n }\n\n T& operator[](int i){\n return mul[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) mul[N+i] = 0;\n if(dobuild) build();\n }\n\n void build(void){\n int i;\n for(i=N-1;i;i--){\n mul[i] = mul[2*i] * mul[2*i+1];\n }\n }\n \n inline void build(int a){\n while(a > 1){\n a /= 2;\n mul[a] = mul[a*2] * mul[a*2+1];\n }\n }\n \n inline void change(int a, T val){\n mul[a+N] = val;\n build(a+N);\n }\n \n inline void add(int a, T val){\n mul[a+N] += val;\n build(a+N);\n }\n \n inline T getProd(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = res * mul[a];\n } else {\n res = mul[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = mul[b] * tmp;\n } else {\n tmp = mul[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = res * tmp;\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_Point_Minval2"; string c = "template<class T>\nstruct segtree_Point_Minval2{\n int N, logN;\n T *mn, *mn2;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n \n mn = new T[2*i];\n mn2 = new T[2*i];\n\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n\n walloc1d(&mn, 2i, mem);\n walloc1d(&mn2, 2i, mem);\n\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] mn;\n delete [] mn2;\n }\n\n T& operator[](int i){\n return mn[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) mn[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n rep(i,N) mn2[N+i] = numeric_limits<T>::max();\n for(i=N-1;i;i--){\n if(mn[2i] <= mn[2i+1]){\n mn[i] = mn[2i];\n mn2[i] = min(mn2[2i], mn[2i+1]);\n } else {\n mn[i] = mn[2i+1];\n mn2[i] = min(mn[2i], mn2[2i+1]);\n }\n }\n }\n \n inline void build(int a){\n while(a > 1){\n a /= 2;\n if(mn[2a] <= mn[2a+1]){\n mn[a] = mn[2a];\n mn2[a] = min(mn2[2a], mn[2a+1]);\n } else {\n mn[a] = mn[2a+1];\n mn2[a] = min(mn[2a], mn2[2a+1]);\n }\n }\n }\n \n inline void change(int a, T val){\n mn[a+N] = val;\n build(a+N);\n }\n \n inline void add(int a, T val){\n mn[a+N] += val;\n build(a+N);\n }\n \n inline pair<T,T> getMinVal2(int a, int b){\n T res1, res2;\n\n a += N;\n b += N;\n\n res1 = res2 = numeric_limits<T>::max();\n while(a < b){\n if(a%2){\n res2 <?= mn[a];\n sortE(res1, res2);\n res2 <?= mn2[a];\n a++;\n }\n if(b%2){\n b--;\n res2 <?= mn[b];\n sortE(res1, res2);\n res2 <?= mn2[b];\n }\n a /= 2;\n b /= 2;\n }\n return make_pair(res1, res2);\n }\n\n inline T getMinVal(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n\n a += N;\n b += N;\n \n while(a < b){\n if(a%2){\n if(fga){\n res = min(res, mn[a]);\n } else {\n res = mn[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = min(mn[b], tmp);\n } else {\n tmp = mn[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = min(res, tmp);\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"chmin"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "segtree_ChangeAdd_Sum"; string c = "template<class T>\nstruct segtree_ChangeAdd_Sum{\n int N, logN;\n T *sum;\n\n T *fixval; char *fixed;\n T *addval;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n\n sum = new T[2*i];\n fixval = new T[i];\n addval = new T[i];\n fixed = new char[i];\n\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n\n walloc1d(&sum, 2i, mem);\n walloc1d(&fixval, i, mem);\n walloc1d(&addval, i, mem);\n walloc1d(&fixed, i, mem);\n\n if(once) setN(maxN);\n }\n\n void free(void){\n delete [] sum;\n delete [] fixval;\n delete [] addval;\n delete [] fixed;\n }\n\n T& operator[](int i){\n return sum[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) sum[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n for(i=N-1;i;i--){\n sum[i] = sum[2*i] + sum[2*i+1];\n }\n REP(i,1,N) fixed[i] = 0;\n REP(i,1,N) addval[i] = 0;\n }\n \n inline void push_one(int a, int sz, int st){\n if(fixed[a]){\n if(sz > 1){\n fixed[a*2] = fixed[a*2+1] = 1;\n fixval[a*2] = fixval[a*2+1] = fixval[a];\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n } else {\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n }\n fixed[a] = 0;\n addval[a] = 0;\n return;\n }\n if(addval[a] != 0){\n if(sz > 1){\n if(fixed[a*2]) fixval[a*2] += addval[a];\n else addval[a*2] += addval[a];\n if(fixed[a*2+1]) fixval[a*2+1] += addval[a];\n else addval[a*2+1] += addval[a];\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n } else {\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n }\n addval[a] = 0;\n return;\n }\n }\n \n inline void push(int a){\n int i, aa = a - N, nd, sz, st;\n for(i=logN;i;i--){\n nd = a>>i;\n sz = 1<<(i-1);\n st = 2 * sz * (aa>>i);\n push_one(nd, sz, st);\n }\n }\n \n inline void build(int a){\n int sz = 1, st = a - N;\n while(a > 1){\n if(a%2) st += sz;\n a /= 2;\n sz *= 2;\n if(fixed[a]){\n sum[a] = sz * fixval[a];\n } else {\n sum[a] = sum[a*2] + sum[a*2+1];\n if(addval[a] != 0){\n sum[a] += sz * addval[a];\n }\n }\n }\n }\n \n inline void change(int a, int b, T val){\n int sz = 1, aa, bb, st_a = a, st_b = b;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] = val;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n sum[b] = val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n fixed[a]=1, fixval[a]=val;\n sum[a] = sz * val;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n fixed[b]=1, fixval[b]=val;\n sum[b] = sz * val;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline void add(int a, int b, T val){\n int sz = 1, aa, bb;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] += val;\n a++;\n }\n if(b%2){\n b--;\n sum[b] += val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n if(fixed[a]) fixval[a] += val; else addval[a] += val;\n sum[a] += sz * val;\n a++;\n }\n if(b%2){\n b--;\n if(fixed[b]) fixval[b] += val; else addval[b] += val;\n sum[b] += sz * val;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline T getSum(int a, int b){\n T res, tmp;\n int fga = 0, fgb = 0;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n while(a < b){\n if(a%2){\n if(fga){\n res = res + sum[a];\n } else {\n res = sum[a];\n fga = 1;\n }\n a++;\n }\n if(b%2){\n b--;\n if(fgb){\n tmp = sum[b] + tmp;\n } else {\n tmp = sum[b];\n fgb = 1;\n }\n }\n a /= 2;\n b /= 2;\n }\n if(fga==1 && fgb==0) return res;\n if(fga==0 && fgb==1) return tmp;\n if(fga==1 && fgb==1){\n res = res + tmp;\n return res;\n }\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "wAdjEdge1"; string c = "template<class S>\nvoid wAdjEdge_L(const int N, const int M, const int *A, const S *B, int **res_sz, S ***res_B, void **mem = &wmem){\n int i, j, k;\n walloc1d(res_sz, N, mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M) (*res_sz)[A[i]]++;\n walloc1d(res_B, N, mem);\n rep(i,N) walloc1d(&((*res_B)[i]), (*res_sz)[i], mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M) (*res_B)[A[i]][(*res_sz)[A[i]]++] = B[i];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "wAdjEdge2"; string c = "template<class S, class T>\nvoid wAdjEdge_L(const int N, const int M, const int *A, const S *B, const T *C, int **res_sz, S ***res_B, T ***res_C, void **mem = &wmem){\n int i, j, k;\n walloc1d(res_sz, N, mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M) (*res_sz)[A[i]]++;\n walloc1d(res_B, N, mem);\n rep(i,N) walloc1d(&((*res_B)[i]), (*res_sz)[i], mem);\n walloc1d(res_C, N, mem);\n rep(i,N) walloc1d(&((*res_C)[i]), (*res_sz)[i], mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M){\n (*res_B)[A[i]][(*res_sz)[A[i]]] = B[i];\n (*res_C)[A[i]][(*res_sz)[A[i]]] = C[i];\n (*res_sz)[A[i]]++;\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "wAdjEdge3"; string c = "template<class S, class T, class U>\nvoid wAdjEdge_L(const int N, const int M, const int *A, const S *B, const T *C, const U *D, int **res_sz, S ***res_B, T ***res_C, U ***res_D, void **mem = &wmem){\n int i, j, k;\n walloc1d(res_sz, N, mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M) (*res_sz)[A[i]]++;\n walloc1d(res_B, N, mem);\n rep(i,N) walloc1d(&((*res_B)[i]), (*res_sz)[i], mem);\n walloc1d(res_C, N, mem);\n rep(i,N) walloc1d(&((*res_C)[i]), (*res_sz)[i], mem);\n walloc1d(res_D, N, mem);\n rep(i,N) walloc1d(&((*res_D)[i]), (*res_sz)[i], mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M){\n (*res_B)[A[i]][(*res_sz)[A[i]]] = B[i];\n (*res_C)[A[i]][(*res_sz)[A[i]]] = C[i];\n (*res_D)[A[i]][(*res_sz)[A[i]]] = D[i];\n (*res_sz)[A[i]]++;\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "wAdjEdge4"; string c = "template<class S, class T, class U, class V>\nvoid wAdjEdge_L(const int N, const int M, int *A, const S *B, const T *C, const U *D, const V *E, int **res_sz, S ***res_B, T ***res_C, U ***res_D, V ***res_E, void **mem = &wmem){\n int i, j, k;\n walloc1d(res_sz, N, mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M) (*res_sz)[A[i]]++;\n walloc1d(res_B, N, mem);\n rep(i,M) walloc1d(&((*res_B)[i]), (*res_sz)[i], mem);\n walloc1d(res_C, N, mem);\n rep(i,M) walloc1d(&((*res_C)[i]), (*res_sz)[i], mem);\n walloc1d(res_D, N, mem);\n rep(i,M) walloc1d(&((*res_D)[i]), (*res_sz)[i], mem);\n walloc1d(res_E, N, mem);\n rep(i,M) walloc1d(&((*res_E)[i]), (*res_sz)[i], mem);\n rep(i,N) (*res_sz)[i] = 0;\n rep(i,M){\n (*res_B)[A[i]][(*res_sz)[A[i]]] = B[i];\n (*res_C)[A[i]][(*res_sz)[A[i]]] = C[i];\n (*res_D)[A[i]][(*res_sz)[A[i]]] = D[i];\n (*res_E)[A[i]][(*res_sz)[A[i]]] = E[i];\n (*res_sz)[A[i]]++;\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "graph"; string c = "struct graph{\n int N, *es, **edge;\n"; string p = "first"; vector<string> d; d.push_back((string)"graph_end"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "graph_setEdge"; string c = " void setEdge(int N__, int M, int A[], int B[], void **mem = &wmem){\n int i;\n N = N__;\n\n walloc1d(&es, N, mem);\n walloc1d(&edge, N, mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++, es[B[i]]++;\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i], edge[B[i]][es[B[i]]++] = A[i];\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_setDirectEdge"; string c = " void setDirectEdge(int N__, int M, int A[], int B[], void **mem = &wmem){\n int i;\n N = N__;\n\n walloc1d(&es, N, mem);\n walloc1d(&edge, N, mem);\n walloc1d(&edge[0], M, mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++;\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i];\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_setEdgeRootedTree"; string c = " void setEdgeRootedTree(int N__, int M, int A[], int B[], int root=0, int reorder=0, int cnv[] = NULL, void **mem = &wmem){\n int i, j, k;\n int *dist, *q, qs, qe, *ind;\n void *tmem;\n N = N__;\n\n tmem = ((char*)(*mem)) + (sizeof(int) * N + 15) + (sizeof(int*) * N + 15) + (sizeof(int) * M + 15 * N);\n\n walloc1d(&es, N, mem);\n walloc1d(&edge, N, mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++, es[B[i]]++;\n rep(i,N) walloc1d(&edge[i], es[i], &tmem);\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i], edge[B[i]][es[B[i]]++] = A[i];\n\n walloc1d(&dist, N, &tmem);\n walloc1d(&q, N, &tmem);\n walloc1d(&ind, N, &tmem);\n if(cnv==NULL) walloc1d(&cnv, N, &tmem);\n\n rep(i,N) dist[i] = -1;\n dist[root] = 0;\n qs = qe = 0;\n q[qe++] = root;\n while(qs < qe){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(dist[k]==-1) dist[k] = dist[i] + 1, q[qe++] = k;\n }\n }\n\n if(reorder == 0){\n rep(i,N) cnv[i] = i;\n rep(i,N) ind[i] = i;\n } else {\n rep(i,N) cnv[i] = q[i];\n rep(i,N) ind[cnv[i]] = i;\n }\n\n rep(i,N) es[i] = 0;\n rep(i,M){\n j = A[i];\n k = B[i];\n if(dist[j] > dist[k]) swap(j, k);\n es[ind[j]]++;\n }\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n rep(i,N) es[i] = 0;\n rep(i,M){\n j = A[i];\n k = B[i];\n if(dist[j] > dist[k]) swap(j, k);\n j = ind[j];\n k = ind[k];\n edge[j][es[j]++] = k;\n }\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_reverse"; string c = " graph reverse(void **mem = &wmem){\n int i, j, k;\n graph g;\n\n g.N = N;\n walloc1d(&g.es, N, mem);\n walloc1d(&g.edge, N, mem);\n\n rep(i,N) g.es[i] = 0;\n rep(i,N) rep(j,es[i]) g.es[edge[i][j]]++;\n rep(i,N) walloc1d(&g.edge[i], g.es[i]);\n\n rep(i,N) g.es[i] = 0;\n rep(i,N) rep(j,es[i]){\n k = edge[i][j];\n g.edge[k][g.es[k]++] = i;\n }\n\n return g;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_reduce"; string c = " graph reduce(int tn, int ind[], int self_e = 0, int dep_e = 0, void **mem = &wmem){\n int i, j, k, M = 0;\n int x, y;\n graph g;\n void *tmem;\n pair<int,int> *A;\n\n rep(i,N) M += es[i];\n tmem = ((char*)(*mem)) + sizeof(int**) * N + sizeof(int*) * N + sizeof(int) * M + 16 * (N+2);\n walloc1d(&A, M, &tmem);\n\n M = 0;\n rep(i,N){\n x = ind[i];\n if(x < 0) continue;\n rep(j,es[i]){\n y = ind[edge[i][j]];\n if(y < 0) continue;\n if(self_e==0 && x==y) continue;\n A[M++] = make_pair(x, y);\n }\n }\n\n if(dep_e==0){\n sort(A, A+M);\n k = 0;\n rep(i,M){\n if(k && A[k-1]==A[i]) continue;\n A[k++] = A[i];\n }\n M = k;\n }\n\n g.N = tn;\n walloc1d(&g.es, tn, mem);\n walloc1d(&g.edge, tn, mem);\n\n rep(i,tn) g.es[i] = 0;\n rep(i,M) g.es[A[i].first]++;\n\n rep(i,tn) walloc1d(&g.edge[i], g.es[i], mem);\n\n rep(i,tn) g.es[i] = 0;\n rep(i,M){\n j = A[i].first;\n k = A[i].second;\n g.edge[j][g.es[j]++] = k;\n }\n return g;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_getDist"; string c = " void getDist(int root, int res[], void *mem = wmem){\n int i,j,k,*q,s,z;\n walloc1d(&q, N, &mem);\n rep(i,N)res[i]=-1;\n res[root]=0;\n s=0;\n z=1;\n q[0]=root;\n while(z){\n i=q[s++];\n z--;\n rep(j,es[i]){\n k=edge[i][j];\n if(res[k]>=0)continue;\n res[k]=res[i]+1;\n q[s+z++]=k;\n }\n }\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_cntShortest"; string c = " template<class S> void cntShortest(int root, int dist[], S cnt[], void *mem = wmem){\n int i,j,k,*q,s,z;\n walloc1d(&q, N, &mem);\n rep(i,N)dist[i]=-1;\n rep(i,N)cnt[i]=0;\n dist[root]=0;\n cnt[root]=1;\n s=0;\n z=1;\n q[0]=root;\n while(z){\n i=q[s++];\n z--;\n rep(j,es[i]){\n k=edge[i][j];\n if(dist[k]==-1) dist[k] = dist[i] + 1, cnt[k] = 0, q[s+z++] = k;\n if(dist[k]==dist[i]+1) cnt[k] += cnt[i];\n }\n }\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_scc"; string c = " inline int sccDFS(int num[], int st, int mx){\n int i,j;\n num[st]=-2;\n rep(i,es[st]) {\n j=edge[st][i]; if(num[j]==-1) mx=sccDFS(num,j,mx);\n }\n num[st]=mx; return mx+1;\n }\n \n int scc(int res[], void *mem = wmem){\n int i, j, k, ret=0;\n graph r;\n int *st, st_size, *num, *nrv;\n \n r = reverse(&mem);\n walloc1d(&st, N, &mem);\n walloc1d(&num, N, &mem);\n walloc1d(&nrv, N, &mem);\n \n rep(i,N) res[i] = num[i] = -1;\n k = 0;\n rep(i,N) if(num[i]==-1) k = sccDFS(num,i,k);\n rep(i,N) nrv[num[i]] = i;\n \n for(k=N-1;k>=0;k--) {\n i=nrv[k]; if(res[i]>=0)continue;\n res[i]=ret; st_size=0; st[st_size++]=i;\n while(st_size){\n i=st[--st_size];\n rep(j,r.es[i])\n if(res[r.edge[i][j]]==-1) res[r.edge[i][j]]=ret, st[st_size++]=r.edge[i][j];\n }\n ret++;\n }\n \n return ret;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"graph_reverse"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_bcc"; string c = " inline void bccDFS(int v, int u, int *res, int *rt, int &rts, int *S, int &Ss, int *inS, int *num, int &tm){\n int i, k;\n \n num[v] = ++tm;\n S[Ss++] = v; inS[v] = 1;\n rt[rts++] = v;\n rep(i, es[v]){\n int w = edge[v][i];\n if(!num[w]){\n bccDFS(w, v, res, rt, rts, S, Ss, inS, num, tm);\n } else if(u != w && inS[w]){\n while(num[rt[rts-1]] > num[w]) rts--;\n }\n }\n \n if(v == rt[rts-1]){\n k = S[Ss-1];\n for(;;){\n int w = S[--Ss];\n inS[w] = 0;\n res[w] = k;\n if(v==w) break;\n }\n rts--;\n }\n }\n\n int bcc(int res[], void *mem=wmem){\n int i, k;\n int *rt, *S, *num, *inS;\n pair<int,int> *arr;\n int rts = 0, Ss = 0, tm = 0;\n\n walloc1d(&num, N, &mem);\n walloc1d(&rt, N, &mem);\n walloc1d(&S, N, &mem);\n walloc1d(&inS, N, &mem);\n \n memset(num, 0, sizeof(int)*N);\n memset(inS, 0, sizeof(int)*N);\n rep(i,N) if(!num[i]) bccDFS(i, N, res, rt, rts, S, Ss, inS, num, tm);\n \n arr = (pair<int,int>*)mem;\n rep(i,N) arr[i].first = res[i], arr[i].second = i;\n sort(arr, arr+N);\n k = 0;\n rep(i,N){\n if(i && arr[i].first != arr[i-1].first) k++;\n res[arr[i].second] = k;\n }\n return k+1;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_articulation"; string c = " void articulationDFS(int n, int b, int &k, int od[], int lw[], int vs[], int &ress, int res[]){\n int i, j, a = 0, c = 0;\n vs[n] = 1;\n lw[n] = od[n] = k++;\n rep(i,es[n]){\n j = edge[n][i];\n if(j==b) continue;\n \n if(!vs[j]){\n c++;\n articulationDFS(j, n, k, od, lw, vs, ress, res);\n lw[n] <?= lw[j];\n if(b != -1 && od[n] <= lw[j]) a = 1;\n } else {\n lw[n] <?= od[j];\n }\n }\n if(b == -1 && c >= 2) a = 1;\n if(a) res[ress++] = n;\n }\n \n int articulation(int res[], void *mem=wmem){\n int i, k = 0, ress = 0;\n int *od, *lw, *vs;\n walloc1d(&od, N, &mem);\n walloc1d(&lw, N, &mem);\n walloc1d(&vs, N, &mem);\n rep(i,N) vs[i] = 0;\n rep(i,N) if(!vs[i]) articulationDFS(i, -1, k, od, lw, vs, ress, res);\n return ress;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_shortestPath"; string c = " int shortestPath(const int s, const int t, int res[], void *mem=wmem){\n int i, j, k;\n int *q, qs = 0, qe = 0, *b;\n\n walloc1d(&b, N, &mem);\n walloc1d(&q, N, &mem);\n\n rep(i,N) b[i] = -1;\n b[s] = -2;\n q[qe++] = s;\n while(qe > qs){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(b[k]!=-1) continue;\n b[k] = i;\n q[qe++] = k;\n }\n if(b[t]!=-1) break;\n }\n if(b[t]==-1) return -1;\n\n k = 0;\n res[k] = i = t;\n while(i != s) res[++k] = (i = b[i]);\n\n std::reverse(res, res+k+1);\n return k;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_TopologicalSort"; string c = " int TopologicalSort(int res[], void *mem=wmem){\n int i, j, k, rs;\n int *deg, *q, qs = 0, qe = 0;\n\n walloc1d(°, N, &mem);\n walloc1d(&q, N, &mem);\n\n rs = 0;\n\n rep(i,N) deg[i] = 0;\n rep(i,N) rep(j,es[i]) deg[edge[i][j]]++;\n rep(i,N) if(deg[i]==0) q[qe++] = i;\n\n while(qs < qe){\n i = q[qs++];\n res[rs++] = i;\n rep(j,es[i]){\n k = edge[i][j];\n deg[k]--;\n if(deg[k]==0) q[qe++] = k;\n }\n }\n\n if(rs==N) return 1;\n return 0;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_preorder"; string c = " int preorder(int res[], int root = 0, void *mem=wmem){\n int i, j, k, *st, sts, sz = 0;\n char *vis;\n walloc1d(&vis, N, &mem);\n walloc1d(&st, N, &mem);\n sts = 0;\n st[sts++] = root;\n rep(i,N) vis[i] = 0;\n vis[root] = 1;\n while(sts){\n i = st[--sts];\n res[sz++] = i;\n rep(j,es[i]){\n k = edge[i][j];\n if(vis[k]) continue;\n vis[k] = 1;\n st[sts++] = k;\n }\n }\n return sz;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_shortestCycle"; string c = " int shortestCycle(int res[] = NULL, void *mem=wmem){\n int i, j, k, r, sz, tp;\n int *q, qs, qe, *arr, *bk;\n\n if(res==NULL) walloc1d(&res, N+1, &mem);\n\n rep(i,N) rep(j,es[i]){\n k = edge[i][j];\n if(k==i){\n res[0] = res[1] = i;\n return 1;\n }\n }\n\n walloc1d(&arr, N, &mem);\n walloc1d(&bk, N, &mem);\n walloc1d(&q, N, &mem);\n sz = int_inf;\n rep(r,N){\n rep(i,N) arr[i] = -1;\n rep(i,N) bk[i] = -1;\n arr[r] = 0;\n qs = qe = 0;\n q[qe++] = r;\n tp = int_inf;\n while(qs < qe && tp == int_inf){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(k==r){\n bk[k] = i;\n tp = arr[i] + 1;\n break;\n }\n if(arr[k]==-1){\n bk[k] = i;\n arr[k] = arr[i] + 1;\n q[qe++] = k;\n continue;\n }\n }\n }\n if(sz > tp){\n sz = tp;\n res[tp] = r;\n k = r;\n for(;;){\n k = bk[k];\n res[arr[k]] = k;\n if(k==r) break;\n }\n }\n }\n \n if(sz==int_inf) sz = -1;\n return sz;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_shortestUndirectedCycle_length"; string c = " int shortestUndirectedCycle_length(void *mem=wmem){\n int i, j, k, r, res;\n int *arr, *q, qs, qe;\n\n rep(i,N) rep(j,es[i]) if(edge[i][j]==i) return 1;\n\n walloc1d(&arr, N, &mem);\n rep(i,N) arr[i] = -1;\n rep(i,N) rep(j,es[i]){\n k = edge[i][j];\n if(arr[k]==i) return 2;\n arr[k] = i;\n }\n\n walloc1d(&q, N, &mem);\n res = int_inf;\n rep(r,N){\n rep(i,N) arr[i] = -1;\n arr[r] = 0;\n qs = qe = 0;\n q[qe++] = r;\n while(qs < qe){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(arr[k]==-1){\n arr[k] = arr[i] + 1;\n q[qe++] = k;\n continue;\n }\n if(arr[k]==arr[i]) res <?= 2 arr[i] + 1;\n if(arr[k]==arr[i]+1) res <?= 2 arr[k];\n }\n }\n }\n \n if(res==int_inf) res = -1;\n return res;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_maxIndependenceSet"; string c = " int maxIndependenceSet(int res[] = NULL, void *mem = wmem, int lim = -1, int skip = 0){\n int i, j, k, m, x, y, fg;\n int ress;\n int *deg, *used, *ind, *rev, *val;\n ll *pr;\n graph g;\n unionFind uf;\n void *tmem;\n\n \n if(N == 0) return 0;\n if(N == 1) res[0] = 0, return 1;\n if(N <= lim) return 0;\n\n if(res==NULL) walloc1d(&res, N, &mem);\n walloc1d(°, N, &mem);\n walloc1d(&used, N, &mem);\n walloc1d(&ind, N, &mem);\n walloc1d(&rev, N, &mem);\n walloc1d(&val, N, &mem);\n walloc1d(&pr, N, &mem);\n\n rep(i,N) deg[i] = es[i];\n rep(i,N) used[i] = 0;\n ress = 0;\n\n if(!(skip&1)){\n do{\n fg = 0;\n rep(i,N) if(!used[i] && deg[i] <= 1){\n fg = 1;\n res[ress++] = i;\n used[i] = 1;\n if(deg[i] == 0) continue;\n rep(j,es[i]){\n k = edge[i][j];\n if(!used[k]) break;\n }\n deg[k]--;\n used[k] = 1;\n rep(j,es[k]){\n m = edge[k][j];\n if(!used[m]) deg[m]--;\n }\n }\n \n rep(i,N) if(!used[i] && deg[i]==2){\n m = 0;\n rep(j,es[i]){\n k = edge[i][j];\n if(used[k]) continue;\n if(m==0) x = k, m++;\n else y = k, m++;\n }\n rep(j,es[x]) if(edge[x][j] == y) break;\n if(j < es[x]){\n fg = 1;\n used[i] = used[x] = used[y] = 1;\n res[ress++] = i;\n rep(j,es[x]){\n m = edge[x][j];\n if(!used[m]) deg[m]--;\n }\n rep(j,es[y]){\n m = edge[y][j];\n if(!used[m]) deg[m]--;\n }\n }\n }\n }while(fg);\n }\n\n if(ress){\n k = 0;\n rep(i,N){\n if(used[i]) ind[i] = -1, continue;\n ind[i] = k;\n rev[k] = i;\n k++;\n }\n g = reduce(k, ind, 1, 1, &mem);\n m = g.maxIndependenceSet(res+ress, mem, lim - ress, 1);\n rep(i,m) res[ress+i] = rev[res[ress+i]];\n ress += m;\n sort(res, res+ress);\n return ress;\n }\n\n if(N-2 <= lim) return 0;\n\n if(lim >= 1){\n rep(i,N) deg[i] = es[i];\n sort(deg, deg+N);\n int ss = 0;\n rep(k,N) ss += es[k];\n j = 0;\n rep(i,N){\n j += deg[i];\n if(2*j > ss) break;\n }\n if(i <= lim) return 0;\n \n rep(i,N) if(deg[i] > N-i-1) break;\n if(i <= lim) return 0;\n }\n \n if(!(skip&2)){\n k = 0;\n uf.walloc(N, &mem);\n uf.init(N);\n rep(i,N) rep(j,es[i]) k += uf(i,edge[i][j]);\n if(k < N-1){\n rep(i,N) val[i] = i;\n rep(i,N) deg[i] = 0;\n rep(i,N) deg[uf(i)]++;\n sortA(N, deg, val);\n y = N;\n rrep(x,N) if(deg[x]){\n k = 0;\n rep(i,N){\n if(uf(i)!=x) ind[i] = -1, continue;\n ind[i] = k;\n rev[k] = i;\n k++;\n }\n y -= k;\n tmem = mem;\n g = reduce(k, ind, 1, 1, &mem);\n m = g.maxIndependenceSet(res+ress, mem, max(-1, lim-(y-2x)-ress), 3);\n mem = tmem;\n rep(i,m) res[ress+i] = rev[res[ress+i]];\n ress += m;\n }\n sort(res,res+ress);\n return ress;\n }\n }\n\n k = articulation(ind);\n rep(i,N) pr[i] = 0;\n rep(i,k) pr[ind[i]] += (1LL<<40);\n rep(i,N) rep(j,es[i]) pr[i] += (1LL<<20) - es[edge[i][j]];\n x = argmax(pr(N));\n\n k = 0;\n rep(i,N){\n if(i == x) ind[i] = -1, continue;\n ind[i] = k;\n rev[k] = i;\n k++;\n }\n tmem = mem;\n g = reduce(k, ind, 1, 1, &mem);\n ress = g.maxIndependenceSet(res, mem, lim);\n mem = tmem;\n rep(i,ress) res[i] = rev[res[i]];\n \n k = 0;\n used[x] = 1;\n rep(j,es[x]) used[edge[x][j]] = 1;\n rep(i,N){\n if(used[i]) ind[i] = -1, continue;\n ind[i] = k;\n rev[k] = i;\n k++;\n }\n g = reduce(k, ind, 1, 1, &mem);\n m = g.maxIndependenceSet(deg, mem, max(ress, lim)-1);\n if(m+1 > ress){\n rep(i,m) res[i] = rev[deg[i]];\n res[m++] = x;\n ress = m;\n }\n \n sort(res,res+ress);\n return ress;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"graph_reduce"); d.push_back((string)"graph_articulation"); d.push_back((string)"max_L"); d.push_back((string)"sortA_2"); d.push_back((string)"unionFind"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_countIndependenceSet"; string c = " ll countIndependenceSet(void *mem = wmem, int skip = 0){\n int i, j, k, x;\n ll res;\n int *deg, *ind;\n ll *pr;\n graph g;\n unionFind uf;\n void *tmem;\n\n if(N == 0) return 1;\n if(N == 1) return 2;\n\n walloc1d(°, N, &mem);\n walloc1d(&ind, N, &mem);\n walloc1d(&pr, N, &mem);\n\n if(!skip){\n k = 0;\n uf.walloc(N, &mem);\n uf.init(N);\n rep(i,N) rep(j,es[i]) k += uf(i,edge[i][j]);\n if(k < N-1){\n res = 1;\n rep(i,N) deg[i] = 0;\n rep(i,N) deg[uf(i)]++;\n rep(x,N) if(deg[x]){\n k = 0;\n rep(i,N){\n if(uf(i)!=x) ind[i] = -1, continue;\n ind[i] = k++;\n }\n tmem = mem;\n g = reduce(k, ind, 1, 1, &mem);\n res *= g.countIndependenceSet(mem, 1);\n mem = tmem;\n }\n return res;\n }\n }\n\n k = articulation(ind);\n rep(i,N) pr[i] = 0;\n rep(i,k) pr[ind[i]] += (1LL<<40);\n rep(i,N) rep(j,es[i]) pr[i] += (1LL<<20) - es[edge[i][j]];\n x = argmax(pr(N));\n\n res = 0;\n \n k = 0;\n rep(i,N){\n if(i == x) ind[i] = -1, continue;\n ind[i] = k++;\n }\n tmem = mem;\n g = reduce(k, ind, 1, 1, &mem);\n res += g.countIndependenceSet(mem);\n mem = tmem;\n\n k = 0;\n rep(i,N) deg[i] = 0;\n deg[x] = 1;\n rep(j,es[x]) deg[edge[x][j]] = 1;\n rep(i,N){\n if(deg[i]) ind[i] = -1, continue;\n ind[i] = k++;\n }\n g = reduce(k, ind, 1, 1, &mem);\n res += g.countIndependenceSet(mem);\n\n return res;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"graph_reduce"); d.push_back((string)"graph_articulation"); d.push_back((string)"max_L"); d.push_back((string)"sortA_2"); d.push_back((string)"unionFind"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_bipartite"; string c = " int bipartite(int res[] = NULL, void *mem = wmem){\n int i, j, k;\n int *st, sts;\n\n if(res==NULL) walloc1d(&res, N, &mem);\n walloc1d(&st, N, &mem);\n\n rep(i,N) res[i] = -1;\n rep(i,N) if(res[i]==-1){\n res[i] = 0;\n sts = 0;\n st[sts++] = i;\n while(sts){\n i = st[--sts];\n rep(j,es[i]){\n k = edge[i][j];\n if(res[k]==-1){\n res[k] = 1 - res[i];\n st[sts++] = k;\n }\n if(res[i] + res[k] != 1) return 0;\n }\n }\n }\n return 1;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "graph_end"; string c = "};\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "graph"; } { string n = "wgraph"; string c = "template<class T>\nstruct wgraph{\n int N, *es, **edge;\n T **cost;\n graph g;\n"; string p = "first"; vector<string> d; d.push_back((string)"graph"); d.push_back((string)"wgraph_end"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "wgraph_setEdge"; string c = " void setEdge(int N__, int M, int A[], int B[], T C[], void **mem = &wmem){\n int i;\n N = N__;\n\n walloc1d(&es, N, mem);\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++, es[B[i]]++;\n walloc1d(&edge, N, mem);\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n walloc1d(&cost, N, mem);\n rep(i,N) walloc1d(&cost[i], es[i], mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M){\n edge[A[i]][es[A[i]]] = B[i];\n edge[B[i]][es[B[i]]] = A[i];\n cost[A[i]][es[A[i]]++] = C[i];\n cost[B[i]][es[B[i]]++] = C[i];\n }\n\n g.N = N;\n g.es = es;\n g.edge = edge;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_setDirectEdge"; string c = " void setDirectEdge(int N__, int M, int A[], int B[], T C[], void **mem = &wmem){\n int i;\n N = N__;\n\n walloc1d(&es, N, mem);\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++;\n walloc1d(&edge, N, mem);\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n walloc1d(&cost, N, mem);\n rep(i,N) walloc1d(&cost[i], es[i], mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M){\n edge[A[i]][es[A[i]]] = B[i];\n cost[A[i]][es[A[i]]++] = C[i];\n }\n\n g.N = N;\n g.es = es;\n g.edge = edge;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_setEdgeRootedTree"; string c = " void setEdgeRootedTree(int N__, int M, int A[], int B[], T C[], int root=0, int reorder=0, int cnv[] = NULL, void **mem = &wmem){\n int i, j, k;\n int *dist, *q, qs, qe, *ind;\n void *tmem;\n N = N__;\n\n tmem = ((char*)(*mem)) + (sizeof(int) * N + 15) + (sizeof(int*) * N + 15) + (sizeof(int) * M + 15 * N) + (sizeof(T*) * N + 15) + (sizeof(T) * M + 15 * N);\n\n walloc1d(&es, N, mem);\n walloc1d(&edge, N, mem);\n walloc1d(&cost, N, mem);\n\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++, es[B[i]]++;\n rep(i,N) walloc1d(&edge[i], es[i], &tmem);\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i], edge[B[i]][es[B[i]]++] = A[i];\n\n walloc1d(&dist, N, &tmem);\n walloc1d(&q, N, &tmem);\n walloc1d(&ind, N, &tmem);\n if(cnv==NULL) walloc1d(&cnv, N, &tmem);\n\n rep(i,N) dist[i] = -1;\n dist[root] = 0;\n qs = qe = 0;\n q[qe++] = root;\n while(qs < qe){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(dist[k]==-1) dist[k] = dist[i] + 1, q[qe++] = k;\n }\n }\n\n if(reorder == 0){\n rep(i,N) cnv[i] = i;\n rep(i,N) ind[i] = i;\n } else {\n rep(i,N) cnv[i] = q[i];\n rep(i,N) ind[cnv[i]] = i;\n }\n\n rep(i,N) es[i] = 0;\n rep(i,M){\n j = A[i];\n k = B[i];\n if(dist[j] > dist[k]) swap(j, k);\n es[ind[j]]++;\n }\n rep(i,N) walloc1d(&edge[i], es[i], mem);\n rep(i,N) walloc1d(&cost[i], es[i], mem);\n rep(i,N) es[i] = 0;\n rep(i,M){\n j = A[i];\n k = B[i];\n if(dist[j] > dist[k]) swap(j, k);\n j = ind[j];\n k = ind[k];\n edge[j][es[j]] = k;\n cost[j][es[j]] = C[i];\n es[j]++;\n }\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_getDist"; string c = " template<class S>\n void getDist(int root, S res[], S unreachable = -1, void *mem = wmem){\n int i, j;\n DijkstraHeap<S> hp;\n hp.walloc(N, &mem);\n hp.init(N);\n hp.change(root,0);\n while(hp.size){\n i = hp.pop();\n rep(j,es[i]) hp.change(edge[i][j], hp.val[i]+cost[i][j]);\n }\n rep(i,N) res[i] = (hp.visited[i] ? hp.val[i] : unreachable);\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"DijkstraHeap"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_getDistDense"; string c = " template<class S>\n void getDistDense(int root, S res[], S unreachable = -1, void *mem = wmem){\n int i, j, k;\n char *vis, *done;\n walloc1d(&vis, N, &mem);\n walloc1d(&done, N, &mem);\n rep(i,N) vis[i] = 0;\n rep(i,N) done[i] = 0;\n res[root] = 0;\n vis[root] = 1;\n\n for(;;){\n i = -1;\n rep(j,N) if(!done[j] && vis[j]){\n if(i==-1) i = j, continue;\n if(res[i] > res[j]) i = j;\n }\n if(i==-1) break;\n done[i] = 1;\n rep(j,es[i]){\n k = edge[i][j];\n if(vis[k]==0 || res[k] > res[i] + cost[i][j]){\n vis[k] = 1;\n res[k] = res[i] + cost[i][j];\n }\n }\n }\n\n rep(i,N) if(!vis[i]) res[i] = unreachable;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_getDistForest"; string c = " template<class S>\n void getDistForest(int root, S res[], S unreachable = -1, void *mem = wmem){\n int i,j,k,*q,s,z;\n char *r;\n walloc1d(&q,N,&mem);\n walloc1d(&r,N,&mem);\n rep(i,N)r[i]=0;\n res[root]=0; r[root]=1;\n s=0;\n z=1;\n q[0]=root;\n while(z){\n i=q[s++];\n z--;\n rep(j,es[i]){\n k=edge[i][j];\n if(r[k])continue;\n res[k]=res[i]+cost[i][j];\n r[k]=1;\n q[s+z++]=k;\n }\n }\n rep(i,N)if(!r[i])res[i]=unreachable;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_BellmanFord"; string c = " template<class S>\n void BellmanFord(int root, S res[], S unreachable = -1, S minusInf = -2, int step = -1, void *mem = wmem){\n int i, j, k, t;\n int *inf, *q, qs, qe;\n S *arr;\n\n walloc1d(&q, N, &mem);\n walloc1d(&inf, N, &mem);\n walloc1d(&arr, N, &mem);\n\n rep(i,N) inf[i] = 0;\n rep(i,N) res[i] = arr[i] = std::numeric_limits<S>::max();\n res[root] = arr[root] = 0;\n\n t = step;\n if(t==-1) t = N;\n rep(t){\n rep(i,N) if(res[i] != std::numeric_limits<S>::max()) rep(j,es[i]){\n arr[edge[i][j]] <?= res[i] + cost[i][j];\n }\n rep(i,N) res[i] = arr[i];\n }\n if(step != -1){\n rep(i,N) if(res[i]==std::numeric_limits<S>::max()) res[i] = unreachable;\n return;\n }\n\n rep(i,N) if(res[i] != std::numeric_limits<S>::max()) rep(j,es[i]){\n k = edge[i][j];\n if(arr[k] > res[i] + cost[i][j]) inf[k] = 1;\n }\n\n qs = qe = 0;\n rep(i,N) if(inf[i]) q[qe++] = i;\n while(qs < qe){\n i = q[qs++];\n rep(j,es[i]){\n k = edge[i][j];\n if(inf[k]==0){\n inf[k] = 1;\n q[qe++] = k;\n }\n }\n }\n\n rep(i,N) if(res[i]==std::numeric_limits<S>::max()) res[i] = unreachable;\n rep(i,N) if(inf[i]==1) res[i] = minusInf;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"chmin"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_MST_Prim_cost"; string c = " T MST_Prim_cost(void *mem = wmem){\n int i, j;\n T res = 0;\n DijkstraHeap<T> hp;\n hp.walloc(N, &mem);\n hp.init(N);\n hp.change(0,0);\n while(hp.size){\n i = hp.pop();\n res += hp.val[i];\n rep(j,es[i]) hp.change(edge[i][j], cost[i][j]);\n }\n return res;\n }\n\n int MST_Prim_cost(T &res, void *mem = wmem){\n int i, j, cnt = 0;\n res = 0;\n DijkstraHeap<T> hp;\n hp.walloc(N, &mem);\n hp.init(N);\n hp.change(0,0);\n while(hp.size){\n i = hp.pop();\n res += hp.val[i];\n cnt++;\n rep(j,es[i]) hp.change(edge[i][j], cost[i][j]);\n }\n if(cnt==N) return 1;\n return 0;\n }\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"DijkstraHeap"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "wgraph_end"; string c = "};\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; parent[n] = "wgraph"; } { string n = "HLD"; string c = "struct HLD{\n int N;\n int *es, **edge;\n\n int *group, *groupind;\n int groupNum, *groupSize, **groupNode, *groupUpNode, *groupDepth;\n\n void init(graph g, void **mem = &wmem){\n init(g.N, g.es, g.edge, mem);\n }\n \n void init(int N__, int *es__, int **edge__, void **mem = &wmem){\n int i, j, k, x, y, mx;\n int *q, q_st, q_ed, *sz;\n char *vis;\n void *tmpmem;\n\n N = N__;\n es = es__;\n edge = edge__;\n\n walloc1d(&group, N, mem);\n walloc1d(&groupind, N, mem);\n\n tmpmem = *mem;\n walloc1d(&q, N, &tmpmem);\n walloc1d(&sz, N, &tmpmem);\n walloc1d(&vis, N, &tmpmem);\n rep(i,N) vis[i] = 0;\n q_st = 0; q_ed = 1;\n q[0] = 0; vis[0] = 1;\n while(q_st < q_ed){\n i = q[q_st++];\n rep(j,es[i]){\n k = edge[i][j];\n if(!vis[k]) vis[k] = 1, q[q_ed++] = k;\n }\n }\n \n rep(i,N) sz[i] = 0;\n for(j=N-1;j>=0;j--){\n i = q[j];\n sz[i] = 1;\n rep(k,es[i]) sz[i] += sz[edge[i][k]];\n }\n\n rep(i,N) group[i] = -1;\n\n groupNum = 0;\n rep(j,N){\n i = q[j];\n if(group[i]>=0) continue;\n\n group[i] = groupNum++;\n groupind[i] = 0;\n for(;;){\n mx = -1;\n rep(k,es[i]){\n if(group[edge[i][k]] != -1) continue;\n if(mx==-1) mx = k;\n else if(sz[edge[i][k]] > sz[edge[i][mx]]) mx = k;\n }\n if(mx==-1) break;\n group[edge[i][mx]] = group[i];\n groupind[edge[i][mx]] = groupind[i]+1;\n i = edge[i][mx];\n }\n }\n\n walloc1d(&groupSize, groupNum, mem);\n walloc1d(&groupUpNode, groupNum, mem);\n walloc1d(&groupDepth, groupNum, mem);\n\n rep(i,groupNum) groupSize[i] = 0;\n rep(i,N) groupSize[group[i]]++;\n walloc1d(&groupNode, groupNum, mem);\n rep(i,groupNum) walloc1d(&groupNode[i], groupSize[i], mem);\n rep(i,N) groupNode[group[i]][groupind[i]] = i;\n\n rep(i,groupNum) groupDepth[i] = -1;\n groupUpNode[0] = -1;\n groupDepth[0] = 0;\n rep(x,groupNum) rep(y,groupSize[x]){\n i = groupNode[x][y];\n rep(j,es[i]){\n k = edge[i][j];\n if(x != group[k] && groupDepth[group[k]]==-1){\n groupUpNode[group[k]] = i;\n groupDepth[group[k]] = groupDepth[x] + 1;\n }\n }\n }\n }\n \n int lca(int x, int y){\n int x1, y1, x2, y2;\n x1 = group[x]; x2 = groupind[x];\n y1 = group[y]; y2 = groupind[y];\n while(groupDepth[x1] > groupDepth[y1]){\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n }\n while(groupDepth[x1] < groupDepth[y1]){\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n while(x1 != y1){\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n \n if(x2 <= y2) return x;\n return y;\n }\n\n int depth(int x){\n int x1, x2, res = 0;\n x1 = group[x];\n x2 = groupind[x];\n while(groupUpNode[x1] != -1){\n res += x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x];\n x2 = groupind[x];\n }\n return res + x2;\n }\n\n int dist(int x, int y){\n int x1, y1, x2, y2, res = 0;\n x1 = group[x]; x2 = groupind[x];\n y1 = group[y]; y2 = groupind[y];\n while(groupDepth[x1] > groupDepth[y1]){\n res += x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n }\n while(groupDepth[x1] < groupDepth[y1]){\n res += y2 + 1;\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n while(x1 != y1){\n res += x2 + y2 + 2;\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n\n if(x2 <= y2) return res + y2 - x2;\n return res + x2 - y2;\n }\n\n int up(int x){\n int x1 = group[x];\n int x2 = groupind[x];\n if(x2==0) return groupUpNode[x1];\n return groupNode[x1][x2-1];\n }\n\n int up(int x, int d){\n int x1 = group[x];\n int x2 = groupind[x];\n while(d > x2){\n if(groupUpNode[x1]==-1) return -1;\n d -= x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x];\n x2 = groupind[x];\n }\n return groupNode[x1][x2-d];\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"graph"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "HLD_fenwick"; string c = "template<class T>\nstruct HLD_fenwick{\n HLD *hld;\n fenwick<T> *fen;\n\n void init(HLD *hld__, void **mem = &wmem){\n int i, j;\n\n hld = hld__;\n walloc1d(&fen, hld->groupNum, mem);\n\n rep(i,hld->groupNum){\n fen[i].walloc(hld->groupSize[i], mem);\n fen[i].init(hld->groupSize[i]);\n }\n }\n\n inline void add(int u, T val){\n int ug, ui;\n ug = hld->group[u];\n ui = hld->groupind[u];\n fen[ug].add(ui, val);\n }\n\n inline T get(int u, int v){\n T res;\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n\n res = 0;\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n res += fen[ug].get(hld->groupind[u]);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n res += fen[ug].range(min(ui,vi), max(ui,vi));\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"graph"); d.push_back((string)"HLD"); d.push_back((string)"min_L"); d.push_back((string)"max_L"); d.push_back((string)"fenwick"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "HLD_segtree"; string c = "template<class T>\nstruct HLD_segtree{\n HLD *hld;\n segtree<T> *seg;\n\n void init(HLD *hld__, T initval[], void **mem = &wmem){\n int i, j;\n\n hld = hld__;\n walloc1d(&seg, hld->groupNum, mem);\n\n rep(i,hld->groupNum){\n seg[i].walloc(hld->groupSize[i], 0, mem);\n seg[i].setN(hld->groupSize[i], 0, 0);\n if(initval!=NULL) rep(j,hld->groupSize[i]) seg[i][j] = initval[ hld->groupNode[i][j] ];\n else rep(j,hld->groupSize[i]) seg[i][j] = 0;\n seg[i].build();\n }\n }\n\n inline void change(int u, int v, T val){\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n seg[ug].change(0, hld->groupind[u]+1, val);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n seg[ug].change(min(ui,vi), max(ui,vi)+1, val);\n }\n\n inline void add(int u, int v, T val){\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n seg[ug].add(0, hld->groupind[u]+1, val);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n seg[ug].add(min(ui,vi), max(ui,vi)+1, val);\n }\n\n inline pair<T,int> getMin(int u, int v){\n pair<T,int> res, tmp;\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n\n res.first = numeric_limits<T>::max();\n res.second = -1;\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n tmp = seg[ug].getMin(0, hld->groupind[u]+1);\n tmp.second = hld->groupNode[ug][tmp.second];\n res <?= tmp;\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n tmp = seg[ug].getMin(min(ui,vi), max(ui,vi)+1);\n tmp.second = hld->groupNode[ug][tmp.second];\n res <?= tmp;\n return res;\n }\n\n inline T getMinVal(int u, int v){\n return getMin(u,v).first;\n }\n\n inline int getMinInd(int u, int v){\n return getMin(u,v).second;\n }\n\n inline T getSum(int u, int v){\n T res;\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n\n res = 0;\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n res += seg[ug].getSum(0, hld->groupind[u]+1);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n res += seg[ug].getSum(min(ui,vi), max(ui,vi)+1);\n return res;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); d.push_back((string)"graph"); d.push_back((string)"HLD"); d.push_back((string)"min_L"); d.push_back((string)"max_L"); d.push_back((string)"segtree"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "maxflow"; string c = "template<class T, class S>\nstruct maxflow{\n int node, st, ed;\n int *es, *emem, **edge, **rev, *level, *qq;\n T **flow, eps;\n\n void malloc(int N){\n int i;\n es = (int*)std::malloc(N*sizeof(int));\n emem = (int*)std::malloc(N*sizeof(int));\n level = (int*)std::malloc(N*sizeof(int));\n qq = (int*)std::malloc(N*sizeof(int));\n edge = (int**)std::malloc(N*sizeof(int*));\n rev = (int**)std::malloc(N*sizeof(int*));\n flow = (T**)std::malloc(N*sizeof(T*));\n rep(i,N) emem[i] = 0, edge[i] = rev[i] = NULL, flow[i] = NULL;\n }\n\n void walloc(int N, void**mem = &wmem){\n int i;\n walloc1d(&es, N, mem);\n walloc1d(&emem, N, mem);\n walloc1d(&level, N, mem);\n walloc1d(&qq, N, mem);\n walloc1d(&edge, N, mem);\n walloc1d(&rev, N, mem);\n walloc1d(&flow, N, mem);\n (*mem) = (flow + N);\n }\n\n void levelize(void){\n int i, j, k, t;\n int q_st = 0, q_ed = 1;\n rep(i,node) level[i] = -1;\n level[st] = 0;\n qq[0] = st;\n while(q_st != q_ed){\n i = qq[q_st++];\n t = level[i] + 1;\n rep(j,es[i]) if(flow[i][j] > eps){\n k = edge[i][j];\n if(level[k]!=-1) continue;\n level[k] = t;\n qq[q_ed++] = k;\n if(k==ed) return;\n }\n }\n }\n\n S pushflow(int i, S lim){\n int j, k, ji;\n S s, t, res = 0;\n if(i==ed) return lim;\n rep(j,es[i]) if(flow[i][j] > eps){\n k = edge[i][j];\n if(level[k] != level[i]+1) continue;\n s = min(lim, (S)flow[i][j]);\n t = pushflow(k, s); if(!t) continue;\n res += t;\n lim -= t;\n ji = rev[i][j];\n flow[i][j] -= t; flow[k][ji] += t;\n if(!lim) break;\n }\n if(lim) level[i] = -1;\n return res;\n }\n\n S solve(int st_, int ed_){\n S res = 0;\n st = st_; ed = ed_;\n for(;;){\n levelize();\n if(level[ed] == -1) break;\n res += pushflow(st, numeric_limits<S>::max());\n }\n return res;\n }\n\n void init(int N){\n int i;\n node = N;\n rep(i,N) es[i] = 0;\n eps = (T)1e-9;\n }\n\n void memoryExpand(int i, int sz){\n if(sz <= emem[i]) return;\n sz = max(sz, max(3, emem[i]*2));\n emem[i]=sz;\n edge[i] = (int*)realloc(edge[i], sz*sizeof(int));\n rev[i] = (int*)realloc(rev[i], sz*sizeof(int));\n flow[i] = (T*)realloc(flow[i], sz*sizeof(T));\n }\n\n void addEdge(int n1, int n2, T f1, T f2 = 0){\n int s1 = es[n1]++, s2 = es[n2]++;\n if(s1 >= emem[n1]) memoryExpand(n1, es[n1]);\n if(s2 >= emem[n2]) memoryExpand(n2, es[n2]);\n edge[n1][s1]=n2; edge[n2][s2]=n1;\n flow[n1][s1]=f1; flow[n2][s2]=f2;\n rev[n1][s1]=s2; rev[n2][s2]=s1;\n }\n \n void addEdgeAdv(int n1, int n2, T f1, T f2 = 0){\n int s1 = es[n1]++, s2 = es[n2]++;\n edge[n1][s1]=n2; edge[n2][s2]=n1;\n flow[n1][s1]=f1; flow[n2][s2]=f2;\n rev[n1][s1]=s2; rev[n2][s2]=s1;\n }\n \n void setGraph(int N, int M, int n1[], int n2[], T f1[], T f2[]){\n int i;\n node = N;\n rep(i,N) es[i] = 0;\n rep(i,M) es[n1[i]]++, es[n2[i]]++;\n rep(i,N) memoryExpand(i, es[i]);\n rep(i,N) es[i] = 0;\n rep(i,M) addEdgeAdv(n1[i], n2[i], f1[i], f2[i]);\n eps = (T)1e-9;\n }\n\n void setGraph_w(int N, int M, int n1[], int n2[], T f1[], T f2[], void **mem = wmem){\n int i, j, k;\n node = N;\n rep(i,N) es[i] = emem[i] = 0;\n rep(i,M) es[n1[i]]++, es[n2[i]]++;\n \n edge[0] = (int*)(*mem);\n REP(i,1,N) edge[i] = edge[i-1] + es[i-1];\n rev[0] = edge[N-1] + es[N-1];\n REP(i,1,N) rev[i] = rev[i-1] + es[i-1];\n flow[0] = (T*)(rev[N-1] + es[N-1]);\n REP(i,1,N) flow[i] = flow[i-1] + es[i-1];\n *mem = (void*)(flow[N-1] + es[N-1]);\n \n rep(i,N) es[i] = 0;\n rep(i,M) addEdgeAdv(n1[i], n2[i], f1[i], f2[i]);\n eps = (T)1e-9;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"max_L"); d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "minCostFlow"; string c = "template<class FT, class CT>\nstruct minCostFlow {\n int node;\n int *es, *emem, **edge, **rev;\n FT **flow, eps;\n CT **cost;\n \n LHeap<CT> hp;\n char *reached;\n FT *cur_flow;\n CT *cur_cost;\n int *back_edge;\n\n void malloc(int N){\n int i;\n es = (int*)std::malloc(N*sizeof(int));\n emem = (int*)std::malloc(N*sizeof(int));\n edge = (int**)std::malloc(N*sizeof(int*));\n rev = (int**)std::malloc(N*sizeof(int*));\n flow = (FT**)std::malloc(N*sizeof(FT*));\n cost = (CT**)std::malloc(N*sizeof(CT*));\n rep(i,N){\n emem[i] = 0;\n edge[i] = rev[i] = NULL;\n flow[i] = NULL;\n cost[i] = NULL;\n }\n \n hp.malloc(N);\n reached = (char*)std::malloc(N*sizeof(char));\n cur_flow = (FT*)std::malloc(N*sizeof(FT));\n cur_cost = (CT*)std::malloc(N*sizeof(CT));\n back_edge = (int*)std::malloc(N*sizeof(int));\n\n node = N;\n rep(i,N) es[i] = 0;\n eps = (FT)1e-9;\n }\n\n void init(int N){\n int i;\n node = N;\n rep(i,N) es[i] = 0;\n eps = (FT)1e-9;\n }\n\n void memoryExpand(int i, int sz){\n if(sz <= emem[i]) return;\n sz = max(sz, 3, 2emem[i]);\n emem[i] = sz;\n edge[i] = (int*)realloc(edge[i], sz*sizeof(int));\n rev[i] = (int*)realloc(rev[i], sz*sizeof(int));\n flow[i] = (FT*)realloc(flow[i], sz*sizeof(FT));\n cost[i] = (CT*)realloc(cost[i], sz*sizeof(CT));\n }\n\n void addEdge(int n1, int n2, FT f, CT c){\n int s1 = es[n1]++;\n int s2 = es[n2]++;\n if(s1 >= emem[n1]) memoryExpand(n1, es[n1]);\n if(s2 >= emem[n2]) memoryExpand(n2, es[n2]);\n edge[n1][s1] = n2; edge[n2][s2] = n1;\n rev[n1][s1] = s2; rev[n2][s2] = s1;\n flow[n1][s1] = f; flow[n2][s2] = 0;\n cost[n1][s1] = c; cost[n2][s2] = -c;\n }\n\n template<class FTS, class CTS>\n void solve(int st, int ed, FTS &fres, CTS &cres, FT flim = -1){\n int i, j, k;\n FT f;\n \n fres = 0;\n cres = 0;\n for(;;){\n hp.init(node);\n rep(i,node) reached[i] = 0;\n reached[st] = 1;\n cur_cost[st] = 0;\n hp.change(st, cur_cost[st]);\n while(hp.size){\n i = hp.pop();\n rep(j, es[i]){\n if(flow[i][j] <= eps) continue;\n k = edge[i][j];\n if(reached[k]==0 || cur_cost[k] > cur_cost[i]+cost[i][j]+eps){\n reached[k] = 1;\n cur_cost[k] = cur_cost[i] + cost[i][j];\n cur_flow[k] = flow[i][j];\n if(i!=st) cur_flow[k] <?= cur_flow[i];\n back_edge[k] = rev[i][j];\n hp.change(k, cur_cost[k]);\n }\n }\n }\n if(reached[ed]==0) break;\n if(flim==-2 && cur_cost[ed] < 0) break;\n f = cur_flow[ed];\n if(flim != -1 && flim != -2) f <?= flim;\n if(f < eps) break;\n\n fres += f;\n cres += f * cur_cost[ed];\n\n i = ed;\n while(i != st){\n j = back_edge[i];\n k = edge[i][j];\n flow[i][j] += f;\n flow[k][rev[i][j]] -= f;\n i = k;\n }\n }\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); d.push_back((string)"max_L"); d.push_back((string)"LHeap"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "KMP"; string c = "template<class T, class S>\nint KMP(T A[], int As, T B[], int Bs, S res[] = NULL, int *fail = (int*)wmem){\n int i, k, cnt = 0;\n k = fail[0] = -1;\n rep(i,Bs){\n while(k>=0 && B[k]!=B[i]) k = fail[k];\n fail[i+1] = ++k;\n }\n if(res != NULL) rep(i,As) res[i] = 0;\n k = 0;\n rep(i,As){\n while(k >= 0 && B[k] != A[i]) k = fail[k];\n k++;\n if(k == Bs){\n cnt++;\n if(res != NULL) res[i-Bs+1] = 1;\n k = fail[k];\n }\n }\n return cnt;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "isSubsequence"; string c = "template<class T>\nint isSubsequence(int As, T A[], int Bs, T B[]){\n int i, j = 0;\n if(Bs==0) return 1;\n rep(i,As) if(A[i]==B[j]){\n j++;\n if(j==Bs) break;\n }\n return j == Bs;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "longestSuffixPrefix"; string c = "template<class T>\nint longestSuffixPrefix(int As, T A[], int Bs, T B[], void *mem = wmem){\n int i, k, res;\n int *fail;\n\n if(As > Bs) A += As-Bs, As = Bs;\n if(As < Bs) Bs = As;\n\n walloc1d(&fail, Bs, &mem);\n \n k = fail[0] = -1;\n rep(i,Bs){\n while(k>=0 && B[k]!=B[i]) k = fail[k];\n fail[i+1] = ++k;\n }\n\n res = 0;\n rep(i,As){\n while(res && A[i]!=B[res]) res = fail[res];\n if(A[i]==B[res]) res++;\n }\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"min_L"); d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "AhoCorasick"; string c = "struct AhoCorasick{\n int node, mem, alphabet;\n int **nx, *failed;\n int **ind, *indsz, *indmem;\n\n void init(void){\n int i;\n node = 1;\n rep(i,alphabet) nx[0][i] = -1;\n failed[0] = 0;\n indsz[0] = 0;\n }\n\n void malloc(const int n, const int k){\n int i;\n malloc2d(&nx,n,k);\n malloc1d(&failed,n);\n malloc1d(&ind,n);\n malloc1d(&indsz,n);\n malloc1d(&indmem,n);\n node = n;\n alphabet = k;\n rep(i,n) indmem[i] = 0;\n init();\n }\n\n void free(void){\n free2d(nx);\n free1d(failed);\n free1d(ind);\n free1d(indsz);\n free1d(indmem);\n }\n\n inline void addEnd(const int n, const int id){\n int s;\n if(indsz[n]+1 > indmem[n]){\n s = indmem[n] * 2 + 1;\n if(indmem[n]==0) ind[n] = (int*) std::malloc(indmem[n] * sizeof(int));\n else ind[n] = (int*) std::realloc(ind[n], indmem[n] * sizeof(int));\n indmem[n] = s;\n }\n ind[n][indsz[n]++] = id;\n }\n\n template<class T> void addWord(const T word[], const int len, int id){\n int i, j, k, now = 0;\n rep(i,len){\n if(nx[now][word[i]]==-1){\n k = node++;\n nx[now][word[i]] = k;\n rep(j,alphabet) nx[k][j] = -1;\n indsz[k] = 0;\n }\n now = nx[now][word[i]];\n }\n addEnd(now, id);\n }\n\n void construct(void *mem = wmem){\n int i, j, k, now;\n int *q, qs, qe;\n\n q = (int*) mem;\n qs = qe = 0;\n\n now = 0;\n rep(k,alphabet) if(nx[now][k] != -1){\n q[qe++] = nx[now][k];\n failed[ nx[now][k] ] = now;\n }\n\n while(qs < qe){\n now = q[qs++];\n rep(k,alphabet) if(nx[now][k] != -1){\n i = failed[now];\n while(i){\n if(nx[i][k] != -1) break;\n i = failed[i];\n }\n if(nx[i][k] != -1) i = nx[i][k];\n failed[ nx[now][k] ] = i;\n rep(j,indsz[i]) addEnd(nx[now][k], ind[i][j]);\n q[qe++] = nx[now][k];\n }\n }\n }\n\n template<class T> inline int next(const int n, const T c){\n int i, now;\n now = n;\n if(nx[n][c]!=-1) return nx[n][c];\n while(now && nx[now][c]==-1) now=failed[now];\n if(nx[now][c]!=-1) now = nx[now][c];\n return nx[n][c] = now;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"malloc1d"); d.push_back((string)"malloc2d"); d.push_back((string)"free1d"); d.push_back((string)"free2d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "AhoCorasick_Sum"; string c = "template<class S>\nstruct AhoCorasick_Sum{\n int node, mem, alphabet;\n int **nx, *failed;\n S *sum;\n\n void init(void){\n int i;\n node = 1;\n rep(i,alphabet) nx[0][i] = -1;\n failed[0] = 0;\n sum[0] = 0;\n }\n\n void malloc(const int n, const int k){\n int i;\n malloc2d(&nx,n,k);\n malloc1d(&failed,n);\n malloc1d(&sum,n);\n node = n;\n alphabet = k;\n init();\n }\n\n void free(void){\n free2d(nx);\n free1d(failed);\n free1d(sum);\n }\n\n template<class T> void addWord(const T word[], const int len, S val){\n int i, j, k, now = 0;\n rep(i,len){\n if(nx[now][word[i]]==-1){\n k = node++;\n nx[now][word[i]] = k;\n rep(j,alphabet) nx[k][j] = -1;\n sum[k] = 0;\n }\n now = nx[now][word[i]];\n }\n sum[now] += val;\n }\n\n void construct(void *mem = wmem){\n int i, j, k, now;\n int *q, qs, qe;\n\n q = (int*) mem;\n qs = qe = 0;\n\n now = 0;\n rep(k,alphabet) if(nx[now][k] != -1){\n q[qe++] = nx[now][k];\n failed[ nx[now][k] ] = now;\n }\n\n while(qs < qe){\n now = q[qs++];\n rep(k,alphabet) if(nx[now][k] != -1){\n i = failed[now];\n while(i){\n if(nx[i][k] != -1) break;\n i = failed[i];\n }\n if(nx[i][k] != -1) i = nx[i][k];\n failed[ nx[now][k] ] = i;\n sum[ nx[now][k] ] += sum[i];\n q[qe++] = nx[now][k];\n }\n }\n }\n\n template<class T> inline int next(const int n, const T c){\n int i, now;\n now = n;\n if(nx[n][c]!=-1) return nx[n][c];\n while(now && nx[now][c]==-1) now=failed[now];\n if(nx[now][c]!=-1) now = nx[now][c];\n return nx[n][c] = now;\n }\n};\n"; string p = "first"; vector<string> d; d.push_back((string)"malloc1d"); d.push_back((string)"malloc2d"); d.push_back((string)"free1d"); d.push_back((string)"free2d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "inversion_range"; string c = "ll inversion_range(int N, int A[], int mn, int mx, void *mem=wmem){\n int i, j, k;\n ll res = 0;\n fenwick<int> t;\n\n t.walloc(mx-mn+1, &mem);\n t.init(mx-mn+1);\n\n for(i=N-1;i>=0;i--){\n res += t.get(A[i]-mn-1);\n t.add(A[i]-mn,1);\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"fenwick"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "inversion"; string c = "template<class T>\nll inversion(int N, T A[], void *mem=wmem){\n int i, j, k, p;\n int n1, n2;\n T *x, *y;\n ll res = 0;\n\n walloc1d(&x, N, &mem);\n walloc1d(&y, N, &mem);\n rep(i,N) x[i] = A[i];\n\n for(k=0;k<N;k+=4){\n n1 = min(4, N-k);\n for(j=n1;j;j--){\n REP(i,1,j) if(x[k+i-1] > x[k+i]){\n swap(x[k+i-1], x[k+i]);\n res++;\n }\n }\n }\n\n p = 4;\n while(p<N){\n for(k=0;k<N;k+=2*p){\n n1 = min(p,N-k);\n n2 = min(p,N-k-n1);\n \n i = j = 0;\n while(i<n1 && j<n2){\n if(x[k+i] <= x[k+n1+j]){\n y[k+i+j] = x[k+i];\n i++;\n } else {\n y[k+i+j] = x[k+n1+j];\n res += n1-i;\n j++;\n }\n }\n while(i<n1){\n y[k+i+j] = x[k+i];\n i++;\n }\n while(j<n2){\n y[k+i+j] = x[k+n1+j];\n j++;\n }\n }\n \n swap(x,y);\n p *= 2;\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"min_L"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "ZetaTransform"; string c = "template<class T, class S>\nvoid ZetaTransform_L(int N, T A[], S res[] = NULL){\n int i, j;\n if(res==NULL){\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) A[j] += A[j^(1<<i)];\n }\n } else {\n rep(j,N) res[j] = A[j];\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) res[j] += res[j^(1<<i)];\n }\n }\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "ZetaTransform_min"; string c = "template<class T, class S>\nvoid ZetaTransform_min_L(int N, T A[], S res[] = NULL){\n int i, j;\n if(res==NULL){\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) A[j] <?= A[j^(1<<i)];\n }\n } else {\n rep(j,N) res[j] = A[j];\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) res[j] <?= res[j^(1<<i)];\n }\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "ZetaTransform_min2"; string c = "template<class T, class S>\nvoid ZetaTransform_min_L(int N, T A[], S r1[], S r2[]){\n int i, j, k;\n rep(j,N) r1[j] = A[j];\n rep(j,N) r2[j] = numeric_limits<S>::max();\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i){\n k = (j^(1<<i));\n r2[j] <?= r1[k];\n sortE(r1[j], r2[j]);\n r2[j] <?= r2[k];\n }\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); d.push_back((string)"sortE"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "ZetaTransform_min3"; string c = "template<class T, class S>\nvoid ZetaTransform_min_L(int N, T A[], S r1[], S r2[], S r3[]){\n int i, j, k;\n rep(j,N) r1[j] = A[j];\n rep(j,N) r2[j] = numeric_limits<S>::max();\n rep(j,N) r3[j] = numeric_limits<S>::max();\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i){\n k = (j^(1<<i));\n r3[j] <?= r1[k];\n sortE(r2[j], r3[j]);\n sortE(r1[j], r2[j]);\n r3[j] <?= r2[k];\n sortE(r2[j], r3[j]);\n r3[j] <?= r3[k];\n }\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"chmin"); d.push_back((string)"sortE"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "ZetaTransform_max"; string c = "template<class T, class S>\nvoid ZetaTransform_max_L(int N, T A[], S res[] = NULL){\n int i, j;\n if(res==NULL){\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) A[j] >?= A[j^(1<<i)];\n }\n } else {\n rep(j,N) res[j] = A[j];\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) res[j] >?= res[j^(1<<i)];\n }\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"chmax"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "MoebiusTransform"; string c = "template<class T>\nvoid MoebiusTransform(int N, T A[], T res[] = NULL){\n int i, j;\n if(res==NULL){\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) A[j] -= A[j^(1<<i)];\n }\n } else {\n rep(j,N) res[j] = A[j];\n for(i=0;(1<<i)<N;i++){\n rep(j,N) if(j&1<<i) res[j] -= res[j^(1<<i)];\n }\n }\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "slideMin"; string c = "template<class T>\nvoid slideMin(int n, int k, T in[], T res[], void *mem = wmem){\n int i, s = 0;\n T *q;\n int q_st = 0, q_size = 0;\n\n walloc1d(&q, n);\n\n rep(i,n){\n while(q_size && q[q_st+q_size-1] > in[i]) q_size--;\n q[q_st+q_size++] = in[i];\n if(i>=k && in[i-k]==q[q_st]) q_st++, q_size--;\n if(i>=k-1) res[s++] = q[q_st];\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "slideMax"; string c = "template<class T>\nvoid slideMax(int n, int k, T in[], T res[], void *mem = wmem){\n int i, s = 0;\n T *q;\n int q_st = 0, q_size = 0;\n\n walloc1d(&q, n);\n\n rep(i,n){\n while(q_size && q[q_st+q_size-1] < in[i]) q_size--;\n q[q_st+q_size++] = in[i];\n if(i>=k && in[i-k]==q[q_st]) q_st++, q_size--;\n if(i>=k-1) res[s++] = q[q_st];\n }\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"workmemory"); d.push_back((string)"walloc1d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "isLeapYear"; string c = "inline int isLeapYear(const int y){\n if(y%4) return 0;\n if(y%100) return 1;\n if(y%400) return 0;\n return 1;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "numOfDaysInMonth1"; string c = "inline int numOfDaysInMonth(const int m){\n if(m==2) return 28;\n if(m==4||m==6||m==9||m==11) return 30;\n return 31;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"isLeapYear"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "numOfDaysInMonth2"; string c = "inline int numOfDaysInMonth(const int y, const int m){\n return numOfDaysInMonth(m) if[m==2, + isLeapYear(y)];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"isLeapYear"); d.push_back((string)"numOfDaysInMonth1"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "dayOfWeek"; string c = "inline int dayOfWeek(int Y, int M, int D){\n int i, j;\n if(M <= 2) M += 12, Y--;\n i = Y / 100;\n j = Y % 100;\n return (D + 13*(M+1)/5 + j + j/4 + 5*i + i/4 + 5) % 7;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "dayOfWeekStr"; string c = "const char* WeekStr[7] = {\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"};\n\ninline const char* dayOfWeekStr(int w){\n return WeekStr[w];\n}\n\ninline const char* dayOfWeekStr(int Y, int M, int D){\n return WeekStr[dayOfWeek(Y, M, D)];\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"dayOfWeek"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "isVowel"; string c = "inline int isVowel(const char c){\n if(c=='a'||c=='i'||c=='u'||c=='e'||c=='o') return 1;\n if(c=='A'||c=='I'||c=='U'||c=='E'||c=='O') return 1;\n return 0;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Grid1d"; string c = "template<class T>\nstruct Grid1d {\n int n;\n T *d;\n\n int set_s, set_d;\n \n T *d_s;\n int *up, *dw, *lf, *rg;\n\n void malloc(const int nn){\n n = nn;\n set_s = 0;\n set_d = 0;\n malloc1d(&d, n);\n }\n\n void free(void){\n free1d(d);\n if(set_s) free1d(d_s);\n if(set_d) free1d(up), free1d(dw);\n }\n\n T& operator[](int a){\n return d[a];\n }\n\n void setSum(void){\n int i;\n if(set_s == 0){\n set_s = 1;\n malloc1d(&d_s, n+1);\n }\n d_s[0] = 0;\n rep(i,n) d_s[i+1] = d_s[i] + d[i];\n }\n\n void setDir(void){\n int i;\n if(set_d == 0){\n set_d = 1;\n malloc1d(&up, n);\n malloc1d(&dw, n);\n lf = dw;\n rg = up;\n }\n\n lf[0] = 1;\n rep(i,1,n) lf[i] = 1 if[d[i]==d[i-1], + lf[i-1]];\n\n rg[n-1] = 1;\n for(i=n-2;i>=0;i--) rg[i] = 1 if[d[i]==d[i+1], + rg[i+1]];\n }\n\n void setDirMatch(const T v){\n int i;\n if(set_d == 0){\n set_d = 1;\n malloc1d(&up, n);\n malloc1d(&dw, n);\n lf = dw;\n rg = up;\n }\n\n lf[0] = if[d[0]==v, 1, 0];\n rep(i,1,n) lf[i] = if[d[i]==v, 1 + lf[i-1], 0];\n\n rg[n-1] = if[d[n-1]==v, 1, 0];\n for(i=n-2;i>=0;i--) rg[i] = if[d[i]==v, 1 + rg[i+1], 0];\n }\n\n inline T getSum(const int a, const int b){\n return d_s[b+1] - d_s[a];\n }\n \n};\n"; string p = "first"; vector<string> d; d.push_back((string)"malloc1d"); d.push_back((string)"free1d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Grid2d"; string c = "template<class T>\nstruct Grid2d {\n int r, c;\n T **d;\n\n int set_s, set_d;\n \n T **d_s;\n int **up, **dw, **lf, **rg;\n\n void malloc(const int rr, const int cc){\n r = rr;\n c = cc;\n set_s = 0;\n set_d = 0;\n malloc2d(&d, r, c);\n }\n\n void free(void){\n free2d(d);\n if(set_s) free2d(d_s);\n if(set_d) free2d(up), free2d(dw), free2d(lf), free2d(rg);\n }\n\n T*operator[](int a){\n return d[a];\n }\n\n void setSum(void){\n int i, j;\n if(set_s == 0){\n set_s = 1;\n malloc2d(&d_s, r+1, c+1);\n }\n rep(i,r+1) d_s[i][0] = 0;\n rep(j,c+1) d_s[0][j] = 0;\n rep(i,r) rep(j,c) d_s[i+1][j+1] = d_s[i][j+1] + d_s[i+1][j] - d_s[i][j] + d[i][j];\n }\n\n void setDir(void){\n int i, j;\n if(set_d == 0){\n set_d = 1;\n malloc2d(&up, r, c);\n malloc2d(&dw, r, c);\n malloc2d(&lf, r, c);\n malloc2d(&rg, r, c);\n }\n\n rep(j,c) up[0][j] = 1;\n rep(i,1,r) rep(j,c) up[i][j] = 1 if[d[i][j]==d[i-1][j], + up[i-1][j]];\n\n rep(j,c) dw[r-1][j] = 1;\n for(i=r-2;i>=0;i--) rep(j,c) dw[i][j] = 1 if[d[i][j]==d[i+1][j], + dw[i+1][j]];\n\n rep(i,r){\n lf[i][0] = 1;\n rep(j,1,c) lf[i][j] = 1 if[d[i][j]==d[i][j-1], + lf[i][j-1]];\n }\n\n rep(i,r){\n rg[i][c-1] = 1;\n for(j=c-2;j>=0;j--) rg[i][j] = 1 if[d[i][j]==d[i][j+1], + rg[i][j+1]];\n }\n }\n\n void setDirMatch(const T v){\n int i, j;\n if(set_d == 0){\n set_d = 1;\n malloc2d(&up, r, c);\n malloc2d(&dw, r, c);\n malloc2d(&lf, r, c);\n malloc2d(&rg, r, c);\n }\n\n rep(j,c) up[0][j] = if[d[0][j]==v, 1, 0];\n rep(i,1,r) rep(j,c) up[i][j] = if[d[i][j]==v, 1 + up[i-1][j], 0];\n\n rep(j,c) dw[r-1][j] = if[d[r-1][j]==v, 1, 0];\n for(i=r-2;i>=0;i--) rep(j,c) dw[i][j] = if[d[i][j]==v, 1 + dw[i+1][j], 0];\n\n rep(i,r){\n lf[i][0] = if[d[i][0]==v, 1, 0];\n rep(j,1,c) lf[i][j] = if[d[i][j]==v, 1 + lf[i][j-1], 0];\n }\n\n rep(i,r){\n rg[i][c-1] = if[d[i][c-1]==v, 1, 0];\n for(j=c-2;j>=0;j--) rg[i][j] = if[d[i][j]==v, 1 + rg[i][j+1], 0];\n }\n }\n\n inline T getSum(const int r1, const int c1, const int r2, const int c2){\n return d_s[r2+1][c2+1] - d_s[r1][c2+1] - d_s[r2+1][c1] + d_s[r1][c1];\n }\n \n};\n"; string p = "first"; vector<string> d; d.push_back((string)"malloc2d"); d.push_back((string)"free2d"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "convolution"; string c = "struct fft_pnt{\n double x, y;\n\n fft_pnt(void){\n }\n fft_pnt(double a, double b){\n x = a;\n y = b;\n }\n\n void set(double a, double b){\n x = a;\n y = b;\n }\n\n fft_pnt& operator+=(fft_pnt a){ x+=a.x; y+=a.y; return *this; }\n fft_pnt& operator-=(fft_pnt a){ x-=a.x; y-=a.y; return *this; }\n fft_pnt& operator*=(fft_pnt a){ fft_pnt p = *this; x = p.x*a.x-p.y*a.y; y = p.x*a.y+p.y*a.x; return *this; }\n\n fft_pnt operator+(fft_pnt a){ return fft_pnt(*this) += a; }\n fft_pnt operator-(fft_pnt a){ return fft_pnt(*this) -= a; }\n fft_pnt operator*(fft_pnt a){ return fft_pnt(*this) *= a; }\n};\n\nvoid fft_L(int n, fft_pnt x[], void *mem){\n int i, j;\n int n1, n2, n3, step = 1;\n double theta = 2*PI / n, tmp;\n fft_pnt w1, w2, w3, a, b, c, d, aa, bb, cc, dd, *y = (fft_pnt*)mem;\n\n while(n > 2){\n n1 = n / 4;\n n2 = n1 + n1;\n n3 = n1 + n2;\n rep(i,n1){\n w1 = fft_pnt(cos(i*theta),-sin(i*theta));\n w2 = w1*w1;\n w3 = w1*w2;\n rep(j,step){\n a = x[j+step*i];\n b = x[j+step*(i+n1)];\n c = x[j+step*(i+n2)];\n d = x[j+step*(i+n3)];\n aa = a + c;\n bb = a - c;\n cc = b + d;\n dd = b - d;\n tmp = dd.y; dd.y = dd.x; dd.x = -tmp;\n y[j+step*(4*i )] = aa + cc;\n y[j+step*(4*i+1)] = w1*(bb - dd);\n y[j+step*(4*i+2)] = w2*(aa - cc);\n y[j+step*(4*i+3)] = w3*(bb + dd);\n }\n }\n n /= 4;\n step *= 4;\n theta *= 4;\n swap(x,y);\n }\n\n if(n==2){\n rep(i,step){\n y[i] = x[i] + x[i+step];\n y[i+step] = x[i] - x[i+step];\n }\n n /= 2;\n step *= 2;\n theta *= 2;\n swap(x,y);\n }\n \n rep(i,step) y[i] = x[i];\n}\n\nvoid fftinv_L(int n, fft_pnt x[], void *mem){\n int i, j;\n int n1, n2, n3, step = 1;\n double theta = 2*PI / n, tmp;\n fft_pnt w1, w2, w3, a, b, c, d, aa, bb, cc, dd, *y = (fft_pnt*)mem;\n\n while(n > 2){\n n1 = n / 4;\n n2 = n1 + n1;\n n3 = n1 + n2;\n rep(i,n1){\n w1 = fft_pnt(cos(i*theta),sin(i*theta));\n w2 = w1*w1;\n w3 = w1*w2;\n rep(j,step){\n a = x[j+step*i];\n b = x[j+step*(i+n1)];\n c = x[j+step*(i+n2)];\n d = x[j+step*(i+n3)];\n aa = a + c;\n bb = a - c;\n cc = b + d;\n dd = b - d;\n tmp = dd.y; dd.y = dd.x; dd.x = -tmp;\n y[j+step*(4*i )] = aa + cc;\n y[j+step*(4*i+1)] = w1*(bb + dd);\n y[j+step*(4*i+2)] = w2*(aa - cc);\n y[j+step*(4*i+3)] = w3*(bb - dd);\n }\n }\n n /= 4;\n step *= 4;\n theta *= 4;\n swap(x,y);\n }\n\n if(n==2){\n rep(i,step){\n y[i] = x[i] + x[i+step];\n y[i+step] = x[i] - x[i+step];\n }\n n /= 2;\n step *= 2;\n theta *= 2;\n swap(x,y);\n }\n \n rep(i,step) y[i] = x[i];\n}\n\nvoid convolution_L(double A[], int As, double B[], int Bs, double res[], int Rs, void *mem = wmem){\n int i, n, n2;\n double mul;\n fft_pnt *a, *b;\n\n n = max(As+Bs, Rs);\n for(n2=1;n2<n;n2*=2);\n walloc1d(&a, n2, &mem);\n walloc1d(&b, n2, &mem);\n\n rep(i,As) a[i].set(A[i], 0);\n REP(i,As,n2) a[i].set(0,0);\n rep(i,Bs) b[i].set(B[i], 0);\n REP(i,Bs,n2) b[i].set(0,0);\n\n fft_L(n2, a, mem);\n fft_L(n2, b, mem);\n rep(i,n2) a[i] *= b[i];\n fftinv_L(n2, a, mem);\n mul = 1.0 / n2;\n rep(i,Rs) res[i] = a[i].x * mul;\n}\n\nvoid convolution_L(double A[], int As, double res[], int Rs, void *mem = wmem){\n int i, n, n2;\n double mul;\n fft_pnt *a;\n\n n = max(As+As, Rs);\n for(n2=1;n2<n;n2*=2);\n walloc1d(&a, n2, &mem);\n\n rep(i,As) a[i].set(A[i], 0);\n REP(i,As,n2) a[i].set(0,0);\n\n fft_L(n2, a, mem);\n rep(i,n2) a[i] *= a[i];\n fftinv_L(n2, a, mem);\n mul = 1.0 / n2;\n rep(i,Rs) res[i] = a[i].x * mul;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); d.push_back((string)"max_L"); d.push_back((string)"define_PI"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Hungarian"; string c = "template<class T>\nT Hungarian(T **mat, int n, int m, int match[] = NULL, void *mem = wmem){\n int i, a, b, c, r, z;\n int *toright;\n int *toleft;\n T *ofsleft;\n T *ofsright;\n int *left, *right;\n int *trace, *ptr;\n T d, t, res = 0;\n\n walloc1d(&toright, n, &mem);\n walloc1d(&toleft, m, &mem);\n walloc1d(&ofsleft, n, &mem);\n walloc1d(&ofsright, m, &mem);\n\n walloc1d(&left, n, &mem);\n walloc1d(&right, m, &mem);\n walloc1d(&trace, m, &mem);\n walloc1d(&ptr, m, &mem);\n\n rep(i,n) toright[i] = -1, ofsleft[i] = 0;\n rep(i,m) toleft[i] = -1, ofsright[i] = 0;\n\n rep(r,n){\n rep(i,n) left[i] = 0;\n rep(i,m) right[i] = 0;\n rep(i,m) trace[i] = -1, ptr[i] = r;\n left[r] = 1;\n\n for(;;){\n d = std::numeric_limits<T>::max();\n rep(i,m) if(!right[i]){\n t = mat[ptr[i]][i] + ofsleft[ptr[i]] + ofsright[i];\n if(d > t) d = t, b = i;\n }\n\n res += d;\n rep(i,n) if(left[i]) ofsleft[i] -= d;\n rep(i,m) if(right[i]) ofsright[i] += d;\n\n trace[b] = ptr[b];\n c = toleft[b];\n if(c < 0){\n while(b>=0){\n a = trace[b];\n z = toright[a];\n toleft[b] = a;\n toright[a] = b;\n b = z;\n }\n break;\n }\n right[b] = left[c] = 1;\n rep(i,m) if(mat[c][i] + ofsleft[c] + ofsright[i] < mat[ptr[i]][i] + ofsleft[ptr[i]] + ofsright[i]) ptr[i] = c;\n }\n }\n\n if(match!=NULL) rep(i,n) match[i] = toright[i];\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"walloc1d"); d.push_back((string)"workmemory"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "polationVal_1"; string c = "template<class T>\nT polationVal_L(int n, T x[], T y[], T t){\n int i, j;\n T res, tmp;\n\n rep(i,n) if(x[i]==t) return y[i];\n\n res = 0;\n rep(i,n){\n tmp = 1;\n rep(j,n) if(i!=j) tmp *= x[i] - x[j];\n tmp = 1 / tmp;\n rep(j,n) if(i!=j) tmp *= t - x[j];\n res += y[i] * tmp;\n }\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "polationVal_2"; string c = "template<class T>\nT polationVal_L(int n, T y[], T t){\n int i, j;\n T res, tmp, fc, m;\n\n rep(i,n) if(t==i) return y[i];\n\n fc = 1;\n rep(i,n) fc *= (t-i);\n\n m = 1;\n rep(i,2,n) m *= i;\n m = 1 / m;\n if(n%2) m = -m;\n\n res = 0;\n rep(i,n){\n if(i) m = m * (i-n) / i;\n tmp = fc / (t-i) * m;\n res -= y[i] * tmp;\n }\n \n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "polationPoly"; string c = "template<class T>\nPolynomial<T> polationPoly_L(int n, T x[], T y[]){\n int i, j;\n T c;\n Polynomial<T> res, tmp, t1;\n\n tmp.change(0, 1);\n t1.change(1, 1);\n rep(i,n){\n t1.change(0, -x[i]);\n tmp *= t1;\n }\n\n rep(i,n){\n c = 1;\n rep(j,n) if(j!=i) c *= (x[i] - x[j]);\n c = y[i] / c;\n\n t1.change(0, -x[i]);\n res += c * tmp / t1;\n }\n\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"Polynomial"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "Explode"; string c = "vector<string> Explode_L(const string &str, const string &d){\n int s = 0, i = 0, j;\n vector<string> res;\n while(i + d.size() - 1 < str.size()){\n rep(j,d.size()) if(str[i+j] != d[j]) break;\n if(j != d.size()) i++, continue;\n res.push_back(str.substr(s, i-s));\n s = (i += d.size());\n }\n res.push_back(str.substr(s));\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "Implode"; string c = "string Implode_L(const vector<string> &v, const string &d){\n int i;\n string res;\n if(v.size()==0) return res;\n res += v[0];\n rep(i,1,v.size()){\n res += d;\n res += v[i];\n }\n return res;\n}\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "knightDistance"; string c = "template<class T>\ninline T knightDistance(T x, T y){\n T res;\n if(x < 0) x = -x;\n if(y < 0) y = -y;\n if(x+y==1) return 3;\n if(x==y==2) return 4;\n res = max( x/+2, y/+2, (x+y)/+3 );\n if(res%2 != (x+y)%2) res++;\n return res;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"max_L"); d.push_back((string)"divup"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "InnerProd_1"; string c = "template<class S>\nS InnerProd_L(int n, S a[]){\n S res = 0;\n rep(i,n) res += a[i];\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; place[n] = p; } { string n = "InnerProd_2"; string c = "template<class S, class T>\nS InnerProd_L(int n, S a[], T b[]){\n S res = 0;\n rep(i,n) res += a[i] * b[i];\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; place[n] = p; } { string n = "InnerProd_3"; string c = "template<class S, class T, class U>\nS InnerProd_L(int n, S a[], T b[], U c[]){\n S res = 0;\n rep(i,n) res += a[i] * b[i] * c[i];\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; place[n] = p; } { string n = "InnerProd_4"; string c = "template<class S, class T, class U, class V>\nS InnerProd_L(int n, S a[], T b[], U c[], V d[]){\n S res = 0;\n rep(i,n) res += a[i] * b[i] * c[i] * d[i];\n return res;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; place[n] = p; } { string n = "crossProd"; string c = "ll crossProd_L(ll x1, ll y1, ll x2, ll y2){\n return x1 * y2 - x2 * y1;\n}\n"; string p = "first"; vector<string> d; name.push_back(n); func[n] = c; place[n] = p; } { string n = "LineIntersection_size"; string c = "int LineIntersection_size_L(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3, ll x4, ll y4, int p1 = 1, int p2 = 1, int p3 = 1, int p4 = 1){\n ll a, b, dx1, dy1, dx2, dy2;\n\n if(p1 == p3 == 2){\n dx1 = x2 - x1;\n dy1 = y2 - y1;\n if(dx1 < 0) dx1 = -dx1, dy1 = -dy1;\n dx2 = x4 - x3;\n dy2 = y4 - y3;\n if(dx2 < 0) dx2 = -dx2, dy2 = -dy2;\n a = gcd(dx1, abs(dy1));\n dx1 /= a;\n dy1 /= a;\n a = gcd(dx2, abs(dy2));\n dx2 /= a;\n dy2 /= a;\n if(dx1!=dx2 || dy1 != dy2) return 1;\n\n a = crossProd(x2-x1, y2-y1, x3-x1, y3-y1);\n if(a==0) return 2;\n return 0;\n }\n\n if(p3 == 2){\n swap(x1, x3); swap(y1, y3); swap(p1, p3);\n swap(x2, x4); swap(y2, y4); swap(p2, p4);\n }\n\n a = crossProd(x2-x1, y2-y1, x3-x1, y3-y1);\n b = crossProd(x2-x1, y2-y1, x4-x1, y4-y1);\n\n if(a==b==0){\n if(p1==2) return 2;\n if(x1==x2==x3==x4) x1 = y1, x2 = y2, x3 = y3, x4 = y4;\n if(x1 > x2) swap(x1, x2), swap(p1, p2);\n if(x3 > x4) swap(x3, x4), swap(p3, p4);\n if(x2 == x3 && p2 == p3 == 1) return 1;\n if(x4 == x1 && p4 == p1 == 1) return 1;\n if(x2 < x3 || x4 < x1) return 0;\n return 2;\n }\n\n if(a > b) a = -a, b = -b;\n if(a > 0 || (p3==0 && a >= 0)) return 0;\n if(b < 0 || (p4==0 && b <= 0)) return 0;\n if(p1==2) return 1;\n\n a = crossProd(x4-x3, y4-y3, x1-x3, y1-y3);\n b = crossProd(x4-x3, y4-y3, x2-x3, y2-y3);\n if(a > b) a = -a, b = -b;\n if(a > 0 || (p1==0 && a >= 0)) return 0;\n if(b < 0 || (p2==0 && b <= 0)) return 0;\n\n return 1;\n}\n"; string p = "first"; vector<string> d; d.push_back((string)"gcd"); d.push_back((string)"crossProd"); name.push_back(n); func[n] = c; need[n] = d; place[n] = p; } { string n = "dimcomp2"; string c = "struct dimcomp2 {\n int B;\n dimcomp2(){}\n dimcomp2(int b){\n B = b;\n }\n dimcomp2(int a, int b){\n B = b;\n }\n inline void set(int b){\n B = b;\n }\n inline void set(int a, int b){\n B = b;\n }\n inline int mask(int a, int b){\n return a * B + b;\n }\n inline int operator()(int a, int b){\n return a * B + b;\n }\n inline void para(int mask, int &a, int &b){\n a = mask / B;\n b = mask % B;\n }\n inline void operator()(int mask, int &a, int &b){\n a = mask / B;\n b = mask % B;\n }\n};\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "dimcomp3"; string c = "struct dimcomp3 {\n int B, C;\n dimcomp3(){};\n dimcomp3(int b, int c){\n B = b; C = c;\n }\n dimcomp3(int a, int b, int c){\n B = b; C = c;\n }\n inline void set(int b, int c){\n B = b; C = c;\n }\n inline void set(int a, int b, int c){\n B = b; C = c;\n }\n inline int mask(int a, int b, int c){\n return (a * B + b) * C + c;\n }\n inline int operator()(int a, int b, int c){\n return (a * B + b) * C + c;\n }\n inline void para(int mask, int &a, int &b, int &c){\n a = mask / (B*C);\n b = mask % (B*C) / C;\n c = mask % C;\n }\n inline void operator()(int mask, int &a, int &b, int &c){\n a = mask / (B*C);\n b = mask % (B*C) / C;\n c = mask % C;\n }\n};\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "dimcomp4"; string c = "struct dimcomp4 {\n int B, C, D;\n dimcomp4(){}\n dimcomp4(int b, int c, int d){\n B = b; C = c; D = d;\n }\n dimcomp4(int a, int b, int c, int d){\n B = b; C = c; D = d;\n }\n inline void set(int b, int c, int d){\n B = b; C = c; D = d;\n }\n inline void set(int a, int b, int c, int d){\n B = b; C = c; D = d;\n }\n inline int operator()(int a, int b, int c, int d){\n return ((a * B + b) * C + c) * D + d;\n }\n inline int mask(int a, int b, int c, int d){\n return ((a * B + b) * C + c) * D + d;\n }\n inline void operator()(int mask, int &a, int &b, int &c, int &d){\n a = mask / (B*C*D);\n b = mask % (B*C*D) / (C*D);\n c = mask % (C*D) / D;\n d = mask % D;\n }\n inline void para(int mask, int &a, int &b, int &c, int &d){\n a = mask / (B*C*D);\n b = mask % (B*C*D) / (C*D);\n c = mask % (C*D) / D;\n d = mask % D;\n }\n};\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } { string n = "dimcomp5"; string c = "struct dimcomp5 {\n int B, C, D, E;\n dimcomp5(){};\n dimcomp5(int b, int c, int d, int e){\n B = b; C = c; D = d; E = e;\n }\n dimcomp5(int a, int b, int c, int d, int e){\n B = b; C = c; D = d; E = e;\n }\n inline void set(int b, int c, int d, int e){\n B = b; C = c; D = d; E = e;\n }\n inline void set(int a, int b, int c, int d, int e){\n B = b; C = c; D = d; E = e;\n }\n inline int operator()(int a, int b, int c, int d, int e){\n return (((a * B + b) * C + c) * D + d) * E + e;\n }\n inline int mask(int a, int b, int c, int d, int e){\n return (((a * B + b) * C + c) * D + d) * E + e;\n }\n inline void operator()(int mask, int &a, int &b, int &c, int &d, int &e){\n a = mask / (B*C*D*E);\n b = mask % (B*C*D*E) / (C*D*E);\n c = mask % (C*D*E) / (D*E);\n d = mask % (D*E) / E;\n e = mask % E;\n }\n inline void para(int mask, int &a, int &b, int &c, int &d, int &e){\n a = mask / (B*C*D*E);\n b = mask % (B*C*D*E) / (C*D*E);\n c = mask % (C*D*E) / (D*E);\n d = mask % (D*E) / E;\n e = mask % E;\n }\n};\n"; string p = "first"; name.push_back(n); func[n] = c; place[n] = p; } if(0){ string n = ""; string c = ""; string p = "first"; vector<string> d; vector<string> L; name.push_back(n); func[n] = c; need[n] = d; place[n] = p; del[n] = L; } doit.insert((string)"optimize"); doit.insert((string)"stdc"); doit.insert((string)"namespace"); } string get_insert_string(string p){ int i, fg; map<string,vector<string> >::iterator it; vector<string> vs; string res, tmp; for(;;){ fg = 0; for(it=need.begin(); it!=need.end(); it++){ tmp = it->first; vs = it->second; if(doit.count(tmp)==0 || g_flags.count("no-insert-"+tmp)) continue; if(parent.count(tmp) && doit.count(parent[tmp])==0) continue; rep(i,vs.size()){ if(doit.count(vs[i])==0){ fg++; doit.insert(vs[i]); } } } for(it=del.begin(); it!=del.end(); it++){ tmp = it->first; vs = it->second; if(doit.count(tmp)==0 || g_flags.count("no-insert-"+tmp)) continue; if(parent.count(tmp) && doit.count(parent[tmp])==0) continue; rep(i,vs.size()){ if(already.count(vs[i])==0){ fg++; already.insert(vs[i]); } } } if(!fg) break; } rep(i,name.size()){ if(parent.count(name[i]) && doit.count(parent[name[i]])==0) continue; if(doit.count(name[i]) && g_flags.count("no-insert-"+name[i])==0 && already.count(name[i])==0 && place[name[i]] == p){ res += func[name[i]]; } } return res; } }; insertfunctions ifun; struct code{ code *up; vector<string> str, strtype; vector<int> nxt; vector<code*> nxtlst; string name, type; std::set<string> vartype, tvartype, tmp_vartype; map<string,string> localvar, globalvar, argvar; int insert_count; void set_init(){ vartype.insert((string)"void"); vartype.insert((string)"char"); vartype.insert((string)"signed char"); vartype.insert((string)"unsigned char"); vartype.insert((string)"int"); vartype.insert((string)"signed int"); vartype.insert((string)"unsigned int"); vartype.insert((string)"signed"); vartype.insert((string)"unsigned"); vartype.insert((string)"uint"); vartype.insert((string)"long"); vartype.insert((string)"signed long"); vartype.insert((string)"unsigned long"); vartype.insert((string)"ulong"); vartype.insert((string)"long long"); vartype.insert((string)"signed long long"); vartype.insert((string)"unsigned long long"); vartype.insert((string)"ll"); vartype.insert((string)"ull"); vartype.insert((string)"size_t"); vartype.insert((string)"int8_t"); vartype.insert((string)"int16_t"); vartype.insert((string)"int32_t"); vartype.insert((string)"int64_t"); vartype.insert((string)"uint8_t"); vartype.insert((string)"uint16_t"); vartype.insert((string)"uint32_t"); vartype.insert((string)"uint64_t"); vartype.insert((string)"__int8_t"); vartype.insert((string)"__int16_t"); vartype.insert((string)"__int32_t"); vartype.insert((string)"__int64_t"); vartype.insert((string)"__int128_t"); vartype.insert((string)"__uint8_t"); vartype.insert((string)"__uint16_t"); vartype.insert((string)"__uint32_t"); vartype.insert((string)"__uint64_t"); vartype.insert((string)"__uint128_t"); vartype.insert((string)"float"); vartype.insert((string)"double"); vartype.insert((string)"long double"); vartype.insert((string)"bool"); vartype.insert((string)"string"); vartype.insert((string)"FILE"); vartype.insert((string)"Timer"); vartype.insert((string)"Rand"); vartype.insert((string)"Modint"); vartype.insert((string)"Mint"); vartype.insert((string)"modint"); vartype.insert((string)"mint"); vartype.insert((string)"combination_mint"); vartype.insert((string)"graph"); vartype.insert((string)"HLD"); vartype.insert((string)"unionFind"); vartype.insert((string)"AhoCorasick"); vartype.insert((string)"fft_pnt"); vartype.insert((string)"Permutation"); vartype.insert((string)"dimcomp2"); vartype.insert((string)"dimcomp3"); vartype.insert((string)"dimcomp4"); vartype.insert((string)"dimcomp5"); tvartype.insert((string)"pair"); tvartype.insert((string)"tuple"); tvartype.insert((string)"vector"); tvartype.insert((string)"stack"); tvartype.insert((string)"queue"); tvartype.insert((string)"deque"); tvartype.insert((string)"priority_queue"); tvartype.insert((string)"set"); tvartype.insert((string)"multiset"); tvartype.insert((string)"map"); tvartype.insert((string)"bitset"); tvartype.insert((string)"unordered_set"); tvartype.insert((string)"unordered_map"); tvartype.insert((string)"Heap"); tvartype.insert((string)"Heap_max"); tvartype.insert((string)"LHeap"); tvartype.insert((string)"DijkstraHeap"); tvartype.insert((string)"fenwick"); tvartype.insert((string)"segtree"); tvartype.insert((string)"segtree_Point_Minval"); tvartype.insert((string)"segtree_Point_Min"); tvartype.insert((string)"segtree_Point_SumMin"); tvartype.insert((string)"segtree_Point_Prod"); tvartype.insert((string)"segtree_Point_Minval2"); tvartype.insert((string)"segtree_ChangeAdd_Sum"); tvartype.insert((string)"wgraph"); tvartype.insert((string)"maxflow"); tvartype.insert((string)"minCostFlow"); tvartype.insert((string)"HLD_fenwick"); tvartype.insert((string)"HLD_segtree"); tvartype.insert((string)"Matrix"); tvartype.insert((string)"Polynomial"); tvartype.insert((string)"AhoCorasick_Sum"); tvartype.insert((string)"Grid1d"); tvartype.insert((string)"Grid2d"); } void merge(std::set<string> &a, std::set<string> &b){ std::set<string>::iterator it; for(it=b.begin();it!=b.end();it++){ a.insert(*it); } } void merge(map<string,string> &a, map<string,string> &b){ map<string,string>::iterator it; for(it=b.begin();it!=b.end();it++){ a[it->first] = it->second; } } void set_next_types(std::set<string> &s_vartype, set<string> &s_tvartype, map<string,string> &s_localvar, map<string,string> &s_globalvar, map<string,string> &s_argvar){ merge(vartype, s_vartype); merge(tvartype, s_tvartype); merge(globalvar, s_globalvar); merge(globalvar, s_localvar); merge(globalvar, s_argvar); } void setUpnode(code *cc){ up = cc; set_next_types(cc->vartype, cc->tvartype, cc->localvar, cc->globalvar, cc->argvar); } int is_empty_block(void){ int i, j; int res = 1; if(localvar.size()) res = 0; if(nxtlst.size()) res = 0; rep(i,str.size()) if(str[i]!=";") res = 0; return res; } code* get_root(void){ code *r = this; while(r->up != NULL) r = r->up; return r; } pair<code*, string> find_struct(string in){ int i; string tmp; pair<code*, string> res; res.first = NULL; res.second = ""; rep(i,str.size()){ if(strtype[i] == "block-struct"){ tmp = str[i]; if(tmp == "struct " + in){ res.first = nxtlst[nxt[i]]; res.second = str[i]; return res; } } if(strtype[i] == "block-class"){ tmp = str[i]; if(tmp == "class " + in){ res.first = nxtlst[nxt[i]]; res.second = str[i]; return res; } } if(strtype[i].substr(0,5) == "block"){ res = nxtlst[nxt[i]]->find_struct(in); if(res.first != NULL) return res; } } return res; } void add_vartype(string in){ int i; vartype.insert(in); rep(i,nxtlst.size()) nxtlst[i]->add_vartype(in); } void add_tvartype(string in){ int i; tvartype.insert(in); rep(i,nxtlst.size()) nxtlst[i]->add_tvartype(in); } void add_localvar(string in1, string in2){ int i; code *cc = this; while(cc->type == "block-inserted") cc = cc->up; cc->localvar[in1] = in2; rep(i,cc->nxtlst.size()) cc->nxtlst[i]->add_globalvar(in1, in2); } void add_globalvar(string in1, string in2){ int i; globalvar[in1] = in2; rep(i,nxtlst.size()) nxtlst[i]->add_globalvar(in1, in2); } void add_argvar(string in1, string in2){ int i; argvar[in1] = in2; rep(i,nxtlst.size()) nxtlst[i]->add_globalvar(in1, in2); } void ftrim(string &in){ while(in.size() && isspace(in[0])) in = in.substr(1); } void etrim(string &in){ while(in.size() && isspace(in[in.size()-1])) in = in.substr(0, in.size()-1); } void trim(string &in){ ftrim(in); etrim(in); } void alltrim(string &in){ int i; string t; rep(i,in.size()) if(!isspace(in[i])) t += in[i]; in = t; } void ftrim_until(string &in, char s){ while(in.size() && in[0] != s) in = in.substr(1); } void etrim_until(string &in, char t){ while(in.size() && in[in.size()-1] != t) in = in.substr(0, in.size()-1); } void trim_until(string &in, char s, char t){ ftrim_until(in,s); etrim_until(in,t); } int MD_get_inv(ll a, int md){ll t=a,s=md,u=1,v=0,e;while(s){e=t/s;t-=e*s;u-=e*v;swap(t,s);swap(u,v);}if(u<0)u+=md;return u;} void code_replace(string &in){ int i, j, k, dot, dotp, d, dp, ex; string str; char buf[30]; ull val; trim(in); replaceAll_ns_t(in, "ll", "long long"); replaceAll_ns_t(in, "ull", "unsigned long long"); replaceAll_ns_t(in, "int_inf", "1073709056"); replaceAll_ns_t(in, "ll_inf", "4611686016279904256LL"); replaceAll_ns_t(in, "double_inf", "1e150"); if(strpos_ns_t(in, (string)"MD") >= 0) ifun.doit.insert((string)"define_MD"); if(strpos_ns_t(in, (string)"PI") >= 0) ifun.doit.insert((string)"define_PI"); if(strpos_ns_t(in, (string)"Timer") >= 0) ifun.doit.insert((string)"Timer"); if(strpos_ns_t(in, (string)"Rand") >= 0) ifun.doit.insert((string)"Rand"); if(strpos_ns_t(in, (string)"Modint") >= 0) ifun.doit.insert((string)"Modint"); if(strpos_ns_t(in, (string)"Mint") >= 0) ifun.doit.insert((string)"Mint"); if(strpos_ns_t(in, (string)"modint") >= 0) ifun.doit.insert((string)"modint"); if(strpos_ns_t(in, (string)"mint") >= 0) ifun.doit.insert((string)"mint"); if(strpos_ns_t(in, (string)"combination_mint") >= 0) ifun.doit.insert((string)"combination_mint"); if(strpos_ns_t(in, (string)"Heap") >= 0) ifun.doit.insert((string)"Heap"); if(strpos_ns_t(in, (string)"Heap_max") >= 0) ifun.doit.insert((string)"Heap_max"); if(strpos_ns_t(in, (string)"LHeap") >= 0) ifun.doit.insert((string)"LHeap"); if(strpos_ns_t(in, (string)"DijkstraHeap") >= 0) ifun.doit.insert((string)"DijkstraHeap"); if(strpos_ns_t(in, (string)"fenwick") >= 0) ifun.doit.insert((string)"fenwick"); if(strpos_ns_t(in, (string)"segtree") >= 0) ifun.doit.insert((string)"segtree"); if(strpos_ns_t(in, (string)"segtree_Point_Minval") >= 0) ifun.doit.insert((string)"segtree_Point_Minval"); if(strpos_ns_t(in, (string)"segtree_Point_Min") >= 0) ifun.doit.insert((string)"segtree_Point_Min"); if(strpos_ns_t(in, (string)"segtree_Point_SumMin") >= 0) ifun.doit.insert((string)"segtree_Point_SumMin"); if(strpos_ns_t(in, (string)"segtree_Point_Prod") >= 0) ifun.doit.insert((string)"segtree_Point_Prod"); if(strpos_ns_t(in, (string)"segtree_Point_Minval2") >= 0) ifun.doit.insert((string)"segtree_Point_Minval2"); if(strpos_ns_t(in, (string)"segtree_ChangeAdd_Sum") >= 0) ifun.doit.insert((string)"segtree_ChangeAdd_Sum"); if(strpos_ns_t(in, (string)"graph") >= 0) ifun.doit.insert((string)"graph"); if(strpos_ns_t(in, (string)"wgraph") >= 0) ifun.doit.insert((string)"wgraph"); if(strpos_ns_t(in, (string)"HLD") >= 0) ifun.doit.insert((string)"HLD"); if(strpos_ns_t(in, (string)"HLD_fenwick") >= 0) ifun.doit.insert((string)"HLD_fenwick"); if(strpos_ns_t(in, (string)"HLD_segtree") >= 0) ifun.doit.insert((string)"HLD_segtree"); if(strpos_ns_t(in, (string)"maxflow") >= 0) ifun.doit.insert((string)"maxflow"); if(strpos_ns_t(in, (string)"minCostFlow") >= 0) ifun.doit.insert((string)"minCostFlow"); if(strpos_ns_t(in, (string)"unionFind") >= 0) ifun.doit.insert((string)"unionFind"); if(strpos_ns_t(in, (string)"Matrix") >= 0) ifun.doit.insert((string)"Matrix"); if(strpos_ns_t(in, (string)"Permutation") >= 0) ifun.doit.insert((string)"Permutation"); if(strpos_ns_t(in, (string)"Polynomial") >= 0) ifun.doit.insert((string)"Polynomial"); if(strpos_ns_t(in, (string)"AhoCorasick") >= 0) ifun.doit.insert((string)"AhoCorasick"); if(strpos_ns_t(in, (string)"AhoCorasick_Sum") >= 0) ifun.doit.insert((string)"AhoCorasick_Sum"); if(strpos_ns_t(in, (string)"Grid1d") >= 0) ifun.doit.insert((string)"Grid1d"); if(strpos_ns_t(in, (string)"Grid2d") >= 0) ifun.doit.insert((string)"Grid2d"); if(strpos_ns_t(in, (string)"dimcomp2") >= 0) ifun.doit.insert((string)"dimcomp2"); if(strpos_ns_t(in, (string)"dimcomp3") >= 0) ifun.doit.insert((string)"dimcomp3"); if(strpos_ns_t(in, (string)"dimcomp4") >= 0) ifun.doit.insert((string)"dimcomp4"); if(strpos_ns_t(in, (string)"dimcomp5") >= 0) ifun.doit.insert((string)"dimcomp5"); for(;;){ int k4 = 0, k5 = 0; int fg = 0; rep(i,in.size()){ if(in[i]=='\'') k4 ^= 1; if(in[i]=='"') k5 ^= 1; if(k4 || k5) continue; if(!isdigit(in[i])) continue; if(i && isalnum(in[i-1])) continue; dot = d = ex = 0; REP(j,i,in.size()){ if(in[j]=='d'){ d++; dp=j; if(in[j+1]=='-' || in[j+1]=='+') j++; continue; } if(in[j]=='.'){ dot++; dotp=j; continue; } if(!isdigit(in[j])) break; } if(j < in.size() && isalpha(in[j])) continue; if(dot > 1 || d != 1) continue; if(dot && dotp > dp) continue; if(j == dp+1) continue; str = in.substr(i, dp-i); ex = atoi(in.c_str() + dp + 1); if(ex > 30) ex = 30; if(ex < -30) ex = -30; while(ex > 0){ rep(k,str.size()) if(str[k]=='.') break; if(k==str.size()){ str += '0'; } else if(k==str.size()-1) { str[k] = '0'; } else { str = str.substr(0,k) + str.substr(k+1,1) + "." + str.substr(k+2); } ex--; } while(ex < 0){ rep(k,str.size()) if(str[k]=='.') break; if(k!=str.size()) str = str.substr(0, k); if(str.size()) str = str.substr(0, str.size()-1); ex++; } val = 0; rep(k,str.size()){ if(str[k]=='.') break; val = val * 10 + (str[k] - '0'); } if(val < (1ULL << 31)){ sprintf(buf, "%llu", val); } else if(val < (1ULL << 63)) { sprintf(buf, "%lluLL", val); } else { sprintf(buf, "%lluULL", val); } str = buf; in = in.substr(0,i) + str + in.substr(j); fg = 1; break; } if(!fg) break; } } vector<string> split_p(string in, char c){ int i; int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0; vector<string> res; string tmp; rep(i,in.size()){ if(k4==0 && k5==0){ if(in[i]=='(') k1++; if(in[i]==')') k1--; if(in[i]=='[') k2++; if(in[i]==']') k2--; if(in[i]=='{') k3++; if(in[i]=='}') k3--; } if(in[i]=='\'') k4 ^= 1; if(in[i]=='"') k5 ^= 1; if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0 && in[i]==c){ res.push_back(tmp); tmp = ""; } else { tmp += in[i]; } } res.push_back(tmp); return res; } vector<string> split_p2(string in, char c){ int i; int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0, k6 = 0; vector<string> res; string tmp; rep(i,in.size()){ if(k4==0 && k5==0){ if(in[i]=='(') k1++; if(in[i]==')') k1--; if(in[i]=='[') k2++; if(in[i]==']') k2--; if(in[i]=='{') k3++; if(in[i]=='}') k3--; } if(k2==0 && in[i]=='<') k6++; if(k2==0 && in[i]=='>') k6--; if(in[i]=='\'') k4 ^= 1; if(in[i]=='"') k5 ^= 1; if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0 && k6==0 && in[i]==c){ res.push_back(tmp); tmp = ""; } else { tmp += in[i]; } } res.push_back(tmp); return res; } int isValidVarType(string in, char nxt){ int i, j, cnt; if(in.size()==0) return 0; if(in[in.size()-1] != '>' && isalnum(nxt)) return 0; if( (isalnum(in[in.size()-1]) || in[in.size()-1]=='_') && (isalnum(nxt) || nxt=='_') ) return 0; for(;;){ if(in.substr(0,1) == "~"){ in = in.substr(1); ftrim(in); continue; } if(in.substr(0,6) == "const "){ in = in.substr(6); ftrim(in); continue; } if(in.substr(0,7) == "static "){ in = in.substr(7); ftrim(in); continue; } if(in.substr(0,9) == "register "){ in = in.substr(9); ftrim(in); continue; } if(in.substr(0,9) == "register "){ in = in.substr(9); ftrim(in); continue; } if(in.substr(0,7) == "extern "){ in = in.substr(7); ftrim(in); continue; } if(in.substr(0,8) == "typename "){ in = in.substr(8); ftrim(in); continue; } if(in.substr(0,10) == "inplace_L "){ in = in.substr(10); ftrim(in); continue; } break; } if(vartype.count(in) || tmp_vartype.count(in)) return 1; if(tvartype.count(in)) return 1; rep(i,in.size()){ if(tvartype.count( in.substr(0,i) )){ cnt = 0; REP(j,i,in.size()){ if(cnt==0 && isalnum(in[j])) break; if(in[j]=='<') cnt++; if(in[j]=='>') cnt--; if(cnt==0 && in[j]=='>'){ j++; if(j==in.size()) return 1; if(in.substr(j) == "::iterator") return 1; break; } } } } return 0; } pair<string, char> nextToken(string &in){ int i, dig = 0; string res1 = ""; char res2 = '\0'; i = 0; while(i < in.size() && isspace(in[i])) i++; if(i==in.size()) return make_pair(res1,res2); if(isdigit(in[0]) || (in[0]=='.' && isdigit(in[1]))) dig = 1; while(i < in.size() && (isalnum(in[i]) || in[i]=='.' || (!dig && in[i]=='_'))) res1 += in[i++]; // while(i < in.size() && (isalnum(in[i]) || (dig && in[i]=='.') || (!dig && in[i]=='_'))) res1 += in[i++]; while(i < in.size() && isspace(in[i])) i++; res2 = in[i]; return make_pair(res1,res2); } pair<string,string> var_definition(string in){ int i, j, tt; string type, name, pre, suf, eq; vector<string> tmp; rep(i,in.size()+1) if(isValidVarType(in.substr(0,i), in[i])) tt = i; type = in.substr(0, tt); in = in.substr(tt); trim(in); if(in[in.size()-1] == ';'){ in = in.substr(0, in.size()-1); trim(in); } //fprintf(stderr, "[%s]\n", in.c_str()); tmp = split_p(in, '='); assert(tmp.size() <= 2); if(tmp.size()==2){ eq = tmp[1]; trim(eq); eq = equation_main(eq); in = tmp[0]; } rep(i,in.size()) if(isalpha(in[i]) || in[i]=='_' || in[i]==':') break; REP(j,i,in.size()) if(!(isalnum(in[j]) || in[j]=='_' || in[j]==':')) break; name = in.substr(i, j-i); pre = in.substr(0, i); suf = in.substr(j); trim(name); trim(pre); trim(suf); return make_pair(name, type+","+pre+","+suf+","+eq); } string getElementalyVarType(string in){ int i, k; vector<string> vs; k = strpos(in, "."); if(k >= 0){ string tp, res; code *cc; pair<code*,string> rs; tp = getElementalyVarType( in.substr(0,k) ); in = in.substr(k+1); trim(in); //fprintf(stderr, "--- %s - %s\n", tp.c_str(), in.c_str()); if(tp == "graph"){ if(in=="es" || in=="edge" || in=="N") return "int"; return "error"; } if(tp == "maxflow"){ // todo } cc = get_root(); rs = cc->find_struct(tp); if(rs.first == NULL) return "error"; res = rs.first->getElementalyVarType(in); return res; } while(in.size() && !isalpha(in[0])) in = in.substr(1); if(in.size()==0) return (string)"error"; rep(i,in.size()) if(!isalnum(in[i])) break; in = in.substr(0, i); if(in == "MD") return "int"; if(in == "PI") return "double"; if(localvar.count(in)){ in = localvar[in]; } else if(argvar.count(in)){ in = argvar[in]; } else if(globalvar.count(in)){ in = globalvar[in]; } else { return (string)"error"; } vs = split_p(in, ','); in = vs[0]; for(;;){ if(in.substr(0,6) == "const "){ in = in.substr(6); ftrim(in); continue; } if(in.substr(0,7) == "static "){ in = in.substr(7); ftrim(in); continue; } if(in.substr(0,8) == "typename "){ in = in.substr(8); ftrim(in); continue; } if(in.substr(0,10) == "inplace_L "){ in = in.substr(10); ftrim(in); continue; } break; } for(;;){ int fg = 0; if(in.substr(0,6) == "Grid1d"){ trim_until(in, '<', '>'); in = in.substr(1, in.size()-2); trim(in); fg = 1; } if(in.substr(0,6) == "Grid2d"){ trim_until(in, '<', '>'); in = in.substr(1, in.size()-2); trim(in); fg = 1; } if(in.substr(0,6) == "vector"){ trim_until(in, '<', '>'); in = in.substr(1, in.size()-2); trim(in); fg = 1; } if(in.substr(0,6) == "Matrix"){ trim_until(in, '<', '>'); in = in.substr(1, in.size()-2); trim(in); fg = 1; } if(in == "Permutation"){ in = "int"; fg = 1; } if(!fg) break; } return in; } string getEquationType(string in, int *fg = NULL, int *char_fg = NULL){ int i; map<string, int> flags; pair<string,char> stchar; string tp, str; for(;;){ trim(in); if(in.size()==0) break; if(in[0] == '['){ i = pairBracket(in, 0); if(i == -1) return (string)"error"; in = in.substr(i+1); continue; } if(in[0] == '"'){ flags["char"] = 1; if(char_fg != NULL) char_fg++; for(i=1;;i++){ if(in[i]=='\\'){ i++; continue; } if(in[i]=='"') break; } in = in.substr(i+1); continue; } if(in[0] == '\''){ flags["char"] = 1; if(char_fg != NULL) char_fg++; for(i=1;;i++) if(in[i]=='\'') break; in = in.substr(i+1); continue; } stchar = nextToken(in); str = stchar.first; //fprintf(stderr,"[%s - %c]\n", stchar.first.c_str(), stchar.second); in = in.substr(str.size()); if(str.size()==0) in = in.substr(1); if(str.size()){ if(isdigit(str[0]) || (str[0]=='.' && isdigit(str[1]))) { if(strpos(str, (string)".") >= 0 || strpos(str,(string)"e") >= 0){ if(str[str.size()-1] == 'f') tp = "float"; else tp = "double"; } else { if(str.size() >= 2 && str.substr(str.size()-2) == "ll") tp = "long long"; else tp = "int"; } } else if(isalpha(str[0])) { tp = getElementalyVarType(str); } //fprintf(stderr, "%s\n",tp.c_str()); flags[tp] = 1; if(tp == "char" && char_fg != NULL) (*char_fg)++; if(tp == "error" && fg!=NULL) (*fg)++; } } if(flags["string"]) return "string"; if(flags["double"]) return "double"; if(flags["float"]) return "float"; if(flags["Modint"]) return "Modint"; if(flags["Mint"]) return "Mint"; if(flags["modint"]) return "modint"; if(flags["mint"]) return "mint"; if(flags["__uint128_t"]) return "__uint128_t"; if(flags["__int128_t"]) return "__int128_t"; if(flags["unsigned long long"]) return "unsigned long long"; if(flags["ull"]) return "unsigned long long"; if(flags["long long"]) return "long long"; if(flags["ll"]) return "long long"; if(flags["uint64_t"]) return "uint64_t"; if(flags["__uint64_t"]) return "__uint64_t"; if(flags["int64_t"]) return "int64_t"; if(flags["__int64_t"]) return "__int64_t"; if(flags["unsigned"]) return "unsigned"; if(flags["unsigned int"]) return "unsigned"; if(flags["uint"]) return "unsigned"; if(flags["int"]) return "int"; if(flags["signed int"]) return "int"; if(flags["signed"]) return "int"; if(flags["uint32_t"]) return "uint32_t"; if(flags["__uint32_t"]) return "__uint32_t"; if(flags["int32_t"]) return "int32_t"; if(flags["__int32_t"]) return "__int32_t"; if(flags["uint16_t"]) return "uint16_t"; if(flags["__uint16_t"]) return "__uint16_t"; if(flags["int16_t"]) return "int16_t"; if(flags["__int16_t"]) return "__int16_t"; if(flags["char"]) return "char"; if(flags["uint8_t"]) return "uint8_t"; if(flags["__uint8_t"]) return "__uint8_t"; if(flags["int8_t"]) return "int8_t"; if(flags["__int8_t"]) return "__int8_t"; if(flags["void"]) return "void"; return (string)"error"; } string getUnusedVarName(void){ int i, k, p, r; string f = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; string res; for(k=8;;k++) rep(p,100){ res = ""; r = rand()%52; res += f[r]; REP(i,1,k){ r = rand()%f.size(); res += f[r]; } if(localvar.count(res)) continue; if(argvar.count(res)) continue; if(globalvar.count(res)) continue; return res; } return res; } void insert(string &in, int p){ int pure; for(;;){ ftrim(in); if(in.size()==0) break; insert_count++; if(in[0]=='{') pure = 1; else pure = 0; code *cc = new code; cc->setUpnode(this); if(pure){ cc->set(in, (string)"block"); } else { cc->set(in, (string)"block-inserted"); } nxt.insert(nxt.begin()+p, nxtlst.size()); nxtlst.push_back(cc); str.insert(str.begin()+p, (string)""); if(pure){ strtype.insert(strtype.begin()+p, (string)"block"); } else { strtype.insert(strtype.begin()+p, (string)"block-inserted"); } p++; } } int strpos(string &A, string B, int st = 0){ int i, As, Bs; As = A.size(); Bs = B.size(); REP(i,st,As-Bs+1) if(A.substr(i,Bs) == B) return i; return -1; } int strpos_ns(string &A, string B, int st = 0){ // "", '' の中は検索対象外 int i, k4, k5, As, Bs; As = A.size(); Bs = B.size(); k4 = k5 = 0; REP(i,st,As-Bs+1){ if( (k4 || k5) && A[i] == '\\' ){i++; continue;} if(A[i] == '"') k4 ^= 1; if(A[i] == '\'') k5 ^= 1; if(k4==0 && k5==0 && A.substr(i,Bs) == B) return i; } return -1; } int strrpos_ns(string &A, string B, int st = -1){ int i, k4, k5, As, Bs; As = A.size(); Bs = B.size(); k4 = k5 = 0; if(st == -1) st = As-Bs+1; for(i=st;i>=0;i--){ if( (k4 || k5) && A[i] == '\\' ){i++; continue;} if(A[i] == '"') k4 ^= 1; if(A[i] == '\'') k5 ^= 1; if(k4==0 && k5==0 && A.substr(i,Bs) == B) return i; } return -1; } int strpos_t(string &A, string B, int st = 0){ int i, As, Bs; As = A.size(); Bs = B.size(); REP(i,st,As-Bs+1) if(A.substr(i,Bs) == B){ if(i && (isalnum(A[i-1]) || A[i-1]=='_')) continue; if(i+Bs<As && (isalnum(A[i+Bs]) || A[i+Bs]=='_')) continue; return i; } return -1; } int strpos_ns_t(string &A, string B, int st = 0){ int i, k4, k5, As, Bs; As = A.size(); Bs = B.size(); k4 = k5 = 0; REP(i,st,As-Bs+1){ if( (k4 || k5) && A[i] == '\\' ){i++; continue;} if(A[i] == '"') k4 ^= 1; if(A[i] == '\'') k5 ^= 1; if(k4==0 && k5==0 && A.substr(i,Bs) == B){ if(i && (isalnum(A[i-1]) || A[i-1]=='_')) continue; if(i+Bs<As && (isalnum(A[i+Bs]) || A[i+Bs]=='_')) continue; return i; } } return -1; } int replaceAll(string &A, string B, string C){ int i, res = 0; for(;;){ i = strpos(A, B); if(i==-1) break; A = A.substr(0, i) + C + A.substr(i+B.size()); } return res; } int replaceAll_ns(string &A, string B, string C){ int i, res = 0; for(;;){ i = strpos_ns(A, B); if(i==-1) break; A = A.substr(0, i) + C + A.substr(i+B.size()); } return res; } int replaceAll_t(string &A, string B, string C){ int i, res = 0; for(;;){ i = strpos_t(A, B); if(i==-1) break; A = A.substr(0, i) + C + A.substr(i+B.size()); } return res; } int replaceAll_ns_t(string &A, string B, string C){ int i, res = 0; for(;;){ i = strpos_ns_t(A, B); if(i==-1) break; A = A.substr(0, i) + C + A.substr(i+B.size()); } return res; } vector<string> rd_wt_array(string in){ // 1+((a,b)(N)+2) returns "1+(", "(a,b)", "N", "+2)", hoge returns "hoge" int i, j, k, bf = -1, fg; string chk; vector<string> res; rep(i,in.size()){ fg = 0; if(bf == ')' || bf == ']') fg = 1; if(isalnum(bf) && in[i] == '('){ if(localvar.count(chk) || globalvar.count(chk) || argvar.count(chk)) fg = 1; if(getElementalyVarType(chk) != "error") fg = 1; } if(fg && in[i] == '('){ rep(k,4) res.push_back((string)""); j = pairBracket(in, i); res[2] = in.substr(i+1, j-i-1); res[3] = in.substr(j+1); in = in.substr(0, i); trim(in); i = in.size() - 1; while(in[i] == ']'){ i = pairBracket(in, i) - 1; while(isspace(in[i])) i--; } if(in[i]==')'){ i = pairBracket(in, i); res[0] = in.substr(0, i); res[1] = in.substr(i); } else { while(i >= 0 && (isalnum(in[i]) || in[i]=='_' || in[i]=='@' || in[i]=='.')) i--; i++; res[0] = in.substr(0, i); res[1] = in.substr(i); } rep(k,4) trim(res[k]); return res; } if(!isspace(in[i])){ bf = in[i]; if(isalnum(bf) || bf=='.' || bf=='_') chk += bf; else chk = ""; } } res.push_back(in); return res; } int checkBracketsCoressponding(string &in){ int i; int k4, k5; stack<int> s; k4 = k5 = 0; rep(i,in.size()){ if(k4==0 && k5==0){ if(in[i] == '(') s.push(1); if(in[i] == '[') s.push(2); if(in[i] == '{') s.push(3); if(in[i] == ')'){ if(s.size()==0 || s.top()!=1) return 0; s.pop(); } if(in[i] == ']'){ if(s.size()==0 || s.top()!=2) return 0; s.pop(); } if(in[i] == '}'){ if(s.size()==0 || s.top()!=3) return 0; s.pop(); } } if(in[i] == '\'') k4^=1; if(in[i] == '"') k5^=1; if( (k4||k5) && in[i] == '\\') {i++; continue;} } if(k4 || k5 || s.size()) return 0; return 1; } int pairBracket(string &in, int p){ int i; int k1, k2, k3, k4, k5; k1 = k2 = k3 = k4 = k5 = 0; if(in[p]=='(' || in[p]=='[' || in[p]=='{'){ for(i=p;i<in.size();i++){ if(k4==0 && k5==0){ if(in[i] == '(') k1++; if(in[i] == ')') k1--; if(in[i] == '[') k2++; if(in[i] == ']') k2--; if(in[i] == '{') k3++; if(in[i] == '}') k3--; } if(in[i] == '\'') k4^=1; if(in[i] == '"') k5^=1; if( (k4||k5) && in[i] == '\\') {i++; continue;} if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0) return i; } } else if(in[p]==')' || in[p]==']' || in[p]=='}'){ for(i=p;i>=0;i--){ if(k4==0 && k5==0){ if(in[i] == '(') k1++; if(in[i] == ')') k1--; if(in[i] == '[') k2++; if(in[i] == ']') k2--; if(in[i] == '{') k3++; if(in[i] == '}') k3--; } if(in[i] == '\'') k4^=1; if(in[i] == '"') k5^=1; if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0) return i; } } return -1; } /* in = bb + argmin[hoge](piyo) + aa; */ /* format = argmin[]() */ /* return {"bb + ", "hoge", "piyo", " + aa;"} */ /* if not found -> return {} */ vector<string> findFunction(string &in, string format){ int i, j, k, m, ok; int k4, k5; vector<string> fmt; vector<string> res; for(;;){ string tmp; trim(format); if(format.size()==0) break; if(format.substr(0,2) == "()" || format.substr(0,2) == "[]"){ fmt.push_back(format.substr(0,2)); format = format.substr(2); continue; } tmp = ""; while(format.size() && (isalnum(format[0]) || format[0]=='_')){ tmp += format[0]; format = format.substr(1); } if(tmp == ""){ tmp += format[0]; format = format.substr(1); } fmt.push_back(tmp); } k4 = k5 = 0; rep(i,in.size()){ if(in[i] == '"'){ k4 ^= 1; continue; } if(in[i] == '\''){ k5 ^= 1; continue; } if(k4 || k5){ if(in[i] == '\\') i++; continue; } if(i && (isalnum(fmt[0][0]) || fmt[0][0]=='_') && (isalnum(in[i-1]) || in[i-1]=='_')) continue; res.clear(); res.push_back( in.substr(0, i) ); j = i; ok = 1; rep(k,fmt.size()){ while(j < in.size() && isspace(in[j])) j++; if(j >= in.size()){ ok = 0; break; } if(fmt[k] == "()"){ if(in[j]!='('){ ok = 0; break; } m = pairBracket(in, j); res.push_back( in.substr(j+1, m-j-1) ); j = m + 1; while(j < in.size() && isspace(in[j])) j++; continue; } if(fmt[k] == "[]"){ if(in[j]!='['){ ok = 0; break; } m = pairBracket(in, j); res.push_back( in.substr(j+1, m-j-1) ); j = m + 1; while(j < in.size() && isspace(in[j])) j++; continue; } if(in.substr(j, fmt[k].size()) == fmt[k]){ j += fmt[k].size(); } else { ok = 0; break; } } if(ok){ res.push_back( in.substr(j) ); return res; } } res.clear(); return res; } int getExprLength_firstind(string tmp, int k){ int i; tmp = tmp.substr(k); k = 0; for(;;){ if(k==tmp.size()) break; if(isspace(tmp[k])){ k++; continue; } if(isOperator(tmp[k])){ k++; continue; } if(tmp[k]=='('){ i = pairBracket(tmp, k); if(isValidVarType(tmp.substr(k+1, i-k-1), ' ')){ k = i + 1; continue; } } break; } while(k < tmp.size() && (isalnum(tmp[k]) || tmp[k]=='.' || tmp[k]=='_')) k++; for(;;){ while(k < tmp.size() && isspace(tmp[k])) k++; if(k==tmp.size()) break; if(tmp[k]=='('){ k = pairBracket(tmp, k) + 1; tmp = tmp.substr(0, k); break; } if(tmp[k]=='['){ k = pairBracket(tmp, k) + 1; continue; } tmp = tmp.substr(0, k); break; } return tmp.size(); } int getExprLength_lastind(string tmp, int k){ int i; tmp = tmp.substr(0, k+1); for(;;){ if(k >= 0 && isspace(tmp[k])){ k--; continue; } if(k >= 0 && (isalnum(tmp[k]) || tmp[k]=='.')){ k--; continue; } if(tmp[k]==']' || tmp[k]==')'){ k = pairBracket(tmp, k) - 1; continue; } break; } tmp = tmp.substr(k+1); return tmp.size(); } string sentence_hatena_minmax_operator(string tmp){ int i, j; int k1, k2, k3, k4, k5; int p, p1, p2, p3, p4; string mode, arg1, arg2, bef, aft; for(;;){ p1 = strpos_ns(tmp, (string)">?="); p2 = strpos_ns(tmp, (string)"<?="); p3 = strpos_ns(tmp, (string)"**="); p4 = strpos_ns(tmp, (string)"%%="); if(p1<0 && p2<0 && p3<0 && p4<0) break; if(p1 > p2 && p1 > p3 && p1 > p4) p = p1, mode = "chmax"; else if(p2 > p1 && p2 > p3 && p2 > p3) p = p2, mode = "chmin"; else if(p3 > p1 && p3 > p2 && p3 > p4) p = p3, mode = "pow_L"; else p = p4, mode = "moddw"; ifun.doit.insert(mode); k1 = k2 = k3 = k4 = k5 = 0; for(i=p-1;;i--){ if(i >= 1 && k4 && tmp[i-1]=='/' && tmp[i]=='\''){ i-=2; continue; } if(i >= 0 && tmp[i]=='\'') k4 ^= 1; if(i >= 0 && tmp[i]=='"') k5 ^= 1; if(i >= 0 && k4==0 && k5==0){ if(tmp[i]==')') k1++; if(tmp[i]=='(') k1--; if(tmp[i]=='}') k2++; if(tmp[i]=='{') k2--; if(tmp[i]==']') k3++; if(tmp[i]=='[') k3--; } if(i==-1 || tmp[i] == '=' || tmp[i] == ','){ aft = ""; bef = tmp.substr(0, i+1); arg1 = tmp.substr(i+1,p-(i+1)); arg2 = tmp.substr(p+3); arg2 = arg2.substr(0, arg2.size()-1); } else if(k1 < 0 || k2 < 0 || k3 < 0){ j = pairBracket(tmp, i); bef = tmp.substr(0, i+1); arg1 = tmp.substr(i+1, p-(i+1)); arg2 = tmp.substr(p+3, j-(p+3)); aft = tmp.substr(j); aft = aft.substr(0, aft.size()-1); } else { continue; } trim(bef); trim(aft); trim(arg1); trim(arg2); if(mode=="pow_L"){ tmp = bef + "(" + arg1 + " = pow_L(" + arg1 + "," + arg2 + "))" + aft + ";"; ifun.doit.insert((string)"pow"); } else if(mode=="moddw"){ tmp = bef + "(" + arg1 + " = moddw_L(" + arg1 + "," + arg2 + "))" + aft + ";"; ifun.doit.insert((string)"moddw"); } else { tmp = bef + mode + "(" + arg1 + ", " + arg2 + ")" + aft + ";"; } break; } } return tmp; } string sentence_inequation(string tmp){ int i, j, k, ls = 0, ok; int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0; string send, recv, tmp2; vector<string> vs, vs2; rep(i,tmp.size()){ k = -1; REP(j,1,tmp.size()-i){ if(j>100) break; if(isValidVarType(tmp.substr(i,j), tmp[i+j])) k = j; } if(k > 0){ i += k-1; continue; } if(tmp[i]=='<'){ int k6 = 0; REP(j,i,tmp.size()){ if(tmp[j] == '<') k6++; if(tmp[j] == '>') k6--; if(k6==0) break; } if(j<tmp.size()){ j++; tmp2 = tmp.substr(i+1, j-i-2); trim(tmp2); vs2 = split_p(tmp2, ','); ok = 0; rep(k,vs2.size()){ trim(vs2[k]); if(isValidVarType(vs2[k], ' ')) ok++; } if(ok){ i = j; continue; } } } if( (k4 || k5) && tmp[i]=='\\' ){ i++; continue; } if(k4==0 && k5==0){ if(tmp[i]=='(') k1++; if(tmp[i]==')') k1--; if(tmp[i]=='[') k2++; if(tmp[i]==']') k2--; if(tmp[i]=='{') k3++; if(tmp[i]=='}') k3--; } if(tmp[i]=='\'') k4 ^= 1; if(tmp[i]=='"') k5 ^= 1; if(k1 == 0 && k2 == 0 & k3 == 0 && k4 == 0 && k5 == 0){ if(tmp.substr(i,2) == "->"){ i++; continue; } if(tmp.substr(i,2) == ">>"){ i++; continue; } if(tmp.substr(i,2) == "<<"){ i++; continue; } if(tmp.substr(i,2) == ">=" || tmp.substr(i,2) == "<=" || tmp.substr(i,2) == "==" || tmp.substr(i,2) == "!=" || tmp.substr(i,2) == "||" || tmp.substr(i,2) == "&&"){ if(ls < i){ vs.push_back( tmp.substr(ls, i-ls) ); ls = i; } i++; vs.push_back( tmp.substr(ls, i+1-ls) ); ls = i+1; continue; } if(tmp[i]=='<' || tmp[i]=='>' || tmp[i]==';' || tmp[i]==':' || tmp[i]=='?'){ if(ls < i){ vs.push_back( tmp.substr(ls, i-ls) ); ls = i; } vs.push_back( tmp.substr(ls, i+1-ls) ); ls = i+1; continue; } } } i = tmp.size(); if(ls < i){ vs.push_back( tmp.substr(ls, i-ls) ); ls = i; } tmp = ""; rep(i,vs.size()){ if(vs[i]=="<" || vs[i]==">" || vs[i]=="<=" || vs[i]==">=" || vs[i]=="==" || vs[i]=="!="){ if(i-2>=0 && (vs[i-2]=="<" || vs[i-2]==">" || vs[i-2]=="<=" || vs[i-2]==">=" || vs[i-2]=="==" || vs[i-2]=="!=")){ if(!( vs[i-2]=="<" && vs[i]==">")){ tmp += " && " + vs[i-1]; } } } tmp += vs[i]; } rep(i,tmp.size()){ if( (k4 || k5) && tmp[i]=='\\' ){ i++; continue; } if(k4==0 && k5==0){ if(tmp[i]=='(') k1++; if(tmp[i]==')') k1--; if(tmp[i]=='[') k2++; if(tmp[i]==']') k2--; if(tmp[i]=='{') k3++; if(tmp[i]=='}') k3--; } if(tmp[i]=='\'') k4 ^= 1; if(tmp[i]=='"') k5 ^= 1; if(k1==1 && k2==0 && k3==0 && k4==0 && k5==0 && tmp[i]=='('){ j = pairBracket(tmp, i); send = tmp.substr(i+1, j-i-1); recv = sentence_inequation(send); tmp = tmp.substr(0, i+1) + recv + tmp.substr(j); } if(k1==0 && k2==1 && k3==0 && k4==0 && k5==0 && tmp[i]=='['){ j = pairBracket(tmp, i); send = tmp.substr(i+1, j-i-1); recv = sentence_inequation(send); tmp = tmp.substr(0, i+1) + recv + tmp.substr(j); } if(k1==0 && k2==0 && k3==1 && k4==0 && k5==0 && tmp[i]=='{'){ j = pairBracket(tmp, i); send = tmp.substr(i+1, j-i-1); recv = sentence_inequation(send); tmp = tmp.substr(0, i+1) + recv + tmp.substr(j); } } return tmp; } string sentence_times_operator(string tmp){ int i, j, k, ok; int k1, k2; string now; pair<string,char> stchar; for(;;){ int fg = 0; k1 = k2 = 0; now = ""; rep(i,tmp.size()){ ok = 1; if((k1 || k2) && tmp[i]=='\\'){ i++; continue; } if(k2==0 && tmp[i]=='"') k1 ^= 1; if(k1==0 && tmp[i]=='\'') k2 ^= 1; if(k1 || k2) continue; if(isalnum(tmp[i]) || tmp[i]=='_' || tmp[i]=='.') now += tmp[i]; else now = ""; if(now[0]=='.' && !isdigit(now[1])) ok = 0; if(!isdigit(now[0]) && now[0]!='.') ok = 0; if((tmp[i+1]=='d' || tmp[i+1]=='e' || tmp[i+1]=='D' || tmp[i+1]=='E') && (isdigit(tmp[i+2])||tmp[i+2]=='-')) ok = 0; if(tmp.substr(i+1,1)=="u" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,1)=="U" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,1)=="l" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,1)=="L" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,1)=="f" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,1)=="F" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0; if(tmp.substr(i+1,2)=="ll" && (!isalnum(tmp[i+3]) && tmp[i+3]!='_')) ok = 0; if(tmp.substr(i+1,2)=="LL" && (!isalnum(tmp[i+3]) && tmp[i+3]!='_')) ok = 0; if(tmp.substr(i+1,3)=="ull" && (!isalnum(tmp[i+4]) && tmp[i+4]!='_')) ok = 0; if(tmp.substr(i+1,3)=="ULL" && (!isalnum(tmp[i+4]) && tmp[i+4]!='_')) ok = 0; j = i + 1; while(j < tmp.size() && isspace(tmp[j])) j++; if(j==i+1 && (isdigit(tmp[j]) || tmp[j]=='.')) ok = 0; if(!(isalnum(tmp[j]) || tmp[j]=='_' || tmp[j]=='.' || tmp[j]=='(')) ok = 0; if(ok){ tmp = tmp.substr(0,i+1) + "*" + tmp.substr(i+1); // int len = getExprLength_firstind(tmp, j); // tmp = tmp.substr(0,i+1-now.size()) + "(" + tmp.substr(i+1-now.size(),now.size()) + "*" + tmp.substr(i+1,len) + ")" + tmp.substr(i+1+len); fg = 1; break; } } if(!fg) break; } return tmp; } string sentence_pow_operator(string tmp){ int i, j, k, st = 0; int bi, bj, ei, ej; int len_i, len_j; string bef, t1, t2, aft; while(strpos_ns(tmp, (string)"**", st) >= 0){ k = strpos_ns(tmp, (string)"**", st); st = k+1; i = k-1; while(i >= 0 && isspace(tmp[i])) i--; if(i < 0 || isOperator(tmp[i])) continue; for(j=i;j>=0&&j>=i-100;j--) if(isValidVarType(tmp.substr(j,i-j+1),tmp[i+1])) break; if(j>=0 && j>=i-100) continue; j = k+2; while(j < tmp.size() && isspace(tmp[j])) j++; if(j == tmp.size()) continue; len_i = getExprLength_lastind(tmp, i); len_j = getExprLength_firstind(tmp, j); bi = i - len_i + 1; ei = i; bj = j; ej = j + len_j - 1; bef = tmp.substr(0, bi); t1 = tmp.substr(bi, ei-bi+1); t2 = tmp.substr(bj, ej-bj+1); aft = tmp.substr(ej+1); trim(t1); trim(t2); if(t2 == "2"){ tmp = bef + "pow2_L(" + t1 + ")" + aft; ifun.doit.insert((string)"pow2"); } else if(t2 == "3"){ tmp = bef + "pow3_L(" + t1 + ")" + aft; ifun.doit.insert((string)"pow3"); } else if(t2 == "4"){ tmp = bef + "pow4_L(" + t1 + ")" + aft; ifun.doit.insert((string)"pow4"); } else { tmp = bef + "pow_L(" + t1 + "," + t2 + ")" + aft; ifun.doit.insert((string)"pow"); } st = 0; } return tmp; } string sentence_div_operator(string tmp){ int i, j, k, st = 0, loop; int bi, bj, ei, ej; int len_i, len_j; string bef, t1, t2, aft, op; rep(loop,2){ if(loop==0) op = "/+"; if(loop==1) op = "%%"; while(strpos_ns(tmp, op, st) >= 0){ k = strpos_ns(tmp, op, st); st = k+1; i = k-1; while(i >= 0 && isspace(tmp[i])) i--; if(i < 0 || isOperator(tmp[i])) continue; j = k+2; while(j < tmp.size() && isspace(tmp[j])) j++; if(j == tmp.size()) continue; len_i = getExprLength_lastind(tmp, i); len_j = getExprLength_firstind(tmp, j); bi = i - len_i + 1; ei = i; bj = j; ej = j + len_j - 1; bef = tmp.substr(0, bi); t1 = tmp.substr(bi, ei-bi+1); t2 = tmp.substr(bj, ej-bj+1); aft = tmp.substr(ej+1); trim(t1); trim(t2); if(loop==0){ tmp = bef + "divup_L(" + t1 + "," + t2 + ")" + aft; ifun.doit.insert((string)"divup"); } if(loop==1){ tmp = bef + "moddw_L(" + t1 + "," + t2 + ")" + aft; ifun.doit.insert((string)"moddw"); } st = 0; } } return tmp; } string sentence_minmax_function(string tmp, int blocked = 1){ int i, j, k, nv, mode; string tp, cd, var, bg, ed, eqn, ieq, indvar; vector<string> vs, unusedname, vararr, tmpvs; for(;;){ vs.clear(); if(vs.size()==0){ vs = findFunction(tmp, "argmin()"); tp = "argmin"; } if(vs.size()==0){ vs = findFunction(tmp, "argmax()"); tp = "argmax"; } if(vs.size()==0){ vs = findFunction(tmp, "argminL()"); tp = "argminL"; } if(vs.size()==0){ vs = findFunction(tmp, "argmaxL()"); tp = "argmaxL"; } if(vs.size()==3){ var = getUnusedVarName(); trim(vs[1]); j = vs[1].size() - 1; assert(vs[1][j]==')'); i = pairBracket(vs[1], j); vs[1] = tp+"["+var+"=0---("+vs[1].substr(i+1,j-i-1)+")-1]("+vs[1].substr(0,i)+"["+var+"])"; tmp = vs[0] + vs[1] + vs[2]; continue; } if(vs.size()==0){ vs = findFunction(tmp, "min[]()"); if(vs.size() == 4) ieq = ">", mode = 0; } if(vs.size()==0){ vs = findFunction(tmp, "max[]()"); if(vs.size() == 4) ieq = "<", mode = 0; } if(vs.size()==0){ vs = findFunction(tmp, "argmin[]()"); if(vs.size() == 4) ieq = ">", mode = 1; } if(vs.size()==0){ vs = findFunction(tmp, "argmax[]()"); if(vs.size() == 4) ieq = "<", mode = 1; } if(vs.size()==0){ vs = findFunction(tmp, "argminL[]()"); if(vs.size() == 4) ieq = ">=", mode = 1; } if(vs.size()==0){ vs = findFunction(tmp, "argmaxL[]()"); if(vs.size() == 4) ieq = "<=", mode = 1; } if(vs.size()==0) break; tp = getEquationType(vs[2]); vararr = split_p(vs[1], ','); nv = vararr.size(); unusedname.clear(); rep(i,nv+3) unusedname.push_back( getUnusedVarName() ); indvar = getUnusedVarName(); if(blocked) cd += "{"; cd += "int " + unusedname[0]; REP(i,1,nv) cd += ", " + unusedname[i]; cd += ", " + unusedname[nv] + " = 0;"; cd += tp + " " + unusedname[nv+1] + ", " + unusedname[nv+2] + ";"; if(mode) cd += "int " + indvar + ";"; eqn = vs[2]; rep(i,nv){ tmpvs = split_p(vararr[i], '='); var = tmpvs[0]; j = strpos_ns(tmpvs[1], "---"); assert(j >= 0); bg = tmpvs[1].substr(0, j); ed = tmpvs[1].substr(j+3); cd += "rep(" + unusedname[i] + ", " + bg + ", (" + ed +")+1) "; replaceAll_ns_t(eqn, var, unusedname[i]); } cd += "{"; cd += unusedname[nv+2] + " = " + eqn + ";"; cd += "if(" + unusedname[nv] + "==0 || " + unusedname[nv+1] + ieq + unusedname[nv+2] + "){"; cd += unusedname[nv+1] + " = " + unusedname[nv+2] + ";"; cd += unusedname[nv] + " = 1;"; if(mode) cd += indvar + " = " + unusedname[0] + ";"; cd += "}"; cd += "}"; if(blocked){ if(mode==0) cd += vs[0] + unusedname[nv+1] + vs[3]; if(mode==1) cd += vs[0] + indvar + vs[3]; cd += "}"; insert(cd, str.size()); return ""; } else { insert(cd, str.size()); if(mode==0) tmp = vs[0] + unusedname[nv+1] + vs[3]; if(mode==1) tmp = vs[0] + indvar + vs[3]; } } return tmp; } string sentence_sortE(string tmp){ int i, j, n; string stc, op; vector<string> vs, e; if(vs.size() == 0){ vs = findFunction(tmp, "sortE()"); if(vs.size() > 0) op = ">"; } if(vs.size() == 0){ vs = findFunction(tmp, "rsortE()"); if(vs.size() > 0) op = "<"; } if(vs.size()==0) return tmp; e = split_p(vs[1], ','); n = e.size(); rep(i,n) trim(e[i]); for(j=n-1;j;j--){ rep(i,j){ stc += "if(" + e[i] + " " + op + " " + e[i+1] + ") swap(" + e[i] + ", " + e[i+1] + ");"; } } stc = vs[0] + stc + vs[2]; insert(stc, str.size()); return ""; } string sentence_reader(string tmp){ int i, j, k; int inc; pair<string, char> stchar; vector<string> vtmp, vvtmp; string at, stmp; stchar = nextToken(tmp); if( (stchar.first == "rd" || stchar.first == "reader") && stchar.second == '(' ){ trim_until(tmp, '(', ')'); tmp = tmp.substr(1,tmp.size()-2); vtmp = split_p(tmp, ','); rep(k,vtmp.size()){ trim(vtmp[k]); string stc, trail; string strtmp; vector<string> vstrtmp; strtmp = vtmp[k]; trim(strtmp); vstrtmp = rd_wt_array(strtmp); if(vstrtmp.size() > 1){ string vn = getUnusedVarName(), var; vector<string> vars; if(vstrtmp[1][0]=='('){ vstrtmp[1] = vstrtmp[1].substr(1, vstrtmp[1].size()-2); vars = split_p(vstrtmp[1], ','); } else { vars.push_back(vstrtmp[1]); } var = ""; rep(j,vars.size()){ if(j) var += ", "; trim(vars[j]); trail = ""; while(vars[j].size() >= 2 && (vars[j].substr(vars[j].size()-2)=="++" || vars[j].substr(vars[j].size()-2)=="--")){ trail = trail + vars[j].substr(vars[j].size()-2); vars[j] = vars[j].substr(0, vars[j].size()-2); trim(vars[j]); } vvtmp = split_p(vars[j], '@'); stmp = ""; rep(i,vvtmp.size()){ if(i) stmp += (string)"@"; stmp += vvtmp[i] + "[" + vn + "]" + trail; } //fprintf(stderr, "%s\n", stmp.c_str()); var += vstrtmp[0] + stmp + vstrtmp[3]; } stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") rd(" + var + "); }"; insert(stc, str.size()); } else { vvtmp = split_p(vstrtmp[0], '@'); at = ""; inc = 0; if(vvtmp.size()>=2){ vstrtmp[0] = vvtmp[0]; at = vvtmp[1]; trim(vstrtmp[0]); trim(at); } for(;;){ if(vstrtmp[0].length() >= 2 && vstrtmp[0].substr(vstrtmp[0].length()-2) == "++"){ inc++; vstrtmp[0] = vstrtmp[0].substr(0, vstrtmp[0].length()-2); trim(vstrtmp[0]); continue; } if(vstrtmp[0].length() >= 2 && vstrtmp[0].substr(vstrtmp[0].length()-2) == "--"){ inc--; vstrtmp[0] = vstrtmp[0].substr(0, vstrtmp[0].length()-2); trim(vstrtmp[0]); continue; } break; } string etype = getElementalyVarType(vstrtmp[0]); //fprintf(stderr, "type estimation: [%s] [%s]\n",etype.c_str(), vstrtmp[0].c_str()); if(etype=="int" || etype=="signed" || etype=="signed int"){ ifun.doit.insert((string)"reader_int"); } else if(etype=="long long" || etype=="signed long long" || etype=="ll"){ ifun.doit.insert((string)"reader_ll"); } else if(etype=="unsigned" || etype=="unsigned int" || etype=="uint"){ ifun.doit.insert((string)"reader_unsigned"); } else if(etype=="unsigned long long" || etype=="ull"){ ifun.doit.insert((string)"reader_ull"); } else if(etype=="int8_t" || etype=="int16_t" || etype=="int32_t" || etype=="int64_t" || etype=="__int8_t" || etype=="__int16_t" || etype=="__int32_t" || etype=="__int64_t" || etype=="__int128_t"){ ifun.doit.insert((string)"reader_int"); ifun.doit.insert((string)"reader_ll"); } else if(etype=="uint8_t" || etype=="uint16_t" || etype=="uint32_t" || etype=="uint64_t" || etype=="__uint8_t" || etype=="__uint16_t" || etype=="__uint32_t" || etype=="__uint64_t" || etype=="__uint128_t"){ ifun.doit.insert((string)"reader_unsigned"); ifun.doit.insert((string)"reader_ull"); } else if(etype=="Modint"){ ifun.doit.insert((string)"reader_Modint"); } else if(etype=="Mint"){ ifun.doit.insert((string)"reader_Mint"); } else if(etype=="modint"){ ifun.doit.insert((string)"reader_modint"); } else if(etype=="mint"){ ifun.doit.insert((string)"reader_mint"); } else if(etype=="double"){ ifun.doit.insert((string)"reader_double"); } else if(etype=="char"){ ifun.doit.insert((string)"reader_char"); ifun.doit.insert((string)"reader_char_array"); } else if(etype=="string"){ ifun.doit.insert((string)"reader_string"); } else { fprintf(stderr, "unknown type [%s] for rd (reader) : %s\n", etype.c_str(), vtmp[k].c_str()); assert(0); } if(at!="") stc = at + " = rd(" + vstrtmp[0] + ");"; else stc = (string)"rd(" + vstrtmp[0] + ");"; if(inc){ char tmpbuf[10]; sprintf(tmpbuf, "%d", inc); stc += vstrtmp[0] + " += (" + tmpbuf + ");"; } str.push_back(stc); nxt.push_back(-1); strtype.push_back((string)"sentence"); } } return ""; } return tmp; } string sentence_writer(string tmp){ int i, j, k; string mode; pair<string, char> stchar; vector<string> vtmp; stchar = nextToken(tmp); if( (stchar.first == "wt" || stchar.first == "writer" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wt"; if( (stchar.first == "wtSp" || stchar.first == "writerSp") && (stchar.second == '[' || stchar.second == '(') ) mode = "wtSp"; if( (stchar.first == "wtLn" || stchar.first == "writerLn") && (stchar.second == '[' || stchar.second == '(') ) mode = "wtLn"; if( (stchar.first == "wtN" || stchar.first == "writerN" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wtN"; if( (stchar.first == "wtF" || stchar.first == "writerF" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wtF"; if(mode=="") return tmp; string optarg = "", basestr = ""; if(stchar.second == '['){ int ss, tt; string stmp; vector<string> vtmp1, vtmp2; pair<string,char> ctmp; ss = strpos(tmp, "["); tt = pairBracket(tmp, ss); optarg = tmp.substr(ss, tt-ss+1); tmp = tmp.substr(tt+1); stmp = optarg.substr(1, optarg.size()-2); vtmp1 = split_p(stmp, ','); rep(k,vtmp1.size()){ trim(vtmp1[k]); ctmp = nextToken(vtmp1[k]); if(ctmp.first == "B" && ctmp.second == '='){ vtmp2 = split_p(vtmp1[k], '='); trim(vtmp2[1]); basestr = "," + vtmp2[1]; } } } trim_until(tmp, '(', ')'); tmp = tmp.substr(1,tmp.size()-2); if(mode == "wtF"){ string wstr, estr, cstr; trim_until(tmp, '"', '"'); tmp = tmp.substr(1, tmp.size() - 2); i = k = 0; rep(i,tmp.size()){ if(tmp[i]=='{'){ if(wstr.size()) cstr += (string)"wtN(\"" + wstr + "\");\n"; wstr = ""; k = 1; continue; } if(tmp[i]=='}'){ if(estr.size()) cstr += (string)"wtN(" + estr + ");\n"; estr = ""; k = 0; continue; } if(tmp[i]=='\\' && (tmp[i+1]=='{' || tmp[i+1]=='}')) i++; if(k==0) wstr += tmp[i]; else estr += tmp[i]; } if(wstr.size()) cstr += (string)"wtN(\"" + wstr + "\");\n"; if(estr.size()) cstr += (string)"wtN(" + estr + ");\n"; insert(cstr, str.size()); } else { vtmp = split_p(tmp, ','); rep(k,vtmp.size()){ trim(vtmp[k]); int fg = 0, char_fg = 0; string etype = getEquationType(vtmp[k], &fg, &char_fg); string stc; //fprintf(stderr, "wt [%s] [%s] [%d] [%d]\n", etype.c_str(), vtmp[k].c_str(), fg, char_fg); if(fg) ifun.doit.insert((string)"writer_all"); if(char_fg) ifun.doit.insert((string)"writer_char_array"); ifun.doit.insert((string)"writer_char"); if(etype=="int" || etype=="signed" || etype=="signed int"){ if(basestr=="") ifun.doit.insert((string)"writer_int"); else ifun.doit.insert((string)"writer_int_withBase"); } else if(etype=="long long" || etype=="signed long long" || etype=="ll"){ if(basestr=="") ifun.doit.insert((string)"writer_ll"); else ifun.doit.insert((string)"writer_ll_withBase"); } else if(etype=="unsigned" || etype=="unsigned int" || etype=="uint"){ ifun.doit.insert((string)"writer_unsigned"); } else if(etype=="unsigned long long" || etype=="ull"){ ifun.doit.insert((string)"writer_ull"); } else if(etype=="int8_t" || etype=="int16_t" || etype=="int32_t" || etype=="int64_t" || etype=="__int8_t" || etype=="__int16_t" || etype=="__int32_t" || etype=="__int64_t" || etype=="__int128_t"){ ifun.doit.insert((string)"writer_int"); ifun.doit.insert((string)"writer_ll"); } else if(etype=="uint8_t" || etype=="uint16_t" || etype=="uint32_t" || etype=="uint64_t" || etype=="__uint8_t" || etype=="__uint16_t" || etype=="__uint32_t" || etype=="__uint64_t" || etype=="__uint128_t"){ ifun.doit.insert((string)"writer_unsigned"); ifun.doit.insert((string)"writer_ull"); } else if(etype=="Modint"){ ifun.doit.insert((string)"writer_Modint"); } else if(etype=="Mint"){ ifun.doit.insert((string)"writer_Mint"); } else if(etype=="modint"){ ifun.doit.insert((string)"writer_modint"); } else if(etype=="mint"){ ifun.doit.insert((string)"writer_mint"); } else if(etype=="double"){ ifun.doit.insert((string)"writer_double"); } else if(etype=="char"){ ifun.doit.insert((string)"writer_char_array"); } else if(etype=="string"){ ifun.doit.insert((string)"writer_string"); } else { //fprintf(stderr, "unknown type [%s] for wt (writer) : %s\n", etype.c_str(), vtmp[k].c_str()); //assert(0); } string strtmp; vector<string> vstrtmp; strtmp = vtmp[k]; trim(strtmp); vstrtmp = rd_wt_array(strtmp); if(vstrtmp.size() > 1){ string vn = getUnusedVarName(), var; if(vstrtmp[1][0]=='('){ vector<string> vars; vstrtmp[1] = vstrtmp[1].substr(1, vstrtmp[1].size()-2); vars = split_p(vstrtmp[1], ','); var = ""; rep(j,vars.size()){ if(j) var += ", "; trim(vars[j]); var += vstrtmp[0] + vars[j] + "[" + vn + "]" + vstrtmp[3]; } } else { var = vstrtmp[0] + vstrtmp[1] + "[" + vn + "]" + vstrtmp[3]; } if(mode == "wt"){ if(k==vtmp.size()-1){ stc = (string)"{\n int "+vn+";\n if("+vstrtmp[2]+"==0) putchar_unlocked('\\n');\n else {\n rep("+vn+","+vstrtmp[2]+"-1) wtSp" + optarg + "("+var+");\n wt" + optarg + "("+var+");\n }\n}"; } else { stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") wtSp" + optarg + "(" + var + "); }"; } } else { stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") " + mode + optarg + "(" + var + "); }"; } insert(stc, str.size()); } else { if(etype=="int" || etype=="long long") vstrtmp[0] += basestr; stc = (string)"wt_L(" + vstrtmp[0] + ");"; str.push_back(stc); nxt.push_back(-1); strtype.push_back((string)"sentence"); stc = ""; if(mode == "wtLn" || (mode=="wt" && k==vtmp.size()-1)){ stc = (string)"wt_L('\\n');"; } if(mode == "wtSp" || (mode=="wt" && k!=vtmp.size()-1)){ stc = (string)"wt_L(' ');"; } if(stc != ""){ str.push_back(stc); nxt.push_back(-1); strtype.push_back((string)"sentence"); } } } } return ""; } string sentence_dot_loop(string tmp){ int k, pl, pb, pa, fg = 0; int k1, k2, k3, k4, k5; string dots = ".."; string vn, stc, bg, ed, fbg, fed; if(strpos_ns(tmp, (string)"..") == -1) return tmp; while(strpos_ns(tmp, dots) >= 0) dots += "."; dots = dots.substr(1); vn = getUnusedVarName(); stc = ""; stc += (string)"{ int " + vn + ";"; for(;;){ pl = strpos_ns(tmp, dots); if(pl<0) break; k1 = k2 = k3 = k4 = k5 = 0; for(k=pl-1;k>=0;k--){ if(k4==0 && k5==0){ if(tmp[k] == '(') k1++; if(tmp[k] == ')') k1--; if(tmp[k] == '[') k2++; if(tmp[k] == ']') k2--; if(tmp[k] == '{') k3++; if(tmp[k] == '}') k3--; } if(tmp[k] == '\'') k4^=1; if(tmp[k] == '"') k5^=1; if(k1 > 0 || k2 > 0 || k3 > 0) break; } pb = k + 1; k1 = k2 = k3 = k4 = k5 = 0; REP(k,pl,tmp.size()){ if(k4==0 && k5==0){ if(tmp[k] == '(') k1++; if(tmp[k] == ')') k1--; if(tmp[k] == '[') k2++; if(tmp[k] == ']') k2--; if(tmp[k] == '{') k3++; if(tmp[k] == '}') k3--; } if(tmp[k] == '\'') k4^=1; if(tmp[k] == '"') k5^=1; if(k1 < 0 || k2 < 0 || k3 < 0) break; } pa = k; bg = tmp.substr(pb, pl-pb); ed = tmp.substr(pl+dots.size(), pa-pl-dots.size()); if(fg==0){ fg = 1; fbg = bg; fed = ed; } if(bg==fbg) tmp = tmp.substr(0, pb) + vn + tmp.substr(pa); else tmp = tmp.substr(0, pb) + vn + " - (" + fbg + ") + (" + bg + ")" + tmp.substr(pa); } stc += "rep(" + vn + ", " + fbg + ", (" + fed + ") + 1) "; stc += tmp; stc += "}"; insert(stc, str.size()); return ""; } string sentence_gcdlcm_sub(vector<string> vs, string op){ while(vs.size() > 1){ if(op=="+" || op=="*"){ vs[0] = "(" + vs[0] + ")" + op + "(" + vs[1] +")"; } else { vs[0] = op + "(" + vs[0] + ", " + vs[1] + ")"; } vs.erase(vs.begin()+1); } return vs[0]; } string sentence_gcdlcm(string tmp, int blocked = 1){ int i, j, k; string stc, func; string vn, loop_vn, vtype; vector<string> vs, arr, barr, varr, tmpvs, vsub; for(;;){ vs.clear(); if(vs.size()==0 && g_flags.count("no-gcd()")==0){ vs = findFunction(tmp,"gcd()"); if(vs.size()==3) func = "GCD_L", ifun.doit.insert((string)"gcd"); } if(vs.size()==0 && g_flags.count("no-GCD()")==0){ vs = findFunction(tmp,"GCD()"); if(vs.size()==3) func = "GCD_L", ifun.doit.insert((string)"gcd"); } if(vs.size()==0 && g_flags.count("no-lcm()")==0){ vs = findFunction(tmp,"lcm()"); if(vs.size()==3) func = "LCM_L", ifun.doit.insert((string)"lcm"); } if(vs.size()==0 && g_flags.count("no-LCM()")==0){ vs = findFunction(tmp,"LCM()"); if(vs.size()==3) func = "LCM_L", ifun.doit.insert((string)"lcm"); } if(vs.size()==0 && g_flags.count("no-min()")==0){ vs = findFunction(tmp,"min()"); if(vs.size()==3 && vs[1].size()==0) vs.clear(); if(vs.size()==3) func = "min_L", ifun.doit.insert((string)"min_L"); } if(vs.size()==0 && g_flags.count("no-MIN()")==0){ vs = findFunction(tmp,"MIN()"); if(vs.size()==3) func = "min_L", ifun.doit.insert((string)"min_L"); } if(vs.size()==0 && g_flags.count("no-max()")==0){ vs = findFunction(tmp,"max()"); if(vs.size()==3 && vs[1].size()==0) vs.clear(); if(vs.size()==3) func = "max_L", ifun.doit.insert((string)"max_L"); } if(vs.size()==0 && g_flags.count("no-MAX()")==0){ vs = findFunction(tmp,"MAX()"); if(vs.size()==3) func = "max_L", ifun.doit.insert((string)"max_L"); } if(vs.size()==0 && g_flags.count("no-sum()")==0){ vs = findFunction(tmp,"sum()"); if(vs.size()==3) func = "+"; } if(vs.size()==0 && g_flags.count("no-SUM()")==0){ vs = findFunction(tmp,"SUM()"); if(vs.size()==3) func = "+"; } if(vs.size()==0 && g_flags.count("no-mul()")==0){ vs = findFunction(tmp,"mul()"); if(vs.size()==3) func = "*"; } if(vs.size()==0 && g_flags.count("no-MUL()")==0){ vs = findFunction(tmp,"MUL()"); if(vs.size()==3) func = "*"; } if(vs.size()==0) break; stc = ""; loop_vn = getUnusedVarName(); arr = split_p(vs[1], ','); rep(k,arr.size()){ trim(arr[k]); barr = rd_wt_array(arr[k]); if(barr.size()==4){ vn = getUnusedVarName(); vtype = getEquationType(barr[1]); stc += vtype + " " + vn + ";"; if(barr[1][0]=='('){ barr[1] = barr[1].substr(1, barr[1].size()-2); varr = split_p(barr[1], ','); } else { varr.clear(); varr.push_back(barr[1]); } stc += "if(" + barr[2] + "==0){"; if(func=="*" || func=="LCM_L"){ stc += vn + " = 1;"; } else if(vtype == "string"){ stc += vn + ";"; } else { stc += vn + " = 0;"; } stc += "} else {"; vsub.clear(); rep(i,varr.size()) vsub.push_back(varr[i] + "[0]"); stc += vn + " = " + sentence_gcdlcm_sub(vsub,func) + ";"; stc += "rep(" + loop_vn + ", 1, " + barr[2] + "){"; vsub.clear(); rep(i,varr.size()) vsub.push_back(varr[i] + "[" + loop_vn + "]"); if(func=="+" || func=="*"){ stc += vn + " " + func + "= " + sentence_gcdlcm_sub(vsub,func) + ";"; } else { stc += vn + " = " + func + "(" + vn + ", " + sentence_gcdlcm_sub(vsub,func) + ");"; } stc += "}"; stc += "}"; arr[k] = vn; } } if(stc != ""){ stc = "int " + loop_vn + ";" + stc; tmp = sentence_gcdlcm_sub(arr, func); if(blocked){ stc = "{" + stc; stc += vs[0] + tmp + vs[2]; stc += "}"; insert(stc, str.size()); return ""; } else { insert(stc, str.size()); tmp = vs[0] + tmp + vs[2]; } } else { tmp = sentence_gcdlcm_sub(arr, func); tmp = vs[0] + tmp + vs[2]; } } return tmp; } string sentence_bsearch(string tmp){ int i, j, k; int min_fg, max_fg, mode_int, setL, setU; string stc, varnameL, varnameU, varnameX, block, cond; vector<string> vs, var; int AE_fg, RE_fg; string AE, RE; for(;;){ vs.clear(); min_fg = max_fg = 0; if(vs.size()==0){ vs = findFunction(tmp, "bsearch_min[]()"); if(vs.size()==4){ min_fg=1; vs.push_back(""); vs[4] = vs[3]; vs[3] = vs[2]; vs[2] = ""; } } if(vs.size()==0){ vs = findFunction(tmp, "bsearch_max[]()"); if(vs.size()==4){ max_fg=1; vs.push_back(""); vs[4] = vs[3]; vs[3] = vs[2]; vs[2] = ""; } } if(vs.size()==0){ vs = findFunction(tmp, "bsearch_min[][]()"); if(vs.size()==5) min_fg=1; } if(vs.size()==0){ vs = findFunction(tmp, "bsearch_max[][]()"); if(vs.size()==5) max_fg=1; } if(vs.size()==0) break; //fprintf(stderr, "bsearch\n"); var = split_p2(vs[1], ','); rep(i,var.size()) trim(var[i]); AE_fg = RE_fg = 0; rep(i,var.size()){ vector<string> arg = split_p2(var[i], '='); rep(j,arg.size()) trim(arg[j]); if(arg.size() == 2){ if(arg[0] == "E"){ AE_fg = RE_fg = 1; AE = RE = arg[1]; } else if(arg[0] == "AE"){ AE_fg = 1; AE = arg[1]; } else if(arg[0] == "RE"){ RE_fg = 1; RE = arg[1]; } else { assert(0 && "invalid argment in bsearch_min|max"); } var.erase( var.begin() + i ); i--; } } varnameL = getUnusedVarName(); varnameU = getUnusedVarName(); varnameX = getUnusedVarName(); setL = setU = 0; if(var.size() >= 3 && var[2] != "") setL = 1; if(var.size() >= 4 && var[3] != "") setU = 1; block = vs[2]; cond = vs[3]; replaceAll_ns_t(block, var[1], varnameX); replaceAll_ns_t(cond, var[1], varnameX); stc = var[0] + " " + varnameL + ", " + varnameU + ", " + varnameX + ";"; stc += varnameL + " = " + var[2] + ";"; stc += varnameU + " = " + var[3] + ";"; if(var[0]=="double" || var[0]=="float") mode_int = 0; else mode_int = 1; if(mode_int){ stc += "while(" + varnameL + " < " + varnameU + "){\n"; stc += "if(("+varnameL+" + "+varnameU+")%2==0){\n"; stc += " "+varnameX+" = ("+varnameL+" + "+varnameU+") / 2;\n"; stc += "} else {\n"; if(min_fg) stc += " "+varnameX+" = ("+varnameL+" + "+varnameU+" - 1) / 2;\n"; if(max_fg) stc += " "+varnameX+" = ("+varnameL+" + "+varnameU+" + 1) / 2;\n"; stc += "}\n"; stc += block; if(min_fg) stc += "if("+cond+") "+varnameU+" = "+varnameX+"; else "+varnameL+" = "+varnameX+" + 1;\n"; if(max_fg) stc += "if("+cond+") "+varnameL+" = "+varnameX+"; else "+varnameU+" = "+varnameX+" - 1;\n"; stc += "}\n"; } else { stc += "for(;;){\n"; stc += varnameX+" = ("+varnameL+" + "+varnameU+") / 2;\n"; if(AE_fg) stc += "if("+varnameU+" - "+varnameL+" < "+AE+") break;\n"; if(RE_fg) stc += "if("+varnameL+" > 0 && "+varnameU+" - "+varnameL+" < "+varnameL+" * "+RE+") break;\n"; if(RE_fg) stc += "if("+varnameU+" < 0 && "+varnameU+" - "+varnameL+" < (-"+varnameU+") * "+RE+") break;\n"; stc += "if("+varnameX+" == "+varnameL+" || "+varnameX+" == "+varnameU+") break;\n"; stc += block; if(min_fg) stc += "if("+cond+") "+varnameU+" = "+varnameX+"; else "+varnameL+" = "+varnameX+";\n"; if(max_fg) stc += "if("+cond+") "+varnameL+" = "+varnameX+"; else "+varnameU+" = "+varnameX+";\n"; stc += "}\n"; } insert(stc, str.size()); if(mode_int){ tmp = stc + vs[0] + varnameU + vs[4]; } else { tmp = stc + vs[0] + "(("+varnameL+" + "+varnameU+") / 2)" + vs[4]; } } return tmp; } string sentence_if(string tmp){ int i; string stc; vector<string> vs, var; vs = findFunction(tmp, "if[]"); if(vs.size()==0) return tmp; var = split_p(vs[1], ','); if(var.size()%2==0) var.push_back((string)""); rep(i,var.size()) trim(var[i]); // rep(i,var.size())fprintf(stderr, "--- %d %s\n", i, var[i].c_str()); stc = ""; for(i=0;i+1<var.size();i+=2){ if(i) stc += "else "; stc += "if(" + var[i] + "){"; stc += vs[0] + var[i+1] + vs[2]; stc += "}"; } stc += "else{"; stc += vs[0] + var[i] + vs[2]; stc += "}"; insert(stc, str.size()); return ""; } string sentence_otherfunctions(string tmp){ vector<string> vs, vtmp; static int readerfile = 0; static int writerfile = 0; for(;;){ vs = findFunction(tmp, "readerFile()"); if(vs.size() == 3){ ifun.doit.insert((string)"readerFile"); if(!readerfile){ int i; readerfile = 1; rep(i, ifun.name.size()) if(ifun.name[i].substr(0,7)=="reader_"){ string str = ifun.func[ifun.name[i]]; for(;;){ vtmp = findFunction(str, "getchar_unlocked()"); if(vtmp.size()!=3) break; str = vtmp[0] + "getc(readerfp)" + vtmp[2]; } ifun.func[ifun.name[i]] = str; } } } vs = findFunction(tmp, "writerFile()"); if(vs.size() == 3){ ifun.doit.insert((string)"writerFile"); if(!writerfile){ int i; writerfile = 1; rep(i, ifun.name.size()) if(ifun.name[i].substr(0,7)=="writer_"){ string str = ifun.func[ifun.name[i]]; for(;;){ vtmp = findFunction(str, "putchar_unlocked()"); if(vtmp.size()!=3) break; str = vtmp[0] + "putc( " + vtmp[1] + ", writerfp)" + vtmp[2]; } ifun.func[ifun.name[i]] = str; } } } vs = findFunction(tmp, "b[]()"); if(vs.size()==4){ int i, j; string s; vector<string> v1, v2; v1 = split_p(vs[1], ','); v2 = split_p(vs[2], ','); rep(i,v2.size()){ if(i){ j = i; if(j >= v1.size()) j = v1.size() - 1; s = "(" + s + "*(" + v1[j] + "))"; } if(i){ s = "(" + s + "+(" + v2[i] + "))"; } else { s = "(" + v2[i] + ")"; } } tmp = vs[0] + s + vs[3]; continue; } vs = findFunction(tmp, "walloc1d()"); if(vs.size() == 3) ifun.doit.insert((string)"walloc1d"); vs = findFunction(tmp, "walloc2d()"); if(vs.size() == 3) ifun.doit.insert((string)"walloc2d"); vs = findFunction(tmp, "malloc1d()"); if(vs.size() == 3) ifun.doit.insert((string)"malloc1d"); vs = findFunction(tmp, "malloc2d()"); if(vs.size() == 3) ifun.doit.insert((string)"malloc2d"); vs = findFunction(tmp, "free1d()"); if(vs.size() == 3) ifun.doit.insert((string)"free1d"); vs = findFunction(tmp, "free2d()"); if(vs.size() == 3) ifun.doit.insert((string)"free2d"); vs = findFunction(tmp, "rdLine()"); if(vs.size() == 3){ ifun.doit.insert((string)"rdLine"); tmp = vs[0] + "rdLine_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "sortA()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size()==2) ifun.doit.insert((string)"sortA_1"); if(vtmp.size()==3) ifun.doit.insert((string)"sortA_1"), ifun.doit.insert((string)"sortA_2"); if(vtmp.size()==4) ifun.doit.insert((string)"sortA_2"), ifun.doit.insert((string)"sortA_3"); if(vtmp.size()==5) ifun.doit.insert((string)"sortA_3"), ifun.doit.insert((string)"sortA_4"); tmp = vs[0] + "sortA_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "rsortA()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size()==2) ifun.doit.insert((string)"rsortA_1"); if(vtmp.size()==3) ifun.doit.insert((string)"rsortA_1"), ifun.doit.insert((string)"rsortA_2"); if(vtmp.size()==4) ifun.doit.insert((string)"rsortA_2"), ifun.doit.insert((string)"rsortA_3"); if(vtmp.size()==5) ifun.doit.insert((string)"rsortA_3"), ifun.doit.insert((string)"rsortA_4"); tmp = vs[0] + "rsortA_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "sortF()"); if(vs.size() == 3){ // 手抜き vtmp = split_p(vs[1], ','); ifun.doit.insert((string)"sortF_int"); ifun.doit.insert((string)"sortF_ll"); tmp = vs[0] + "sortF_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Unique()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size()==2 || vtmp.size()==3) ifun.doit.insert((string)"Unique1"); if(vtmp.size()==3 || vtmp.size()==4) ifun.doit.insert((string)"Unique2"); tmp = vs[0] + "Unique_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "fib_mod()"); if(vs.size()!=3) vs = findFunction(tmp, "fibonacci_mod()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size()==1){ vs[1] = vs[1] + ", MD"; ifun.doit.insert((string)"define_MD"); } ifun.doit.insert((string)"fibonacci_mod"); tmp = vs[0] + "fibonacci_mod_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "coordcomp()"); if(vs.size() != 3) vs = findFunction(tmp, "coord_comp()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() <= 4) ifun.doit.insert((string)"coordcomp_1"); if(vtmp.size() >= 4) ifun.doit.insert((string)"coordcomp_2"); tmp = vs[0] + "coordcomp_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Digit()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 1) ifun.doit.insert((string)"Digit"); if(vtmp.size() == 2) ifun.doit.insert((string)"Digit_base"); tmp = vs[0] + "Digit_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "sod()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 1) ifun.doit.insert((string)"sod"); if(vtmp.size() == 2) ifun.doit.insert((string)"sod_base"); tmp = vs[0] + "sod_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "wAdjEdge()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 6 || vtmp.size() == 7) ifun.doit.insert((string)"wAdjEdge1"); else if(vtmp.size() == 8 || vtmp.size() == 9) ifun.doit.insert((string)"wAdjEdge2"); else if(vtmp.size() == 10 || vtmp.size() == 11) ifun.doit.insert((string)"wAdjEdge3"); else if(vtmp.size() == 12 || vtmp.size() == 13) ifun.doit.insert((string)"wAdjEdge4"); else{ fprintf(stderr, "#arg of wAdjEdge is invalid\n"); assert(0); } tmp = vs[0] + "wAdjEdge_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "isPrime()"); if(vs.size() == 3){ ifun.doit.insert((string)"isPrime"); tmp = vs[0] + "isPrime_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Isqrt()"); if(vs.size() == 3){ ifun.doit.insert((string)"Isqrt_f"); tmp = vs[0] + "Isqrt_f_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Isqrt_f()"); if(vs.size() == 3){ ifun.doit.insert((string)"Isqrt_f"); tmp = vs[0] + "Isqrt_f_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Isqrt_c()"); if(vs.size() == 3){ ifun.doit.insert((string)"Isqrt_c"); tmp = vs[0] + "Isqrt_c_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Isqrt_s()"); if(vs.size() == 3){ ifun.doit.insert((string)"Isqrt_s"); tmp = vs[0] + "Isqrt_s_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Icbrt()"); if(vs.size() == 3){ ifun.doit.insert((string)"Icbrt_f"); tmp = vs[0] + "Icbrt_f_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Icbrt_f()"); if(vs.size() == 3){ ifun.doit.insert((string)"Icbrt_f"); tmp = vs[0] + "Icbrt_f_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Icbrt_c()"); if(vs.size() == 3){ ifun.doit.insert((string)"Icbrt_c"); tmp = vs[0] + "Icbrt_c_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Icbrt_s()"); if(vs.size() == 3){ ifun.doit.insert((string)"Icbrt_s"); tmp = vs[0] + "Icbrt_s_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Prime()"); if(vs.size() == 3){ ifun.doit.insert((string)"Prime"); tmp = vs[0] + "Prime_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Factor()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 1) ifun.doit.insert((string)"Factor1"); if(vtmp.size() == 2) ifun.doit.insert((string)"Factor2"); if(vtmp.size() == 3) ifun.doit.insert((string)"Factor3"); if(vtmp.size() != 1 && vtmp.size() != 2 && vtmp.size() != 3){ fprintf(stderr, "#arg of Factor is invalid\n"); assert(0); } tmp = vs[0] + "Factor_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "FactorM()"); if(vs.size() == 3){ ifun.doit.insert((string)"FactorM"); tmp = vs[0] + "FactorM_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Divisor()"); if(vs.size() == 3){ ifun.doit.insert((string)"Divisor"); tmp = vs[0] + "Divisor_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "DivisorSum()"); if(vs.size() == 3){ ifun.doit.insert((string)"DivisorSum"); tmp = vs[0] + "DivisorSum_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Moebius()"); if(vs.size() == 3){ ifun.doit.insert((string)"Moebius"); tmp = vs[0] + "Moebius_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "convolution()"); if(vs.size() == 3){ ifun.doit.insert((string)"convolution"); tmp = vs[0] + "convolution_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "ZetaTransform()"); if(vs.size() == 3){ ifun.doit.insert((string)"ZetaTransform"); tmp = vs[0] + "ZetaTransform_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "ZetaTransform_min()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 2 || vtmp.size() == 3) ifun.doit.insert((string)"ZetaTransform_min"); if(vtmp.size() == 4) ifun.doit.insert((string)"ZetaTransform_min2"); if(vtmp.size() == 5) ifun.doit.insert((string)"ZetaTransform_min3"); tmp = vs[0] + "ZetaTransform_min_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "ZetaTransform_max()"); if(vs.size() == 3){ ifun.doit.insert((string)"ZetaTransform"); tmp = vs[0] + "ZetaTransform_max_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "polationVal()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 4) ifun.doit.insert((string)"polationVal_1"); if(vtmp.size() == 3) ifun.doit.insert((string)"polationVal_2"); tmp = vs[0] + "polationVal_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "polationPoly()"); if(vs.size() == 3){ ifun.doit.insert((string)"polationPoly"); tmp = vs[0] + "polationPoly_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Explode()"); if(vs.size() == 3){ ifun.doit.insert((string)"Explode"); tmp = vs[0] + "Explode_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "Implode()"); if(vs.size() == 3){ ifun.doit.insert((string)"Implode"); tmp = vs[0] + "Implode_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "InnerProd()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size() == 2) ifun.doit.insert((string)"InnerProd_1"); if(vtmp.size() == 3) ifun.doit.insert((string)"InnerProd_2"); if(vtmp.size() == 4) ifun.doit.insert((string)"InnerProd_3"); if(vtmp.size() == 5) ifun.doit.insert((string)"InnerProd_4"); tmp = vs[0] + "InnerProd_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "crossProd()"); if(vs.size() == 3){ ifun.doit.insert((string)"crossProd"); tmp = vs[0] + "crossProd_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "LineIntersection_size()"); if(vs.size() == 3){ ifun.doit.insert((string)"LineIntersection_size"); tmp = vs[0] + "LineIntersection_size_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "BIT_popcount()"); if(vs.size() == 3){ ifun.doit.insert((string)"BIT_popcount"); tmp = vs[0] + "BIT_popcount_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "BIT_ctz()"); if(vs.size() == 3){ ifun.doit.insert((string)"BIT_ctz"); tmp = vs[0] + "BIT_ctz_L(" + vs[1] + ")" + vs[2]; continue; } vs = findFunction(tmp, "BIT_ith()"); if(vs.size() == 3){ vtmp = split_p(vs[1], ','); if(vtmp.size()==2){ trim(vtmp[0]); trim(vtmp[1]); tmp = vs[0] + "((" + vtmp[0] + ") & BIT_ith(" + vtmp[1] + "))" + vs[2]; } else { trim(vs[1]); if(isdigit(vs[1][0]) && atoi(vs[1].c_str()) >= 31) tmp = vs[0] + "(1LL<<(" + vs[1] + "))" + vs[2]; else tmp = vs[0] + "(1<<(" + vs[1] + "))" + vs[2]; } continue; } vs = findFunction(tmp, "BIT_lowest()"); if(vs.size() == 3){ tmp = vs[0] + "(-(" + vs[1] + ") & (" + vs[1] + "))" + vs[2]; continue; } vs = findFunction(tmp, "BIT_nonlowest()"); if(vs.size() == 3){ tmp = vs[0] + "((" + vs[1] + ") & ((" + vs[1] + ")-1))" + vs[2]; continue; } vs = findFunction(tmp, "knightDistance()"); if(vs.size() == 3) ifun.doit.insert((string)"knightDistance"); vs = findFunction(tmp, "LIS_length()"); if(vs.size() == 3) ifun.doit.insert((string)"LIS_length"); vs = findFunction(tmp, "weaklyLIS_length()"); if(vs.size() == 3) ifun.doit.insert((string)"weaklyLIS_length"); vs = findFunction(tmp, "longestSuffixPrefix()"); if(vs.size() == 3) ifun.doit.insert((string)"longestSuffixPrefix"); vs = findFunction(tmp, "SuffixArray()"); if(vs.size() == 3) ifun.doit.insert((string)"SuffixArray"); vs = findFunction(tmp, "isSubsequence()"); if(vs.size() == 3) ifun.doit.insert((string)"isSubsequence"); vs = findFunction(tmp, "rd_int()"); if(vs.size() == 3) ifun.doit.insert((string)"rd_int"); vs = findFunction(tmp, "runLength()"); if(vs.size() == 3) ifun.doit.insert((string)"runLength"); vs = findFunction(tmp, "slideMin()"); if(vs.size() == 3) ifun.doit.insert((string)"slideMin"); vs = findFunction(tmp, "slideMax()"); if(vs.size() == 3) ifun.doit.insert((string)"slideMax"); vs = findFunction(tmp, "intervalSieve()"); if(vs.size() == 3) ifun.doit.insert((string)"intervalSieve"); vs = findFunction(tmp, "arrcmp()"); if(vs.size() == 3) ifun.doit.insert((string)"arrcmp"); vs = findFunction(tmp, "arrRot()"); if(vs.size() == 3) ifun.doit.insert((string)"arrRot"); vs = findFunction(tmp, "arrErase()"); if(vs.size() == 3) ifun.doit.insert((string)"arrErase"); vs = findFunction(tmp, "arrInsert()"); if(vs.size() == 3) ifun.doit.insert((string)"arrInsert"); vs = findFunction(tmp, "reduceFraction()"); if(vs.size() == 3) ifun.doit.insert((string)"reduceFraction"); vs = findFunction(tmp, "inversion_range()"); if(vs.size() == 3) ifun.doit.insert((string)"inversion_range"); vs = findFunction(tmp, "inversion()"); if(vs.size() == 3) ifun.doit.insert((string)"inversion"); vs = findFunction(tmp, "MoebiusTransform()"); if(vs.size() == 3) ifun.doit.insert((string)"MoebiusTransform"); vs = findFunction(tmp, "isLeapYear()"); if(vs.size() == 3) ifun.doit.insert((string)"isLeapYear"); vs = findFunction(tmp, "numOfDaysInMonth()"); if(vs.size() == 3) ifun.doit.insert((string)"numOfDaysInMonth1"); if(vs.size() == 3) ifun.doit.insert((string)"numOfDaysInMonth2"); vs = findFunction(tmp, "dayOfWeek()"); if(vs.size() == 3) ifun.doit.insert((string)"dayOfWeek"); vs = findFunction(tmp, "dayOfWeekStr()"); if(vs.size() == 3) ifun.doit.insert((string)"dayOfWeekStr"); vs = findFunction(tmp, "isVowel()"); if(vs.size() == 3) ifun.doit.insert((string)"isVowel"); vs = findFunction(tmp, "popFirst()"); if(vs.size() == 3) ifun.doit.insert((string)"multiset_popFirst"); if(vs.size() == 3) ifun.doit.insert((string)"set_popFirst"); vs = findFunction(tmp, "getFirst()"); if(vs.size() == 3) ifun.doit.insert((string)"multiset_getFirst"); if(vs.size() == 3) ifun.doit.insert((string)"set_getFirst"); vs = findFunction(tmp, "popLast()"); if(vs.size() == 3) ifun.doit.insert((string)"multiset_popLast"); if(vs.size() == 3) ifun.doit.insert((string)"set_popLast"); vs = findFunction(tmp, "getLast()"); if(vs.size() == 3) ifun.doit.insert((string)"multiset_getLast"); if(vs.size() == 3) ifun.doit.insert((string)"set_getLast"); vs = findFunction(tmp, "KMP()"); if(vs.size() == 3) ifun.doit.insert((string)"KMP"); vs = findFunction(tmp, "Hungarian()"); if(vs.size() == 3) ifun.doit.insert((string)"Hungarian"); vs = findFunction(tmp, "setEdge()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_setEdge"); vs = findFunction(tmp, "setDirectEdge()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_setDirectEdge"); vs = findFunction(tmp, "setEdgeRootedTree()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_setEdgeRootedTree"); vs = findFunction(tmp, "reduce()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_reduce"); vs = findFunction(tmp, "getDist()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_getDist"); vs = findFunction(tmp, "cntShortest()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_cntShortest"); vs = findFunction(tmp, "scc()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_scc"); vs = findFunction(tmp, "bcc()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_bcc"); vs = findFunction(tmp, "articulation()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_articulation"); vs = findFunction(tmp, "shortestPath()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_shortestPath"); vs = findFunction(tmp, "TopologicalSort()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_TopologicalSort"); vs = findFunction(tmp, "preorder()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_preorder"); vs = findFunction(tmp, "shortestCycle()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_shortestCycle"); vs = findFunction(tmp, "shortestUndirectedCycle_length()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_shortestUndirectedCycle_length"); vs = findFunction(tmp, "maxIndependenceSet()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_maxIndependenceSet"); vs = findFunction(tmp, "countIndependenceSet()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_countIndependenceSet"); vs = findFunction(tmp, "bipartite()"); if(vs.size() == 3) ifun.doit.insert((string)"graph_bipartite"); vs = findFunction(tmp, "setEdge()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_setEdge"); vs = findFunction(tmp, "setDirectEdge()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_setDirectEdge"); vs = findFunction(tmp, "setEdgeRootedTree()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_setEdgeRootedTree"); vs = findFunction(tmp, "getDist()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_getDist"); vs = findFunction(tmp, "getDistDense()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_getDistDense"); vs = findFunction(tmp, "getDistForest()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_getDistForest"); vs = findFunction(tmp, "BellmanFord()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_BellmanFord"); vs = findFunction(tmp, "MST_Prim_cost()"); if(vs.size() == 3) ifun.doit.insert((string)"wgraph_MST_Prim_cost"); break; } return tmp; } int isOperator(char c){ if(c=='+' || c=='-' || c=='*' || c=='/' || c=='%'|| c=='=') return 1; if(c=='&' || c=='|' || c=='^' || c=='~') return 1; return 0; } void sentence_main(string tmpstr, string tmp, int tt, int &fg_return){ pair<string, char> stchar; vector<string> vtmp; code_replace(tmp); //fprintf(stderr, "sentence main [%s] [%s]\n", tmpstr.c_str(), tmp.c_str()); stchar = nextToken(tmp); if(stchar.first == "return") fg_return = 1; else fg_return = 0; tmp = sentence_dot_loop(tmp); // A[0..N-1] = 0; if(tmp=="") return; tmp = sentence_if(tmp); // if[] if(tmp=="") return; tmp = sentence_minmax_function(tmp); // min[](), max[](), argmin[](), argmax[]() if(tmp=="") return; tmp = sentence_gcdlcm(tmp); // gcd(), lcm(), min(), max(), argmin(), argmax() など if(tmp=="") return; tmp = sentence_bsearch(tmp); // bsearch_min[][](), bsearch_max[][]() など if(tmp=="") return; tmp = sentence_otherfunctions(tmp); // runLength(), reduceFraction() if(tmp=="") return; tmp = sentence_inequation(tmp); // &&の省略 if(tmp=="") return; tmp = sentence_hatena_minmax_operator(tmp); // >?=, <?=, **= if(tmp=="") return; tmp = sentence_times_operator(tmp); // *の省略 if(tmp=="") return; tmp = sentence_pow_operator(tmp); // ** if(tmp=="") return; tmp = sentence_div_operator(tmp); // /+ if(tmp=="") return; tmp = sentence_sortE(tmp); // sortE if(tmp=="") return; tmp = sentence_reader(tmp); // rd() if(tmp=="") return; tmp = sentence_writer(tmp); // wt(), wtLn(), wtSp(), wtN() if(tmp=="") return; str.push_back(tmpstr + tmp); nxt.push_back(-1); if(tt==-1){ strtype.push_back((string)"sentence"); } else { strtype.push_back((string)"sentence-var-def"); } } string equation_main(string tmp){ tmp = sentence_times_operator(tmp); tmp = sentence_inequation(tmp); tmp = sentence_pow_operator(tmp); tmp = sentence_div_operator(tmp); tmp = sentence_gcdlcm(tmp, 0); tmp = sentence_minmax_function(tmp, 0); return tmp; } void set(string &in, string tp){ int i, st, cnt, tt, fg; int k1, k2, k3, k4, k5; int end_type = 0; int fg_main = 0, fg_return = 0; string tmp, tmpstr; string str_type, str_var; vector<string> str_arg; pair<string, char> stchar; vector<string> vtmp; type = tp; set_init(); ftrim(in); if(tp != "program" && in[0]=='{') end_type = 1, in = in.substr(1); if(tp == "program") end_type = 2; for(;;){ ftrim(in); tmp_vartype.clear(); // printf("--- %s\n",in.substr(0,10).c_str()); if(in.substr(0,12) == "//no-insert-"){ for(i=12;;i++) if(isspace(in[i]) || in[i]=='\0') break; g_flags.insert(in.substr(2,i-2)); in = in.substr(i); } if(in.substr(0,13) == "//no-unlocked" && (isspace(in[13]) || in[13]=='\0')){ g_flags.insert((string)"no-unlocked"); in = in.substr(13); continue; } if(in.substr(0,10) == "//no-gcd()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-gcd()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-GCD()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-GCD()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-lcm()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-lcm()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-LCM()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-LCM()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-min()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-min()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-MIN()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-MIN()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-max()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-max()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-MAX()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-MAX()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-sum()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-sum()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-SUM()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-SUM()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-mul()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-mul()"); in = in.substr(10); continue; } if(in.substr(0,10) == "//no-MUL()" && (isspace(in[10]) || in[10]=='\0')){ g_flags.insert((string)"no-MUL()"); in = in.substr(10); continue; } if(in.substr(0,2) == "//"){ rep(i,in.size()) if(in[i] == '\n'){ i++; break; } in = in.substr(i); continue; } if(in.substr(0,2) == "/*"){ REP(i,1,in.size()) if(in.substr(i-1,2) == "*/"){ i++; break; } in = in.substr(i); continue; } if(end_type==-1) break; if(end_type==0) end_type = -1; if(in.size()==0 && end_type==2) break; if(in.size() && in[0]=='}' && end_type==1){ in = in.substr(1); if(name == "int main()" && fg_return == 0){ str.push_back((string)"return 0;"); nxt.push_back(-1); strtype.push_back((string)"sentence"); } break; } if(in.substr(0,8) == "#include"){ cnt = 0; for(i=0;;i++){ if(in[i]=='"') cnt++; if(cnt==2 || in[i]=='>'){ i++; break; } } tmp = in.substr(0, i); in = in.substr(i); str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-include"); continue; } if(in.substr(0,7) == "#define"){ int fg_puts = 1; string in_tmp = in.substr(7); stchar = nextToken(in_tmp); if(user_code && stchar.first == "MD"){ unsigned md, W, R, mdninv, RR, t; string sss, alls; char buf[100]; for(i=0;;i++) if(in_tmp[i]=='\n' || in_tmp[i]=='\r') break; sss = in_tmp.substr(0, i); trim(sss); sss = sss.substr(2); trim(sss); sscanf(sss.c_str(), "%u", &md); sprintf(buf, "#define MD (%uU)\n", md); ifun.func["define_MD"] = (string)buf; W = 32; R = (1ULL << W) % md; RR = (ull)R*R % md; mdninv = 0; t = 0; rep(i,(int)W){ if(t%2==0) t+=md, mdninv |= (1U<<i); t /= 2; } sprintf(buf, "#define MINT_W (%uU)\n", W); alls += buf; sprintf(buf, "#define MINT_R (%uU)\n", R); alls += buf; sprintf(buf, "#define MINT_RR (%uU)\n", RR); alls += buf; sprintf(buf, "#define MINT_MDNINV (%uU)\n", mdninv); alls += buf; ifun.func["define_for_Mint"] = alls; fg_puts = 0; } if(stchar.first == "PI") ifun.already.insert((string)"define_PI"); for(i=0;;i++){ if(in[i]=='\n' || in[i]=='\r') break; } tmp = in.substr(0, i); in = in.substr(i); if(fg_puts){ str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-define"); } continue; } if(in.substr(0,6) == "#undef"){ string in_tmp = in.substr(6); stchar = nextToken(in_tmp); for(i=0;;i++){ if(in[i]=='\n' || in[i]=='\r') break; } tmp = in.substr(0, i); in = in.substr(i); str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-undef"); continue; } if(in.substr(0,7) == "#pragma"){ string in_tmp = in.substr(7); stchar = nextToken(in_tmp); for(i=0;;i++){ if(in[i]=='\n' || in[i]=='\r') break; } tmp = in.substr(0, i); in = in.substr(i); str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-pragma"); continue; } stchar = nextToken(in); if(stchar.second == ':'){ for(i=0;;i++) if(in[i]==':'){ i++; break; } if(in[i]!=':'){ tmp = in.substr(0, i); in = in.substr(i); str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-label"); continue; } } if(stchar.first == "case" || stchar.first == "default"){ for(i=0;;i++) if(in[i]==':'){ i++; break; } tmp = in.substr(0, i); in = in.substr(i); str.push_back(tmp); nxt.push_back(-1); strtype.push_back((string)"sentence-case-label"); continue; } tmpstr = ""; for(;;){ stchar = nextToken(in); // printf("[%s] [%c]\n",stchar.first.c_str(),stchar.second); if(stchar.first == "template"){ cnt = 0; for(i=0;;i++){ if(in[i]=='<') cnt++; if(in[i]=='>') cnt--; if(cnt==0 && in[i]=='>'){ i++; break; } } tmpstr += in.substr(0, i) + " "; in = in.substr(i); ftrim(in); continue; } if(stchar.first == "inline"){ tmpstr += "inline "; in = in.substr(6); ftrim(in); continue; } break; } if(tmpstr.size()){ string tt = tmpstr; //fprintf(stderr, "%s\n", tt.c_str()); trim_until(tt, '<', '>'); if(tt.size() >= 2){ tt = tt.substr(1, tt.size()-2); vtmp = split_p(tt, ','); rep(i,vtmp.size()){ trim(vtmp[i]); if(vtmp[i].substr(0,6)=="class "){ vtmp[i] = vtmp[i].substr(5); trim(vtmp[i]); tmp_vartype.insert(vtmp[i]); } } } } fg = 0; tt = -1; REP(i,1,100) if(isValidVarType(in.substr(0,i), in[i])) tt = i; stchar = nextToken(in); if(tt >= 0 || in.substr(0,8)=="operator"){ for(i=0;;i++){ string tmp = in.substr(0,i); if(in[i] == '='){ if(strpos_ns_t(tmp, "operator") == -1) break; } if(in[i] == ';') break; if(strpos_ns_t(tmp, "operator")>=0 && in[i] == '(' && in[i+1]==')'){ i++; continue; } if(in[i] == '('){ int j = pairBracket(in, i); j++; while(j < in.size() && isspace(in[j])) j++; if(in[j]!='{' && in[j]!=':') break; fg++; stchar.first = "function"; break; } } } //fprintf(stderr, "[function check] %d [%s] [%s]\n", tt, in.substr(0,20).c_str(), stchar.first.c_str()); if(stchar.first == "if" && stchar.second =='(') fg = 1; if(stchar.first == "for" && stchar.second =='(') fg = 1; if(stchar.first == "rep" && stchar.second =='(') fg = 1; if(stchar.first == "REP" && stchar.second =='(') fg = 1; if(stchar.first == "rrep" && stchar.second =='(') fg = 1; if(stchar.first == "RREP" && stchar.second =='(') fg = 1; if(stchar.first == "while" && stchar.second =='(') fg = 1; if(stchar.first == "switch" && stchar.second =='(') fg = 1; if(stchar.first == "do") fg = 4; if(stchar.first == "struct") fg = 3; if(stchar.first == "class") fg = 3; if(stchar.first == "else") fg = 2; if(fg==2){ string str_t = in.substr(4,100); pair<string,char> stch_t = nextToken(str_t); if(stch_t.first == "if" && stch_t.second == '('){ fg = 1; stchar.first = "else if"; } } if(fg || in[0]=='{'){ fg_return = 0; if(fg==1 && stchar.first == "function") { rep(i,in.size()) if(in[i]=='{' || in[i] == ';') break; } else if(fg==1){ cnt = 0; k4 = k5 = 0; rep(i,in.size()){ string tmp = in.substr(0,i); if(tt>=0 && i>=tt) tmp=tmp.substr(tt); alltrim(tmp); while(tmp.size() && (tmp[0]=='*' || tmp[0]=='&')) tmp = tmp.substr(1); if(k4==0 && k5==0){ if(in[i] == '(') cnt++; if(in[i] == ')') cnt--; if(in[i] == ')' && cnt == 0 && tmp != "operator("){ i++; break; } } if(in[i]=='\'') k4 ^= 1; if(in[i]=='"') k5 ^= 1; } } else if(fg==2 || fg==4) { i = stchar.first.size(); } else if(fg==3) { rep(i,in.size()) if(in[i]=='{' || in[i] == ';') break; tmp = in.substr(0, i); trim(tmp); vtmp = split_p(tmp, ' '); if(tmpstr.size() == 0) add_vartype(vtmp[vtmp.size()-1]); else add_tvartype(vtmp[vtmp.size()-1]); } else { i = 0; } tmp = in.substr(0, i); in = in.substr(i); //fprintf(stderr, "[[ %s /// %s /// fg = %d]]\n", tmp.c_str(), in.substr(0,10).c_str(), fg); //exit(0); code_replace(tmp); tmp = equation_main(tmp); if(type=="program" && tmp=="" && fg_main==0) tmp = "int main()", fg_main = 1; if(tmp.substr(0,3) == "rep" || tmp.substr(0,3) == "REP" || tmp.substr(0,4) == "rrep" || tmp.substr(0,4) == "RREP"){ int REP_fg = 0, rrep_fg = 0; if(tmp.substr(0,3) == "REP") REP_fg = 1; if(tmp.substr(0,4) == "rrep") rrep_fg = 1; if(tmp.substr(0,4) == "RREP") REP_fg = rrep_fg = 1; while(tmp[0]!='(') tmp = tmp.substr(1); while(tmp[tmp.size()-1]!=')') tmp = tmp.substr(0, tmp.size()-1); tmp = tmp.substr(1, tmp.size()-2); str_arg = split_p(tmp, ','); rep(i,str_arg.size()) trim(str_arg[i]); if(str_arg.size()==1){ str_arg.push_back(str_arg[0]); str_arg[0] = getUnusedVarName(); } if(str_arg.size()==2){ str_arg.push_back(str_arg[1]); str_arg[1] = "0"; } if(localvar.count(str_arg[0])==0 && argvar.count(str_arg[0])==0 && globalvar.count(str_arg[0])==0){ string vardef; pair<string,string> vardefs; vardef = "int " + str_arg[0] + ";"; vardefs = var_definition(vardef); add_localvar(vardefs.first, vardefs.second); } if(REP_fg){ int agn; string doit, tvn; tvn = getUnusedVarName(); if(rrep_fg==0) agn = 2; else agn = 1; doit = "inplace_L int " + tvn + " = " + str_arg[agn] + ";"; insert(doit, str.size()); str_arg[agn] = tvn; } if(REP_fg && str_arg.size() >= 4){ int agn = 3; string doit, tvn; tvn = getUnusedVarName(); doit = "inplace_L int " + tvn + " = " + str_arg[agn] + ";"; insert(doit, str.size()); str_arg[agn] = tvn; } if(str_arg.size()==3 && rrep_fg==0){ tmp = (string)"for(" + str_arg[0] + "=(" + str_arg[1] + ");" + str_arg[0] + "<(" + str_arg[2] + ");" + str_arg[0] + "++)"; } else if(str_arg.size()==3 && rrep_fg==1){ tmp = (string)"for(" + str_arg[0] + "=(" + str_arg[2] + ")-1;" + str_arg[0] + ">=(" + str_arg[1] + ");" + str_arg[0] + "--)"; } else if(str_arg.size()==4 && rrep_fg==0){ tmp = (string)"for(" + str_arg[0] + "=(" + str_arg[1] + ");" + str_arg[0] + "<(" + str_arg[2] + ");" + str_arg[0] + "+=(" + str_arg[3] + "))"; } else if(str_arg.size()==4 && rrep_fg==1){ tmp = (string)"for(" + str_arg[0] + "=(" + str_arg[2] + ")-1;" + str_arg[0] + ">=(" + str_arg[1] + ");" + str_arg[0] + "-=(" + str_arg[3] + "))"; } else { assert(0); } stchar.first = "for"; } code *cc = new code; cc->setUpnode(this); if(tmpstr.size()){ string tt = tmpstr; trim_until(tt, '<', '>'); // assert(tt.size()>=2); if(tt.size() >= 2){ tt = tt.substr(1, tt.size()-2); vtmp = split_p(tt, ','); rep(i,vtmp.size()){ trim(vtmp[i]); if(vtmp[i].substr(0,6)=="class "){ vtmp[i] = vtmp[i].substr(5); trim(vtmp[i]); cc->vartype.insert(vtmp[i]); } } } } if(stchar.first == "function"){ int j; string ttt = tmp, tttt; pair<string,string> ss; //fprintf(stderr,"+-+-- %s\n",ttt.c_str()); trim_until(ttt, '(', ')'); assert(ttt.size()>=2); j = pairBracket(ttt, 0); ttt = ttt.substr(0,j+1); //fprintf(stderr,"+-+-- %s\n",ttt.c_str()); tttt = ttt; alltrim(tttt); if(tttt.size() > 3 && tttt.substr(0,3)=="()("){ int tind = pairBracket(ttt, 0); ttt = ttt.substr(tind+1); } ttt = ttt.substr(1, ttt.size()-2); vtmp = split_p(ttt, ','); rep(i,vtmp.size()){ trim(vtmp[i]); if(vtmp[i].size()==0 || vtmp[i]=="void") continue; ss = cc->var_definition(vtmp[i]); cc->argvar[ss.first] = ss.second; } } if(stchar.first == "for"){ } tmp = sentence_otherfunctions(tmp); cc->name = tmpstr + tmp; cc->set(in, (string)"block"); nxt.push_back(nxtlst.size()); nxtlst.push_back(cc); str.push_back(tmpstr + tmp); strtype.push_back((string)"block-"+stchar.first); continue; } k1 = k2 = k3 = k4 = k5 = 0; st = 0; if(tt != -1) st = tt; for(i=st;;i++){ int is_not_vardef = 0; if(k4==0 && k5==0){ if(in[i] == '(') k1++; if(in[i] == ')') k1--; if(in[i] == '[') k2++; if(in[i] == ']') k2--; if(in[i] == '{') k3++; if(in[i] == '}') k3--; } if(in[i] == '\'') k4^=1; if(in[i] == '"') k5^=1; if( (k4||k5) && in[i] == '\\') {i++; continue;} if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0){ string insubstr = in.substr(0,i); int stpos = 0, hatena_flag = 0; while(stpos < i){ stpos = strpos_ns(insubstr, "?", stpos); if(stpos == -1) break; if(insubstr.substr(stpos-1,3) == ">?=" || insubstr.substr(stpos-1,3) == "<?="){ stpos++; continue; } hatena_flag = 1; break; } if((hatena_flag == 0 && in[i] == ',') || in[i] == ';'){ tmp = in.substr(st, i+1-st); /*if(tt>=0)*/ tmp[tmp.size()-1] = ';'; if(tt >= 0){ int before_count = insert_count; //fprintf(stderr, "[%s] [%s]\n", str_type.c_str(), tmp.c_str()); if(isalnum(tmp[0]) || tmp[0]=='_') tmp = " "+tmp; str_type = in.substr(0, tt); tmp = str_type + tmp; //fprintf(stderr, "1: %s\n",tmp.c_str()); code_replace(tmp); //fprintf(stderr, "2: %s\n",tmp.c_str()); pair<string,string> pss = var_definition(tmp); str_var = pss.first; str_type = pss.second; //fprintf(stderr, "3: [%s] [%s]\n", str_var.c_str(), str_type.c_str()); if(insert_count != before_count){ vector<string> vvs = split_p(str_type, ','); tmp = vvs[0] + " " + str_var + " = " + vvs[3] + ";"; vvs[3] = ""; str_type = vvs[0] + "," + vvs[1] + "," + vvs[2] + "," + vvs[3]; is_not_vardef = 0; } if(/*up==NULL &&*/ str_type.substr(0,10)!="inplace_L "){ str_type = "inplace_L " + str_type; tmp = "inplace_L " + tmp; } //fprintf(stderr, "%s %s\n",str_type.c_str(),str_var.c_str()); add_localvar(str_var, str_type); } sentence_main(tmpstr, tmp, is_not_vardef?-1:tt, fg_return); if(in[i] == ','){ st = i+1; continue; } else { i++; break; } } } } in = in.substr(i); continue; } } void debug_writer(int tab = 0){ int i, j; std::set<string>::iterator it1; map<string,string>::iterator it2; printf("vartype :"); for(it1=vartype.begin();it1!=vartype.end();it1++) printf(" (%s)", it1->c_str()); puts(""); printf("tvartype :"); for(it1=tvartype.begin();it1!=tvartype.end();it1++) printf(" (%s)", it1->c_str()); puts(""); printf("localvar :"); for(it2=localvar.begin();it2!=localvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts(""); printf("globalvar:"); for(it2=globalvar.begin();it2!=globalvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts(""); printf("argvar :"); for(it2=argvar.begin();it2!=argvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts(""); rep(i,str.size()){ rep(j,tab) printf(" "); printf("%4d: %s [%s]\n",i,str[i].c_str(),strtype[i].c_str()); if(nxt[i]>=0) nxtlst[nxt[i]]->debug_writer(tab+4); } } void output_vardef(int mode, int tab){ int i, f; std::set<string> tp; std::set<string>::iterator it; vector<string> tmp; map<string,string>::iterator mt; for(mt=localvar.begin(); mt!=localvar.end(); mt++){ //fprintf(stderr, "%s\n", mt->second.c_str()); tmp = split_p2(mt->second, ','); assert(tmp.size()==4); if(tmp[0].substr(0,10) == "inplace_L ") continue; tp.insert(tmp[0]); } for(it=tp.begin(); it!=tp.end(); it++){ rep(i,tab) printf(" "); f = 0; for(mt=localvar.begin(); mt!=localvar.end(); mt++){ tmp = split_p2(mt->second, ','); assert(tmp.size()==4); if(*it == tmp[0]){ if(f) printf(", "); else printf("%s ", it->c_str()); f++; printf("%s%s%s", tmp[1].c_str(), mt->first.c_str(), tmp[2].c_str()); if(tmp[3].size() != 0) printf("=%s",tmp[3].c_str()); } } printf(";\n"); } } void output(int mode, int tab = 0){ int i, j; int var = 0; string s; rep(i,str.size()+1){ if(i==str.size()){ if(var==0) output_vardef(mode, tab); var = 1; break; } if(strtype[i]=="sentence-var-def"){ if(str[i].substr(0,10) != "inplace_L ") continue; str[i] = str[i].substr(10); } if(var==0 && (type != "program" || strtype[i] != "block-inserted" || i==str.size()-1)){ var = 1; output_vardef(mode, tab); } if(strtype[i]=="block-inserted"){ nxtlst[nxt[i]]->output(mode, tab); continue; } rep(j,tab) printf(" "); s = str[i]; if(g_flags.count((string)"no-unlocked")) replaceAll_ns_t(s, "putchar_unlocked", "putchar"); if(g_flags.count((string)"no-unlocked")) replaceAll_ns_t(s, "getchar_unlocked", "getchar"); printf("%s",s.c_str()); if(strtype[i]=="block-while"){ if(nxtlst[nxt[i]]->is_empty_block()){ printf(";\n"); continue; } } if(strtype[i].substr(0,5)=="block"){ printf("{\n"); } else { printf("\n"); } if(nxt[i]>=0) nxtlst[nxt[i]]->output(mode, tab+(mode==0?2:0)); if(strtype[i].substr(0,5)=="block"){ rep(j,tab) printf(" "); printf("}\n"); } } } }; int main(int argc, char **argv){ int i, k, f; char buf[10001]; string str, str_store; if(argc >= 2) str = argv[1]; if(str == "-lib"){ str = ""; for(;;){ k = fread(buf, 1, 10000, stdin); buf[k] = '\0'; str += buf; if(k < 10000) break; } putchar('"'); rep(i,str.size()){ if(str.substr(i,6)=="-----\n"){ putchar('"'); putchar('\n'); putchar('"'); i += 5; continue; } if(str.substr(i,7)=="-----\r\n"){ putchar('"'); putchar('\n'); putchar('"'); i += 6; continue; } if(str[i]=='"'){ putchar('\\'); putchar('"'); } else if(str[i]=='\\'){ putchar('\\'); putchar('\\'); } else if(str[i]=='\n'){ putchar('\\'); putchar('n'); } else if(str[i]=='\r'){ } else { putchar(str[i]); } } putchar('"'); return 0; } if(str == "-libshow"){ int i; ifun.set(); rep(i,ifun.name.size()){ puts("-------------------------------"); printf("%s\n------\n", ifun.name[i].c_str()); printf("%s\n\n\n", ifun.func[ifun.name[i]].c_str()); } return 0; } for(;;){ k = fread(buf, 1, 10000, stdin); buf[k] = '\0'; str += buf; if(k < 10000) break; } str_store = str; str += "\n"; ifun.set(); string tmp; code c; c.up = NULL; c.set(str, (string)"program"); user_code = 0; tmp = ifun.get_insert_string((string)"first"); c.insert(tmp, 0); tmp = ifun.get_insert_string((string)"main_first"); rep(i,c.str.size()){ if(c.str[i].substr(0,9) == "int main(" || c.str[i].substr(0,10) == "void main("){ c.nxtlst[c.nxt[i]]->insert(tmp,0); } } // c.debug_writer(); return 0; c.output(0); printf("// cLay varsion 20191012-1\n"); str = str_store; f = 0; printf("\n// --- original code ---\n"); rep(i,str.size()){ if(!f) printf("// "), f = 1; if(str[i]=='\r') continue; putchar(str[i]); if(str[i]=='\n') f = 0; } return 0; }
Current time: 2023年03月30日01時33分33秒
Last modified: 2019年10月12日03時59分39秒 (by laycrs)
Tags: no_tags
トップページに戻る
Logged in as: unknown user (not login)