2019年09月02日20時46分16秒に更新されたバージョンを表示しています.
最新のページはこちらをご覧ください.


cLayコード(version 20190902-1)

#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



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 1000000007\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  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  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_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_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;
    }
    
    {
      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;
    }
    
    {
      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_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_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_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;
    }
    
    {
      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;
    }
    
    {
      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    mem = r * c;\n    dat = new T[mem];\n    rep(i,mem) 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 = "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 = "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 = "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 = "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}\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 = "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 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 = "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 = (T*)std::malloc(sizeof(T)*2*i);\n    mn = (T*)std::malloc(sizeof(T)*2*i);\n    mnind = (int*)std::malloc(sizeof(T)*2*i);\n    fixval = (T*)std::malloc(sizeof(T)*i);\n    addval = (T*)std::malloc(sizeof(T)*i);\n    fixed = (char*)std::malloc(sizeof(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    std::free(sum);\n    std::free(mn);\n    std::free(mnind);\n    std::free(fixval);\n    std::free(addval);\n    std::free(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;\n    int sz = 1;\n    \n    a += N;\n    b += N;\n    push(a); push(b-1);\n \n    res.first = numeric_limits<T>::max();\n    res.second = -1;\n    while(a < b){\n      if(a%2){\n        res <?= make_pair(mn[a], mnind[a]);\n        a++;\n      }\n      if(b%2){\n        b--;\n        res <?= make_pair(mn[b], mnind[b]);\n      }\n      a /= 2;\n      b /= 2;\n    }\n    return res;\n  }\n\n  inline T getMinVal(int a, int b){\n    return getMin(a,b).first;\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;\n    int sz = 1;\n    \n    a += N;\n    b += N;\n    push(a); push(b-1);\n \n    res = 0;\n    while(a < b){\n      if(a%2) res += sum[a++];\n      if(b%2) res += sum[--b];\n      a /= 2;\n      b /= 2;\n    }\n    return res;\n  }\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;
    }

    {
      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_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    pair<int,int> *A;\n\n    rep(i,N) M += es[i];\n    A = (pair<int,int>*)((int*)((int**)(*mem) + tn) + tn + M);\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    g.es = (int*)(*mem);\n    g.edge = (int**)(g.es + tn);\n    g.edge[0] = (int*)(g.edge + tn);\n\n    rep(i,tn) g.es[i] = 0;\n    rep(i,M) g.es[A[i].first]++;\n\n    rep(i,1,tn) g.edge[i] = g.edge[i-1] + g.es[i-1];\n    *mem = g.edge[tn-1] + g.es[tn-1];\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_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(&deg, 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_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_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_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_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 = "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;
    }

    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)"long");
    vartype.insert((string)"signed long");
    vartype.insert((string)"unsigned long");
    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)"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)"combination_mint");
    vartype.insert((string)"graph");
    vartype.insert((string)"HLD");
    vartype.insert((string)"unionFind");
    vartype.insert((string)"AhoCorasick");
    vartype.insert((string)"fft_pnt");

    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)"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)"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);
  }


  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)"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)"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)"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");

    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(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,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(!fg) break;
    }
    return in;
  }

  string getEquationType(string in){
    int i;
    int string_fg = 0, double_fg = 0, float_fg = 0, modint_fg = 0, mint_fg = 0, ull_fg = 0, ll_fg = 0, unsigned_fg = 0, int_fg = 0, char_fg = 0, void_fg = 0;
    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] == '"'){
        char_fg = 1;
        for(i=1;;i++){
          if(in[i]=='\\'){ i++; continue; }
          if(in[i]=='"') break;
        }
        in = in.substr(i+1);
        continue;
      }

      if(in[0] == '\''){
        char_fg = 1;
        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());

        if(tp == "string") string_fg = 1;
        if(tp == "double") double_fg = 1;
        if(tp == "float") float_fg = 1;
        if(tp == "modint") modint_fg = 1;
        if(tp == "mint") mint_fg = 1;
        if(tp == "long long") ll_fg = 1;
        if(tp == "int") int_fg = 1;
        if(tp == "char") char_fg = 1;
        if(tp == "void") void_fg = 1;
      }
    }

    if(string_fg) return (string)"string";
    if(double_fg) return (string)"double";
    if(float_fg) return (string)"float";
    if(modint_fg) return (string)"modint";
    if(mint_fg) return (string)"mint";
    if(ull_fg) return (string)"unsigned long long";
    if(ll_fg) return (string)"long long";
    if(unsigned_fg) return (string)"unsigned";
    if(int_fg) return (string)"int";
    if(char_fg) return (string)"char";
    if(void_fg) return (string)"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"){
            ifun.doit.insert((string)"reader_int");
          } else if(etype=="long long"){
            ifun.doit.insert((string)"reader_ll");
          } 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]);
        string etype = getEquationType(vtmp[k]);
        string stc;

        ifun.doit.insert((string)"writer_char");
        if(etype=="int"){
          if(basestr=="") ifun.doit.insert((string)"writer_int");
          else            ifun.doit.insert((string)"writer_int_withBase");
        } else if(etype=="long long"){
          if(basestr=="") ifun.doit.insert((string)"writer_ll");
          else            ifun.doit.insert((string)"writer_ll_withBase");
        } 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, "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() == 2) ifun.doit.insert((string)"Factor2");
        if(vtmp.size() == 3) ifun.doit.insert((string)"Factor3");
        if(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, "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, "BIT_ith()");
      if(vs.size() == 3){
        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, "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, "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, "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, "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, "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, "shortestUndirectedCycle_length()");
      if(vs.size() == 3) ifun.doit.insert((string)"graph_shortestUndirectedCycle_length");

      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, "getDist()");
      if(vs.size() == 3) ifun.doit.insert((string)"wgraph_getDist");
      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"){
        string in_tmp = in.substr(7);
        stchar = nextToken(in_tmp);
        if(stchar.first == "MD") ifun.already.insert((string)"define_MD");
        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);
        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]!='{') 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 == "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){
          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"){
          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(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(str_arg.size()==2){
            tmp = (string)"for(" + str_arg[0] + "=0;" + str_arg[0] + "<(" + str_arg[1] + ");" + str_arg[0] + "++)";
          } else if(str_arg.size()==3){
            tmp = (string)"for(" + str_arg[0] + "=(" + str_arg[1] + ");" + str_arg[0] + "<(" + str_arg[2] + ");" + str_arg[0] + "++)";
          } 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"){
          string ttt = tmp, tttt;
          pair<string,string> ss;
          //fprintf(stderr,"+-+-- %s\n",ttt.c_str());
          trim_until(ttt, '(', ')');
          assert(ttt.size()>=2);

          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;
              
              if(isalnum(tmp[0]) || tmp[0]=='_') tmp = " "+tmp;
              str_type = in.substr(0, tt);
              tmp = str_type + tmp;
              
              code_replace(tmp);
              
              pair<string,string> pss = var_definition(tmp);
              str_var = pss.first;
              str_type = pss.second;

              if(insert_count != before_count){
                vector<string> vvs = split_p(str_type, ',');
                tmp = str_var + " = " + vvs[3] + ";";
                vvs[3] = "";
                str_type = vvs[0] + "," + vvs[1] + "," + vvs[2] + "," + vvs[3];

                is_not_vardef = 1;
              }

              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");

  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 20190902-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: 2024年03月29日23時10分53秒
Last modified: 2019年09月02日20時46分16秒 (by laycrs)
Tags: no_tags
トップページに戻る

Logged in as: unknown user (not login)

ログイン: