/*
Author of all code: Pedro BIGMAN Dias
Last edit: 15/02/2021
*/
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <deque>
#include <list>
#include <iomanip>
#include <stdlib.h>
#include <time.h>
#include <cstring>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
#define REP(i,a,b) for(ll i=(ll) a; i<(ll) b; i++)
#define pb push_back
#define mp make_pair
#define pl pair<ll,ll>
#define ff first
#define ss second
#define whole(x) x.begin(),x.end()
#define DEBUG(i) cout<<"Pedro Is The Master "<<i<<endl
#define INF 500000000LL
#define EPS 0.00000001
#define pi 3.14159
ll mod=99824LL;
vector<ll> fat,ifat;
ll Mo_bucket; //sqrt(arr.size())
template<class A=ll>
void Out(vector<A> a) {REP(i,0,a.size()) {cout<<a[i]<<" ";} cout<<endl;}
template<class A=ll>
void In(vector<A> &a, ll N) {A cur; REP(i,0,N) {cin>>cur; a.pb(cur);}}
struct hash_pair
{
template <class T1, class T2>
size_t operator() (pair<T1, T2> p) const
{
size_t hash1 = hash<T1>()(p.first);
size_t hash2 = hash<T2>()(p.second);
return (hash1 ^ hash2);
}
};
template <class A, class B, class C>
pair<A,B> operator *(pair<A,B> a, C c) {a.ff*=c; a.ss*=c; return a;}
template<class A,class B>
pair<A,B> operator + (pair<A,B> a, pair<A,B> b) {return mp(a.ff+b.ff,a.ss+b.ss);}
template<class A,class B>
pair<A,B> operator - (pair<A,B> a, pair<A,B> b) {return mp(a.ff-b.ff,a.ss-b.ss);}
template<class T=ll>
bool cmp(T A, T B) {return (A<B);}
template<class T=double>
bool eq(T a, T b) {return(abs(a-b)<EPS);}
class complex
{
public:
double re; double im;
complex() {re=0.0; im=0.0;}
complex(double r, double i) {re=r; im=i;}
complex(double r) {re=r; im=0.0;}
complex operator !() //conjugate
{
complex ans(re,-im); return ans;
}
complex operator + (complex z) {complex ans(re+z.re,im+z.im); return ans;}
complex operator - (complex z) {complex ans(re-z.re,im-z.im); return ans;}
void operator += (complex z) {re+=z.re; im+=z.im;}
void operator -= (complex z) {re-=z.re; im-=z.im;}
complex operator * (complex z) {complex ans(re*z.re-im*z.im,re*z.im+z.re*im); return ans;}
void operator *= (complex z) {complex ans=(*this)*z; *this=ans;}
double norm() {double ans = sqrt(re*re+im*im); return ans;}
complex operator / (complex z) {double n = z.norm(); n=n*n; complex ans=!z; ans.re/=n; ans.im/=n; ans*=(*this); return ans;}
void operator /= (complex z) {complex ans=(*this)/z; *this=ans;}
bool operator == (complex z) {if(eq(re,z.re) && eq(im,z.im)) {return true;} else {return false;}}
bool operator < (complex z) {if(re<z.re) {return true;} else if(eq(re,z.re)) {return (im<z.im);} else {return false;}}
bool operator <= (complex z) {return (((*this)<z) || ((*this)==z));}
bool operator > (complex z) {return (z<(*this));}
bool operator >= (complex z) {return (z<=(*this));}
double arg()
{
if(re==0 && im>=0) {return (pi/2.0);}
if(re==0 && im<0) {return (3.0*pi/2.0);}
double val = im/re;
double ans = atan(val);
if(re<0) {ans=pi+ans;}
else if(im<0) {ans=2.0*pi+ans;}
return ans;
}
};
struct hash_complex
{
size_t operator() (complex z) const
{
return (2*sizeof(double));
}
};
complex polar(double len, double angle) //angle in radians
{
complex ans(cos(angle),sin(angle)); ans*=((complex) len);
return ans;
}
class segment
{
public:
complex a,b; //open in a, closed in b
segment() {a=0; b=0;}
segment(complex x) {a=0; b=x;}
segment(complex x, complex y) {a=x; b=y;}
bool belong(complex z)
{
if(z==a) {return false;}
if(z==b) {return true;}
complex w = (b-a)/(b-z);
if(!eq(w.im,0.0)) {return false;}
if(w.re>1.0) {return true;}
else {return false;}
}
};
class line
{
public:
complex a,b; //sometimes directed line a->b
line() {a=0; b=0;}
line(complex x, complex y) {a=x; b=y;}
line(segment s) {a=s.a; b=s.b;}
bool belong(complex z)
{
if(z==a || z==b) {return true;}
complex w = (b-a)/(b-z);
if(!eq(w.im,0.0)) {return false;}
else {return true;}
}
ld slope()
{
ld ans;
if(a.re!=b.re) {ans= (a.im-b.im)/(a.re-b.re);}
else {ans=(ld) INF;}
return ans;
}
};
bool parallel(line l, line r)
{
complex z1=l.a-l.b; complex z2=r.a-r.b;
complex z = z1/z2;
if(eq(z.im,0.0)) {return true;}
else {return false;}
}
complex intersection(line l, line r)
{
complex z1,z2,z3,z;
z1=(l.a-l.b)*((r.a*(!r.b))-(r.b*(!r.a)));
z2=(r.a-r.b)*((l.a*(!l.b))-(l.b*(!l.a)));
z3=((l.a-l.b)*(!r.a-!r.b))-((r.a-r.b)*(!l.a-!l.b));
z=(z2-z1)/z3;
return z;
}
bool intersect(line l, segment s)
{
line r(s);
complex z = intersection(l,r);
return s.belong(z);
}
bool intersect(segment s, segment t)
{
line l(s); line r(t);
return (intersect(l,t) && intersect(r,s));
}
bool concurrent(line l1,line l2, line l3)
{
complex z1 = intersection(l1,l2);
complex z2 = intersection(l2,l3);
complex z3 = intersection(l3,l1);
if(z1==z2 && z2==z3) {return true;}
else {return false;}
}
complex reflection(complex z, line l)
{
return ((((l.a-l.b)*(!z))+((!l.a)*l.b)-(l.a*(!l.b)))/((!l.a)-(!l.b)));
}
complex projection(complex z, line l)
{
return ((complex) (0.5)*(z+reflection(z,l)));
}
bool prependicular(line l, line r)
{
complex z = ((l.a-l.b)/(r.a-r.b));
if(eq(z.re,0.0)) {return true;}
else {return false;}
}
double distance(complex z, line l)
{
complex r = reflection(z,l);
complex ans=z-r;
return ans.norm();
}
class Triangle
{
public:
complex a, b, c;
complex *circumcentre_ptr;
Triangle() {a=0.0; b=0.0; c=0.0; circumcentre_ptr=nullptr;}
Triangle(complex x,complex y,complex z) {a=x; b=y; c=z; circumcentre_ptr=nullptr;}
Triangle operator !()
{
Triangle ANS(!a,!b,!c); return ANS;
}
double Area() //!!SIGNED AREA, is positive if, given point in interior, vertexes of triangle are in counterclockwise order.
{
complex ans;
complex z; z.im=0.25;
complex z1 = a*((!b)-(!c));
complex z2 = b*((!c)-(!a));
complex z3 = c*((!a)-(!b));
ans = z*(z1+z2+z3);
return ans.re;
}
complex centroid ()
{
complex z;
z.re=1.0/3.0;
return (z*(a+b+c));
}
complex circumcentre()
{
if(circumcentre_ptr!=nullptr) {return *circumcentre_ptr;}
complex *ans=new complex();
complex c1,c2,c3,z1,z2;
c1=a*(!a)*(b-c);
c2=b*(!b)*(c-a);
c3=c*(!c)*(a-b);
z1=c1+c2+c3;
c1=(!a)*(b-c);
c2=(!b)*(c-a);
c3=(!c)*(a-b);
z2=c1+c2+c3;
*ans=z1/z2;
circumcentre_ptr=ans;
return (*ans);
}
complex orthocentre()
{
complex h = a+b+c-(complex) 2.0*circumcentre();
return h;
}
};
bool similar(Triangle S, Triangle T) //ATTENTION: Directly similar. For reversely similar, try !S,T
{
complex z1,z2,z3;
z1=S.a*(T.b-T.c);
z2=S.b*(T.c-T.a);
z3=S.c*(T.a-T.b);
complex ans = z1+z2+z3;
if(ans==(complex) 0.0) {return true;}
else {return false;}
}
class Quadrilateral
{
public:
complex a,b,c,d;
Quadrilateral() {a=0; b=0; c=0; d=0;}
Quadrilateral(complex x, complex y, complex w, complex z) {a=x; b=y; c=w; d=z;}
bool concyclic()
{
complex z = ((b-a)*(c-d))/((c-a)*(b-d));
if(z.im==0.0) {return true;}
else {return false;}
}
double Area()
{
Triangle T1(a,b,c); Triangle T2(a,c,d);
return (T1.Area()+T2.Area());
}
complex MiquelPoint()
{
complex ans = ((a*c)-(b*d))/(a+c-b-d);
return ans;
}
};
class Polygon
{
public:
ll N;
vector<complex> v;
double *area_ptr;
bool *cyclic_ptr;
Polygon() {N=0LL; area_ptr=nullptr; cyclic_ptr=nullptr;}
Polygon(vector<complex> vertex) {v=vertex; N=v.size(); area_ptr=nullptr; cyclic_ptr=nullptr;}
double Area()
{
if(area_ptr!=nullptr) {return *area_ptr;}
double *ans = new double();
(*ans)=0.0;
REP(i,1,v.size()-1)
{
Triangle T(v[0],v[i],v[i+1]);
(*ans)+=T.Area();
}
area_ptr=ans;
return abs(*ans);
}
bool concylic()
{
if(cyclic_ptr!=nullptr) {return *cyclic_ptr;}
bool ans;
REP(i,3,v.size())
{
Quadrilateral Q(v[0],v[1],v[2],v[i]);
if(!Q.concyclic()) {ans=false;cyclic_ptr=&ans; return false;}
}
ans=true;
cyclic_ptr=&ans;
return true;
}
bool inside(complex z)
{
segment l(z,z+(complex) (INF));
ll intersections=0LL;
REP(i,0,N)
{
segment s(v[i],v[(i+1)%N]);
if(intersect(l,s)) {intersections++;}
}
if(intersections%2==0) {return false;}
else {return true;}
}
};
vector<ll> SweepSort(line l, vector<complex> v) //ans[i]=j means, in the sweep sorted point array, position i is v[j]
{
vector<pl> s;
REP(i,0,v.size())
{
Triangle T(v[i],l.b,l.a);
s.pb(mp(T.Area(),i));
}
sort(whole(s));
vector<ll> ans; REP(i,0,v.size()) {ans.pb(s[i].ss);}
return ans;
}
vector<ll> ArgSort(vector<complex> v, complex centre) //angles related to horizontal directed line through centre, angles from 0 to 360. ans[i]=j means, in the sweep sorted point array, position i is v[j]
{
vector<pl> angles; vector<ll> ans;
REP(i,0,v.size()) {complex z = v[i]-centre; angles.pb(mp(z.arg(),i));}
sort(whole(angles));
REP(i,0,v.size()) {ans.pb(angles[i].ss);}
return ans;
}
bool cmp_com(complex a, complex b) {return (a<b);}
bool cmp_pcomll(pair<complex,ll> a, pair<complex,ll> b) {if(a.ff<b.ff) {return true;} else if(a.ff>b.ff) {return false;} else {return (a.ss<b.ss);}}
pl ClosestPair(vector<complex> v) //returns (ind1,ind2) pair of indexes, ind1<ind2
{
ll N = v.size();
vector<complex> z = v; sort(whole(z),cmp_com);
pair<complex,complex> ans;
ld mind=(ld) INF;
set<pair<double,double> > s; s.insert(mp(z[0].im,z[0].re));
ll ind=0LL;
set<pair<double,double> >::iterator it;
REP(i,1,N)
{
while(z[i].re-z[ind].re>mind)
{
s.erase(mp(z[ind].im,z[ind].re));
ind++;
}
it=s.lower_bound(mp(z[i].im-mind,-INF));
while(it!=s.end() && it->ff<=z[i].im+mind)
{
complex x(it->ss,it->ff);
complex y = z[i]-x;
if(y.norm()<mind) {mind=y.norm(); ans.ff=x; ans.ss=z[i];}
it++;
}
s.insert(mp(z[i].im,z[i].re));
}
pl f_ans;
REP(i,0,N)
{
if(v[i]==ans.ff) {f_ans.ff=i;}
if(v[i]==ans.ss) {f_ans.ss=i;}
}
if(f_ans.ff>f_ans.ss) {swap(f_ans.ff,f_ans.ss);}
return f_ans;
}
vector<ll> ConvexHull(vector<complex> v, bool sorted=false) //returns vector of indexes of the convex hull
{
ll N=v.size();
vector<pair<complex,ll> > z; REP(i,0,N) {z.pb(mp(v[i],i));}
if(!sorted) {sort(whole(z),cmp_pcomll);}
vector<ll> ans,f_ans;
REP(i,0,N)
{
ans.pb(i);
if(i==0) {continue;}
while(ans.size()>2)
{
line l1(z[ans[ans.size()-3]].ff,z[ans[ans.size()-2]].ff);
line l2(z[ans[ans.size()-2]].ff,z[i].ff);
if(l1.slope()<l2.slope())
{
ans.erase(ans.end()-2);
}
else
{
break;
}
}
}
REP(i,0,ans.size()) {f_ans.pb(z[ans[i]].ss);}
ans.clear();
REP(i,0,N)
{
ans.pb(i);
if(i==0) {continue;}
while(ans.size()>2)
{
line l1(z[ans[ans.size()-3]].ff,z[ans[ans.size()-2]].ff);
line l2(z[ans[ans.size()-2]].ff,z[i].ff);
if(l1.slope()>l2.slope())
{
ans.erase(ans.end()-2);
}
else
{
break;
}
}
}
REP(i,1,ans.size()-1) {f_ans.pb(z[ans[i]].ss);}
sort(whole(f_ans));
return f_ans;
}
ll gcd(ll a,ll b)
{
if(a>b) {swap(a,b);}
if(a==0) {return b;}
else {return gcd(a,b%a);}
}
pl ExtEuclid(ll a, ll b) //return pair x,y: ax+by=(a,b)
{
if(a==0) {return mp(0LL,1LL);}
if(b==0) {return mp(1LL,0LL);}
bool swapped=false;
if(a<b) {swap(a,b); swapped=true;}
ll red=a%b; if(red<0) {red+=b;}
ll k=(a-red)/b;
pl nxt=ExtEuclid(red,b);
pl ans; ans.ff=nxt.ff; ans.ss=nxt.ss-k*nxt.ff;
if(swapped) {swap(ans.ff,ans.ss);}
return ans;
}
bool IsPrime(ll s)
{
if(s==1LL) {return false;}
if(s==2LL) {return true;}
REP(i,2LL,sqrt(s)+1LL)
{
if(s%i==0LL) {return false;}
}
return true;
}
vector<pl> PF(ll s)
{
vector<pl> pf;
if(s==2LL) {pf.pb(mp(2LL,1LL)); return pf;}
ll d=2LL;
while(d<=sqrt(s)+1LL)
{
if(s%d==0LL)
{
ll exp=0LL;
while(s%d==0LL)
{
exp++; s/=d;
}
pf.pb(mp(d,exp));
}
d++;
}
if(s>1LL)
{
pf.pb(mp(s,1LL));
}
return pf;
}
vector<ll> Sieve(ll N) //O(NloglogN)
{
vector<bool> valid; REP(i,0,N+1) {valid.pb(true);}
vector<ll> primes;
REP(i,2,N+1)
{
if(!valid[i]) {continue;}
ll cur=i; primes.pb(cur);
while(cur<=N) {valid[cur]=false; cur+=i;}
}
return primes;
}
ll phi(ll x)
{
ll n=x;
vector<pl> pri=PF(x);
ll ans=1;
REP(i,0,pri.size())
{
ans*=(ll) ((pow(pri[i].ff,pri[i].ss-(ld) 1)));
ans*=(pri[i].ff-1);
}
return ans;
}
ll ord(ll a, ll m)
{
ll cur=a; ll ans=1;
while((cur-1LL)%m!=0LL)
{
cur*=a; ans++; cur%=m;
}
return ans;
}
ll fastexp(ll a,ll e)
{
if(e==0) {return 1LL;}
if(e%2LL==0)
{
ll v=fastexp(a,(ll) e/2LL); return (v*v)%mod;
}
else
{
ll v=fastexp(a,(ll) e/2LL); return (((v*v)%mod)*a)%mod;
}
}
ll fastexp(ll a, ll e, ll m)
{
if(e==0) {return 1LL;}
if(e%2LL==0)
{
ll v=fastexp(a,(ll) e/2LL, m); return (v*v)%m;
}
else
{
ll v=fastexp(a,(ll) e/2LL, m); return (((v*v)%m)*a)%m;
}
}
ll fac(ll n, ll m)
{
ll ans=1LL; REP(i,1LL,n+1LL) {ans*=i; ans%=m;}
if(ans<0) {ans+=m;}
return ans;
}
ll inv(ll s)
{
return fastexp(s,mod-2LL);
}
ll inv(ll s, ll m)
{
return fastexp(s,phi(m)-1LL,m);
}
ll bin(ll n, ll k) //binomial coefficient
{
if(k<0LL || k>n) {return 0LL;}
ll ans=(((ifat[k]*ifat[n-k])%mod)*fat[n])%mod;
return ans;
}
ll bin(ll n, ll k, ll m)
{
if(k<0LL || k>n) {return 0LL;}
ll ans=fac(n,m);
ans*=inv(fac(k,m),m); ans%=m; ans*=inv(fac(n-k,m),m); ans%=m;
if(ans<0) {ans+=m;}
return ans;
}
void Calcfat(ll n)
{
ll ans=1LL; fat.pb(ans);
REP(i,1LL,n+1LL) {ans*=i; ans%=mod; fat.pb(ans);}
REP(i,0,n+1) {ifat.pb(inv(fat[i]));}
}
ll CRT(vector<pl> a) //a[i].ff=ai, a[i].ss=mi
{
REP(i,0,a.size()) {a[i].ff%=a[i].ss;}
ll ans=0LL; vector<ll> X; ll p=1LL; REP(i,0,a.size()) {p*=a[i].ss;}
REP(i,0,a.size()) {X.pb(p/a[i].ss);}
ll val;
REP(i,0,a.size())
{
val=a[i].ff*X[i]*inv(X[i],a[i].ss); val%=p; ans+=val; ans%=p;
}
if(ans<0) {ans+=p;}
return ans;
}
class ModInt
{
public:
ll a; ll m;
ModInt() {a=0LL; m=mod;}
ModInt(ll val) {a=val; m=mod; a%=m; a+=m; a%=m;}
ModInt operator + (ModInt b) {ModInt ans(a+b.a); return ans;}
ModInt operator - (ModInt b) {ModInt ans(a-b.a); return ans;}
ModInt operator * (ModInt b) {ModInt ans(a*b.a); return ans;}
ModInt operator / (ModInt b) {ModInt ans(a*inv(b.a)); return ans;}
void operator ++() {a++; a%=m; a+=m; a%=m;}
void operator --() {a--; a%=m; a+=m; a%=m;}
void operator +=(ModInt b) {ModInt ans=(*(this)) + b; a=ans.a;}
void operator -=(ModInt b) {ModInt ans=(*(this)) - b; a=ans.a;}
void operator *=(ModInt b) {ModInt ans=(*(this))*b; a=ans.a;}
void operator /=(ModInt b) {ModInt ans=(*(this))/b; a=ans.a;}
bool operator ==(ModInt b) {if((a-b.a)%m==0) {return true;} else {return false;}}
};
ostream & operator << (ostream &out, ModInt &M) {cout<<M.a; return out;}
istream & operator >> (istream &in, ModInt &M) {ll a; cin>>a; ModInt ans(a); M=a; return in;}
class Matrix
{
public:
ll N,M;
vector<vector<double> > a;
ll rank;
Matrix *Red, *Inv, *Trans; double det;
vector<bool> pivot;
Matrix() {N=0LL; M=0LL; Red=nullptr; Inv=nullptr; Trans=nullptr;}
Matrix (vector<vector<double> > x)
{
N=x.size(); M=x[0].size(); a=x; rank=0LL; REP(i,0,M) {pivot.pb(false);}
Red=nullptr; Inv=nullptr; Trans=nullptr;
}
Matrix operator + (Matrix B) //O(NM)
{
if((*this).N!=B.N || (*this).M!=B.M) {Matrix ANS; return ANS;}
vector<vector<double> > ans; vector<double> xx; REP(i,0,(*this).M) {xx.pb(0.0);} REP(i,0,(*this).N) {ans.pb(xx);}
REP(i,0,(*this).N) {REP(j,0,(*this).M) {ans[i][j]=(*this).a[i][j]+B.a[i][j];}}
Matrix ANS(ans); return ANS;
}
Matrix operator * (Matrix B) //O(N^3)
{
if(M!=B.N) {Matrix ANS; return ANS;}
vector<vector<double> > d; vector<double> xx; REP(i,0,B.M) {xx.pb(0.0);} REP(i,0,N) {d.pb(xx);}
REP(i,0,N)
{
REP(j,0,B.M)
{
double sum=0.0; REP(z,0,M) {sum+=(a[i][z]*B.a[z][j]);}
d[i][j]=sum;
}
}
Matrix ANS(d);
return ANS;
}
Matrix operator * (double c) //O(NM)
{
Matrix ANS = (*this); REP(i,0,N) {REP(j,0,M) {ANS.a[i][j]*=c;}}
return ANS;
}
Matrix operator - (Matrix B)
{
return ((*this)+B*(-1.0));
}
bool operator ==(Matrix B)
{
return ((*this).a==B.a);
}
bool operator !=(Matrix B)
{
if((*this)==B) {return false;}
else {return true;}
}
void operator +=(Matrix B) {*this=(*this)+B;}
void operator -=(Matrix B) {*this=(*this)-B;}
void operator *=(Matrix B) {*this=(*this)*B;}
void operator *=(double c) {*this=(*this)*c;}
void operator /=(double c) {*this=(*this)*(1.0/c);}
void operator /=(Matrix B) {B.RRE(); *this=(*this)*(*(B.Inv));}
Matrix operator ~()
{
if(Trans!=nullptr) {return *Trans;}
vector<double> xx; REP(i,0,N) {xx.pb(0.0);}
vector<vector<double> > ans; REP(i,0,M) {ans.pb(xx);}
REP(i,0,M) {REP(j,0,N) {ans[i][j]=a[j][i];}}
Matrix *RESULT = new Matrix(ans); Trans=RESULT;
return *RESULT;
}
void disp()
{
REP(i,0,N) {REP(j,0,M) {cout<<a[i][j]<<" ";} cout<<endl;}
}
void Inp()
{
ll NN,MM; cin>>NN>>MM; N=NN; M=MM;
vector<double> xx; REP(i,0,M) {xx.pb(0.0);} REP(i,0,N) {a.pb(xx);}
double c; REP(i,0,N) {REP(j,0,M) {cin>>c; a[i][j]=c;}}
REP(i,0,M) {pivot.pb(false);}
}
Matrix RRE() //Reduced Row Echelon Form, O(N*M^2), also builds "inverse" matrix up
{
if(Red!=nullptr) {return *Red;}
det=1.0;
rank=0LL;
Matrix *A= new Matrix(); *A=*this;
Matrix *Inverse = new Matrix();
vector<double> xx; REP(i,0,N) {xx.pb(0.0);} REP(i,0,N) {(*Inverse).a.pb(xx);}
(*Inverse).N=N; (*Inverse).M=N; REP(i,0,N) {(*Inverse).a[i][i]=1.0;}
vector<bool> v; REP(i,0,N) {v.pb(true);}
REP(ind,0,M)
{
ll line=0LL;
while(line<N)
{
if(!v[line]) {line++; continue;}
if((*A).a[line][ind]!=0.0) {break;}
line++;
}
if(line==N) {continue;}
pivot[ind]=true;
double c=(*A).a[line][ind]; det*=c;
REP(i,0,M) {(*A).a[line][i]/=c;}
REP(i,0,N) {(*Inverse).a[line][i]/=c;}
v[line]=false; rank++;
REP(i,0,N)
{
if(i==line) {continue;}
double c=(*A).a[i][ind];
if(c==0.0) {continue;}
REP(j,0,M) {(*A).a[i][j]-=((*A).a[line][j]*c);}
REP(j,0,N) {(*Inverse).a[i][j]-=((*Inverse).a[line][j]*c);}
}
}
vector<pair<pair<vector<double> ,vector<double> >, ll > > ToOrder; REP(i,0,N) {ToOrder.pb(mp(mp((*A).a[i],(*Inverse).a[i]),i));}
sort(ToOrder.begin(),ToOrder.end());
reverse(ToOrder.begin(),ToOrder.end());
(*A).a.clear(); REP(i,0,N) {(*A).a.pb(ToOrder[i].ff.ff);}
(*Inverse).a.clear(); REP(i,0,N) {(*Inverse).a.pb(ToOrder[i].ff.ss);}
Red=A; Inv=Inverse;
if(rank!=N || rank!=M) {det=(double) 0.0;}
ll inversions=0LL;
REP(i,0,N) {REP(j,i+1,M) {if(ToOrder[i].ss>ToOrder[j].ss) {inversions++;}}}
if(inversions%2!=0) {det*=(-1.0);}
return *Red;
}
vector<double> Gauss(vector<double> b) //gives one possible solution if there is one to Ax=b in O(N^2)
{
Matrix A=RRE(); Matrix B=*Inv;
vector<double> ans; REP(i,0,M) {ans.pb(0.0);}
double val; ll piv=0LL;
REP(i,0,N)
{
val=0.0; REP(j,0,N) {val+=B.a[i][j]*b[j];}
while(!pivot[piv] && piv<M) {piv++;}
if(piv<M) {ans[piv]=val;}
else if(val!=0.0) {ans.clear(); return ans;}
piv++;
}
return ans;
}
};
Matrix fastexp(Matrix A, ll e) //O(N^3loge)
{
if(A.N!=A.M) {Matrix ANS; return ANS;}
if(e<0) {A.RRE();if(A.rank==0) {e=0LL;} else {return fastexp(*(A.Inv),-e);}}
if(e==0)
{Matrix ANS=A; REP(i,0,A.N) {REP(j,0,A.N) {if(i!=j) {ANS.a[i][j]=0.0;} else {ANS.a[i][j]=1.0;}}} return ANS;}
if(e%2LL==0)
{
Matrix V =fastexp(A,(ll) e/2LL); return (V*V);
}
else
{
Matrix V=fastexp(A,(ll) e/2LL); return (V*V*A);
}
}
template<class T=ll>
class SparseTable //Range Minimum Queries
{
public:
ll N;
vector<T> a;
vector<vector<T> > v;
SparseTable() {N=0LL;}
SparseTable(vector<T> b)
{
a=b; N=a.size();
ll lo=(ll) floor((double) log2(N)) +1LL;
vector<T> xx;
REP(i,0,lo) {xx.pb(mp(INF,INF));} REP(i,0,N) {v.pb(xx);}
REP(step,0LL,lo)
{
REP(i,0,N-(1LL<<step)+1LL)
{
if(step==0) {v[i][0]=a[i];}
else {v[i][step]=min(v[i][step-1],v[i+(1LL<<(step-1))][step-1]);}
}
}
}
T query(ll l, ll r)
{
ll step=(ll) floor((double) log2(r-l+1LL));
return min(v[l][step],v[r-(1LL<<step)+1LL][step]);
}
};
class DSU
{
public:
ll N;
vector<ll> p,siz;
DSU(ll n)
{
N=n; REP(i,0,N) {p.pb(i); siz.pb(1);}
}
ll find(ll x)
{
if(p[x]==x) {return x;}
ll ans=find(p[x]);
p[x]=ans;
return ans;
}
void unionn(ll a, ll b)
{
a=find(a); b=find(b);
if(siz[a]>siz[b]) {swap(a,b);}
p[a]=b; siz[b]+=siz[a];
}
};
class SucPath
{
public:
ll N;
vector<ll> fo;
vector<vector<ll> > f2; //sparse table of steps powers of 2
ll ms; //max_steps
SucPath() {N=0LL;}
SucPath(vector<ll> x, ll max_steps)
{
N=x.size(); fo=x; ms=max_steps;
vector<ll> xx;
REP(i,0,(ll) (floor(log2(ms)))+1LL) {xx.pb(0LL);}
REP(i,0,N) {f2.pb(xx);}
Conf2(0);
}
void Conf2(ll e) //O(NlogN)
{
if((1LL<<e)>ms) {return;}
if(e==0) {REP(i,0,N) {f2[i][e]=fo[i];} Conf2(e+1);}
else
{
REP(i,0,N)
{
f2[i][e]=f2[f2[i][e-1]][e-1];
}
}
Conf2(e+1);
}
ll f(ll x,ll s) //O(logN)
{
ll ind=0;
while(s>0)
{
if(s%2!=0) {x=f2[x][ind];}
s/=2; ind++;
}
return x;
}
pl cycle() //Floyd's Algorithm, O(N) time, O(1) memory, return <element of cycle,length od cycle>
{
ll a=fo[0]; ll b=fo[fo[0]];
while(a!=b) {a=fo[a]; b=fo[fo[b]];}
ll l=1; b=fo[a];
while(b!=a) {b=fo[b]; l++;}
return mp(a,l);
}
};
class FT
{
public:
ll N;
vector<ll> a, f;
FT(vector<ll> z)
{
N = z.size(); a = z; ll sum = 0;
vector<ll> ps; ps.pb(0); REP(i,0,N) {sum+=a[i]; ps.pb(sum);}
REP(i,0,N+1)
{
f.pb(ps[i] - ps[i-(i&(-i))]);
}
}
ll sum(ll s)
{
if(s<0) {return 0;}
ll cur = s+1;
ll ans = 0;
while(cur>0)
{
ans+=f[cur];
cur-=(cur&(-cur));
}
return ans;
}
void update(ll s, ll dif)
{
ll cur = s+1;
a[s]+=dif;
while(cur<=N)
{
f[cur]+=dif;
cur+=(cur&(-cur));
}
}
};
class ST
{
public:
ll N;
class SV //seg value
{
public:
ll a;
SV() {a=0LL;}
SV(ll x) {a=x;}
SV operator & (SV X) {SV ANS(a+X.a); return ANS;}
};
class LV //lazy value
{
public:
ll a;
LV() {a=0LL;}
LV(ll x) {a=x;}
LV operator & (LV X) {LV ANS(a+X.a); return ANS;}
};
SV upval(ll c) //how lazy values modify a seg value inside a node, c=current node
{
SV X(p[c].a+(range[c].ss-range[c].ff+1)*lazy[c].a);
return X;
}
SV neuts; LV neutl;
vector<SV> p;
vector<LV> lazy;
vector<pl> range;
ST() {N=0LL;}
ST(vector<ll> arr)
{
N = (ll) 1<<(ll) ceil(log2(arr.size()));
REP(i,0,2*N) {range.pb(mp(0LL,0LL));}
REP(i,0,N) {p.pb(neuts);}
REP(i,0,arr.size()) {SV X(arr[i]); p.pb(X); range[i+N]=mp(i,i);}
REP(i,arr.size(),N) {p.pb(neuts); range[i+N]=mp(i,i);}
ll cur = N-1;
while(cur>0)
{
p[cur]=p[2*cur]&p[2*cur+1];
range[cur]=mp(range[2*cur].ff,range[2*cur+1].ss);
cur--;
}
REP(i,0,2*N) {lazy.pb(neutl);}
}
void prop(ll c) //how lazy values propagate
{
p[c]=upval(c);
lazy[2*c]=lazy[c]&lazy[2*c]; lazy[2*c+1]=lazy[c]&lazy[2*c+1];
lazy[c]=neutl;
}
SV query(ll a,ll b, ll c=1LL) //range [a,b], current node. initially: query(a,b,1)
{
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return neuts;}
if(x>=a && y<=b) {return upval(c);}
prop(c);
SV ans = query(a,b,2*c)&query(a,b,2*c+1);
return ans;
}
void update(LV s, ll a, ll b, ll c=1LL) //update LV, range [a,b], current node, current range. initially: update(s,a,b,1,0,S.N-1)
{
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return ;}
if(x>=a && y<=b)
{
lazy[c]=s&lazy[c];
return;
}
update(s,a,b,2*c); update(s,a,b,2*c+1);
p[c]=upval(2*c)&upval(2*c+1);
}
};
class DynamicST
{
public:
ll N;
class SV //seg value
{
public:
ll a;
SV() {a=0LL;}
SV(ll x) {a=x;}
SV operator & (SV X) {SV ANS(a+X.a); return ANS;}
};
class LV //lazy value
{
public:
ll a;
LV() {a=0LL;}
LV(ll x) {a=x;}
LV operator & (LV X) {LV ANS(a+X.a); return ANS;}
};
SV upval(ll c) //how lazy values modify a seg value inside a node, c=current node
{
SV X((m[c]->sv).a+(m[c]->r-m[c]->l+1)*(m[c]->lv).a);
return X;
}
SV neuts; LV neutl;
class node
{
public:
ll ind;
SV sv; LV lv;
ll l,r; //range
node * par, *lson, *rson;
node(ll ind2, SV sv2, LV lv2, unordered_map<ll,node *> *m)
{
ind=ind2; sv=sv2; lv=lv2; lson=nullptr; rson=nullptr;
if(ind==1) {l=0LL;par=nullptr;}
else
{
node * X = (*m)[ind/2];
par=X;
if(ind%2==0)
{
par->lson=this;
l=X->l; r=(X->l+X->r)/2LL;
}
else
{
par->rson=this;
l=(X->l+X->r+1)/2; r=X->r;
}
}
}
};
unordered_map<ll,node *> m;
node *root;
DynamicST(ll n)
{
N = (ll) 1<<(ll) ceil(log2(n));
node *X = new node(1,neuts,neutl,&m);
root=X; root->r=N-1LL;
}
void prop(ll c) //how lazy values propagate
{
m[c]->sv=upval(c);
if(m[c]->lson==nullptr) {node *X=new node(2*c,neuts,neutl,&m);}
if(m[c]->rson==nullptr) {node *X=new node(2*c+1,neuts,neutl,&m);}
m[2*c]->lv=m[c]->lv&m[2*c]->lv; m[2*c+1]->lv=m[c]->lv&m[2*c+1]->lv;
m[c]->lv=neutl;
if(2*c>=N)
{
m[2*c]->sv=upval(2*c); m[2*c+1]->sv=upval(2*c+1);
m[2*c]->lv=neutl; m[2*c+1]->lv=neutl;
}
}
SV query(ll a,ll b, ll c) //range [a,b], current node. initially: query(a,b,1)
{
ll x=m[c]->l; ll y=m[c]->r;
if(y<a || x>b) {return neuts;}
if(x>=a && y<=b) {return upval(c);}
prop(c);
SV ans = query(a,b,2*c)&query(a,b,2*c+1);
return ans;
}
void update(LV s, ll a, ll b, ll c) //update LV, range [a,b], current node, current range. initially: update(s,a,b,1,0,S.N-1)
{
ll x=m[c]->l; ll y=m[c]->r;
if(y<a || x>b) {return ;}
if(x>=a && y<=b)
{
m[c]->lv=s&m[c]->lv;
if(c>=N) {m[c]->sv=upval(c); m[c]->lv=neutl;}
return;
}
if(m[c]->lson==nullptr) {node *X=new node(2*c,neuts,neutl,&m);}
if(m[c]->rson==nullptr) {node *X=new node(2*c+1,neuts,neutl,&m);}
update(s,a,b,2*c); update(s,a,b,2*c+1);
m[c]->sv=upval(2*c)&upval(2*c+1);
}
};
class PersistentST
{
public:
ll N;
class SV //seg value
{
public:
ll a;
SV() {a=0LL;}
SV(ll x) {a=x;}
SV operator & (SV X) {SV ANS(a+X.a); return ANS;}
};
class LV //lazy value
{
public:
ll a;
LV() {a=0LL;}
LV(ll x) {a=x;}
LV operator & (LV X) {LV ANS(a+X.a); return ANS;}
};
SV neuts; LV neutl;
class node
{
public:
ll ind;
SV sv; LV lv;
ll l,r; //range
ll rootind; //x: this node is root[x]
node *lson, *rson;
node(ll ind,node *par, SV sv2, LV lv2, ll rootindex=-1LL)
{
rootind=rootindex;
sv=sv2; lv=lv2; lson=nullptr; rson=nullptr;
if(par==nullptr) {l=0LL;}
else
{
if(ind%2==0)
{
par->lson=this;
l=par->l; r=(par->l+par->r)/2LL;
}
else
{
par->rson=this;
l=(par->l+par->r+1)/2; r=par->r;
}
}
}
};
SV upval(node *X) //how lazy values modify a seg value inside a node, c=current node
{
SV ANS((X->sv).a+(X->r-X->l+1)*(X->lv).a);
return ANS;
}
vector<node*> root;
vector<ll> anc; //ancestor of a seg tree copy
unordered_map<ll,node*> m; //stores current update
PersistentST(ll n)
{
N = (ll) 1<<(ll) ceil(log2(n));
node *X = new node(1LL,nullptr,neuts,neutl,0LL);
X->r=N-1LL;
root.pb(X);
anc.pb(0LL);
m[0]=nullptr;
}
void Build(node *cur) //goes from dynamic to fixed (except for persistence). init: Build(root[x])
{
if(cur->ind>=N) {return;}
node *X = new node(2*cur->ind,cur,neuts,neutl);
node *Y = new node(2*cur->ind+1,cur,neuts,neutl);
Build(X);
Build(Y);
}
void prop(node *cur) //how lazy values propagate
{
cur->sv=upval(cur);
if(cur->lson==nullptr) {node *X=new node(2*cur->ind,cur,neuts,neutl);}
if(cur->rson==nullptr) {node *X=new node(2*cur->ind+1,cur,neuts,neutl);}
node *X=cur->lson; node *Y=cur->rson;
X->lv=cur->lv&X->lv; Y->lv=cur->lv&Y->lv;
cur->lv=neutl;
if(2*cur->ind>=N)
{
X->sv=upval(X); Y->sv=upval(Y);
X->lv=neutl; Y->lv=neutl;
}
}
SV query(ll a,ll b, node *cur) //range [a,b], current node. initially: query(a,b,root[x]) for a query in seg tree number x
{
ll x=cur->l; ll y=cur->r;
if(y<a || x>b) {return neuts;}
if(x>=a && y<=b) {return upval(cur);}
prop(cur);
SV ans = query(a,b,cur->lson)&query(a,b,cur->rson);
return ans;
}
void CreateCopy(node *cur)
{
node *X = new node(cur->ind,m[cur->ind/2],cur->sv,cur->lv);
X->lson=cur->lson; X->rson=cur->rson;
m[cur->ind]=X;
if(cur->ind==1) {X->rootind=root.size(); root.pb(X); anc.pb(cur->rootind);}
}
void update(LV s, ll a, ll b, node *cur) //update LV, range [a,b], current node, current range. initially: update(s,a,b,0,S.N-1,root[x]). This will create a new seg tree version.
{
ll x=cur->l; ll y=cur->r;
if(y<a || x>b) {return;}
CreateCopy(cur);
node *X=m[cur->ind];
if(x>=a && y<=b)
{
X->lv=s&X->lv;
if(X->ind>=N) {X->sv=upval(X); X->lv=neutl;}
return;
}
if(cur->lson==nullptr) {node *Z=new node(2*cur->ind,cur,neuts,neutl);}
if(cur->rson==nullptr) {node *Z=new node(2*cur->ind+1,cur,neuts,neutl);}
update(s,a,b,cur->lson); update(s,a,b,cur->rson);
X->sv=upval(cur->lson)&upval(cur->rson);
}
};
class WDiGraph
{
public:
ll N;
vector<vector<pl> > adj;
vector<bool> visited;
vector<ll> current; //for CC
vector<bool> c; //for Bip
bool bip; //for Bip
vector<ll> TS;//Top Sort
vector<ll> SCC; //Attributes a number to each node
vector<vector<pl> > adjK; //reverse graph, for Kosaraju
vector<bool> pr; //for Djikstra
vector<ll> nv; //for Floyd
vector<bool> deleted; //dynamic graph
vector<unordered_set<ll> > adjs,adjr; //dynamic graph
unordered_map<pl,ll,hash_pair> we; //dynamic graph
vector<vector<pl> > adjFlow; //MaxFlow
unordered_map<pl,ll,hash_pair> m; //MaxFlow, m[(a,b)]=index of adjFlow[a] where b is stored, works for adj as well
unordered_map<pl,bool,hash_pair> exist; //maxFlow
ll src,ter; //MaxFlow, source and terminator/sink
bool reached; //MaxFlow
ll pathflow; //MaxFlow
vector<ll> lev; //Layered_Network,MaxFlow
vector<ll> nxted; //Dinics
Matrix Madj;
WDiGraph(vector<vector<pl> > ad)
{
adj=ad; N=adj.size(); REP(i,0,N) {pr.pb(false); nv.pb(0); visited.pb(false); c.pb(-1); SCC.pb(-1LL);}
vector<pl> xx; REP(i,0,N) {adjK.pb(xx);}
REP(i,0,adj.size())
{
REP(j,0,adj[i].size()) {adjK[adj[i][j].ff].pb(mp(i,adj[i][j].ss));}
}
unordered_set<ll> em; REP(i,0,N) {adjs.pb(em); adjr.pb(em);}
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
adjs[i].insert(adj[i][j].ff);
adjr[adj[i][j].ff].insert(i);
we[mp(i,adj[i][j].ff)]=adj[i][j].ss;
}
}
REP(i,0,N) {deleted.pb(false);}
}
void Reset()
{
REP(i,0,N) {visited[i]=false;}
current.clear();
unordered_set<ll>::iterator it;
REP(i,0,N) {adj[i].clear();it=adjs[i].begin(); while(it!=adjs[i].end()) {adj[i].pb(mp(*it,we[mp(i,*it)])); it++;}}
}
void DFS(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i].ff]) {c[adj[s][i].ff]=(c[s]+1)%2; DFS(adj[s][i].ff);}
else if(c[adj[s][i].ff]==c[s]) {bip=false;}
}
current.pb(s); //only needed for Kosaraju
return;
}
vector<ll> BFS(ll s)
{
vector<ll> distance; REP(i,0,N) {distance.pb(INF);}
REP(i,0,N) {visited[i]=false;}
distance[s]=0; visited[s]=true;
deque<ll> d; d.pb(s); ll cur;
while(!d.empty())
{
cur=d.front(); d.pop_front();
REP(i,0,adj[cur].size())
{
if(!visited[adj[cur][i].ff])
{
visited[adj[cur][i].ff]=true;
d.pb(adj[cur][i].ff);
distance[adj[cur][i].ff]=distance[cur]+1;
}
}
}
return distance;
}
bool Bip()
{
c[0]=0;
bip=true;
DFS(0);
if(bip) {return true;}
else {return false;}
}
void DFSTS(ll s)
{
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i].ff]) {DFSTS(adj[s][i].ff);}
}
visited[s]=true;
}
void TopSort()
{
Reset();
REP(i,0,N)
{
if(visited[i]) {continue;}
DFSTS(i);
}
reverse(TS.begin(),TS.end());
}
void DFSK(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
REP(i,0,adjK[s].size())
{
if(!visited[adjK[s][i].ff]) {DFSK(adjK[s][i].ff);}
}
current.pb(s); //only needed for Kosaraju
return;
}
void Kosaraju()
{
if(SCC[0]!=-1) {return;}
Reset();
REP(i,0,N)
{
if(visited[i]) {continue;}
DFS(i);
}
vector<ll> List=current;
Reset();
ll c=0LL;
for(ll i=N-1LL;i>=0LL;i--)
{
ll node=List[i];
if(visited[node]) {continue;}
DFSK(node);
REP(j,0,current.size()) {SCC[current[j]]=c;}
c++;
current.clear();
}
}
WDiGraph SCCGraph()
{
Kosaraju();
set<pair<pl,ll> > ed;
REP(i,0,adj.size())
{
REP(j,0,adj[i].size())
{
ed.insert(mp(mp(SCC[i],SCC[adj[i][j].ff]),adj[i][j].ss));
}
}
vector<vector<pl> > a; vector<pl> xx;
ll nscc=-INF; REP(i,0,N) {nscc=max(nscc,SCC[i]+1LL);}
REP(i,0,nscc) {a.pb(xx);}
set<pair<pl,ll> >::iterator it=ed.begin();
pair<pl,ll> cur; pl last=mp(-1,-1);
while(it!=ed.end())
{
cur=*it;
if(cur.ff!=last && cur.ff.ff!=cur.ff.ss) {a[cur.ff.ff].pb(mp(cur.ff.ss,cur.ss)); } //only shortes paths are relevant
last=cur.ff;
it++;
}
WDiGraph ans(a);
return ans;
}
vector<ll> Djikstra(ll s)
{
Reset();
vector<ll> d; REP(i,0,N) {d.pb(INF);}
d[s]=0;
priority_queue<pl> q;
q.push(mp(0,s));
ll cur;
while(!q.empty())
{
cur=q.top().ss; q.pop();
if(pr[cur]) {continue;}
pr[cur]=true;
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff]>d[cur]+adj[cur][i].ss)
{
d[adj[cur][i].ff]=d[cur]+adj[cur][i].ss;
q.push(mp(-d[adj[cur][i].ff],adj[cur][i].ff));
}
}
}
return d;
}
vector<pl> Djikstra_MS(vector<ll> sn) //Djikstra Multi-sourced, ans[i].ff=d(i,sn), ans[i].ss=member of sn closest to i
{
Reset();
ll K=sn.size();
vector<pl> d; REP(i,0,N) {d.pb(mp(INF,-1LL));}
REP(i,0,K) {d[sn[i]]=mp(0LL,sn[i]);}
priority_queue<pl> q;
REP(i,0,K) {q.push(mp(0,sn[i]));}
ll cur;
while(!q.empty())
{
cur=q.top().ss; q.pop();
if(pr[cur]) {continue;}
pr[cur]=true;
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff].ff>d[cur].ff+adj[cur][i].ss)
{
d[adj[cur][i].ff].ff=d[cur].ff+adj[cur][i].ss;
d[adj[cur][i].ff].ss=d[cur].ss;
q.push(mp(-d[adj[cur][i].ff].ff,adj[cur][i].ff));
}
}
}
return d;
}
vector<ll> SPFA(ll s)
{
Reset();
vector<ll> d; REP(i,0,N) {d.pb(INF);}
d[s]=0;
deque<ll> tv; tv.pb(s); pr[s]=true;
ll cur; ll mv=0;
while(!tv.empty())
{
cur=tv.front(); tv.pop_front(); pr[cur]=false;
nv[cur]++; mv=max(mv,nv[cur]);
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff]>d[cur]+adj[cur][i].ss)
{
d[adj[cur][i].ff]=d[cur]+adj[cur][i].ss;
if(!pr[adj[cur][i].ff]) {tv.pb(adj[cur][i].ff);}
pr[adj[cur][i].ff]=true;
}
}
if(mv>=N) {d.clear(); break;} //negative cycle
}
return d;
}
vector<pl> SPFA_MS(vector<ll> sn)
{
ll K=sn.size();
Reset();
vector<pl> d; REP(i,0,N) {d.pb(mp(INF,-1LL));}
REP(i,0,K) {d[sn[i]]=mp(0LL,sn[i]);}
deque<ll> tv; REP(i,0,K) {tv.pb(sn[i]); pr[sn[i]]=true;}
ll cur; ll mv=0;
while(!tv.empty())
{
cur=tv.front(); tv.pop_front(); pr[cur]=false;
nv[cur]++; mv=max(mv,nv[cur]);
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff].ff>d[cur].ff+adj[cur][i].ss)
{
d[adj[cur][i].ff].ff=d[cur].ff+adj[cur][i].ss;
d[adj[cur][i].ff].ss=d[cur].ss;
if(!pr[adj[cur][i].ff]) {tv.pb(adj[cur][i].ff);}
pr[adj[cur][i].ff]=true;
}
}
if(mv>=N) {d.clear(); break;} //negative cycle
}
return d;
}
vector<vector<ll> > Floyd() //assumes there is no neg cycle
{
Reset();
vector<vector<ll> > d; vector<ll> xx; REP(i,0,N) {xx.pb(INF);} REP(i,0,N) {d.pb(xx);}
REP(i,0,N)
{
d[i][i]=0;
REP(j,0,adj[i].size())
{
d[i][adj[i][j].ff]=adj[i][j].ss;
}
}
REP(i,0,N)
{
REP(q1,0,N)
{
REP(q2,0,N)
{
if(q1==q2) {continue;}
d[q1][q2]=min(d[q1][q2],d[q1][i]+d[i][q2]);
}
}
}
return d;
}
void erase_edge(pl edge)
{
adjs[edge.ff].erase(edge.ss); adjr[edge.ss].erase(edge.ff);
}
void add_edge(pair<pl,ll> edge)
{
if(adjs[edge.ff.ff].find(edge.ff.ss)==adjs[edge.ff.ff].end())
{
we[edge.ff]=edge.ss;
adjs[edge.ff.ff].insert(edge.ff.ss); adjr[edge.ff.ss].insert(edge.ff.ff);
}
else
{
we[edge.ff]+=edge.ss;
}
}
void erase_node(ll s)
{
deleted[s]=true;
unordered_set<ll>::iterator it; it=adjs[s].begin(); vector<pl> e;
while(it!=adjs[s].end())
{
e.pb(mp(s,*it));
it++;
}
REP(i,0,e.size()) {erase_edge(e[i]);}
}
void add_node(vector<pl> in, vector<pl> out) // adds node with adjacency list con, and index N
{
N++; pr.pb(false); nv.pb(0); deleted.pb(false); unordered_set<ll> em; vector<pl> emm; adjs.pb(em); adj.pb(emm);
REP(i,0,in.size()) {add_edge(mp(mp(in[i].ff,N-1),in[i].ss));}
REP(i,0,out.size()) {add_edge(mp(mp(N-1,out[i].ff),out[i].ss));}
}
void RGConstructor(ll source, ll terminator) //Constructs Residual Grap, adjFlow, map m
{
src=source; ter=terminator;
adjFlow=adj;
REP(i,0,N)
{
REP(j,0,adj[i].size()) {m[mp(i,adj[i][j].ff)]=j; exist[mp(i,adj[i][j].ff)]=true;}
}
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
if(!exist[mp(adj[i][j].ff,i)]) {adjFlow[adj[i][j].ff].pb(mp(i,0LL)); m[mp(adj[i][j].ff,i)]=adjFlow[adj[i][j].ff].size()-1;}
}
}
REP(i,0,N) {lev.pb(-1); nxted.pb(0LL);}
}
void ResetFlow()
{
REP(i,0,N) {visited[i]=false;}
pathflow=0LL; reached=false;
}
void BFSFlow(ll s) //builds Layered Network
{
Reset();
REP(i,0,N) {lev[i]=INF;}
REP(i,0,N) {visited[i]=false;}
lev[s]=0; visited[s]=true;
deque<ll> d; d.pb(s); ll cur;
while(!d.empty())
{
cur=d.front(); d.pop_front();
REP(i,0,adjFlow[cur].size())
{
ll node=adjFlow[cur][i].ff;
if(!visited[node] && adjFlow[cur][i].ss>0LL)
{
visited[node]=true;
d.pb(node);
lev[node]=lev[cur]+1;
}
}
}
}
void DFSFlow1(ll s, ll flow, ll D) //Scaling
{
if(reached) {return;}
if(visited[s]) {return;}
ll node,we;
if(s==ter) {reached=true; pathflow=flow; return;}
visited[s]=true;
REP(i,0,adjFlow[s].size())
{
node=adjFlow[s][i].ff; we=adjFlow[s][i].ss;
if(visited[node]) {continue;}
if(we<D) {continue;}
DFSFlow1(node,min(flow,we),D);
if(reached)
{
adjFlow[s][i].ss-=pathflow;
adjFlow[node][m[mp(node,s)]].ss+=pathflow;
break;
}
}
return;
}
void DFSFlow2(ll s, ll flow) //Dinics
{
if(reached) {return;}
if(visited[s]) {return;}
ll node,we;
if(s==ter) {reached=true; pathflow=flow; return;}
visited[s]=true;
REP(i,nxted[s],adjFlow[s].size())
{
node=adjFlow[s][i].ff; we=adjFlow[s][i].ss;
if(visited[node]) {continue;}
if(we==0) {continue;}
if(lev[node]<=lev[s]) {nxted[s]++;continue;}
DFSFlow2(node,min(flow,we));
if(reached)
{
adjFlow[s][i].ss-=pathflow;
if(adjFlow[s][i].ss==0) {nxted[s]++;}
adjFlow[node][m[mp(node,s)]].ss+=pathflow;
break;
}
nxted[s]++;
}
return;
}
ll MF_Scaling(ll source, ll terminator) //min(O(E*MaxFlow),O(E^2*log(Emax))), prefered choice for weighted
{
RGConstructor(source,terminator);
ll flow=0LL; ll D=0LL; REP(i,0,N) {REP(j,0,adjFlow[i].size()) {D=max(D,adjFlow[i][j].ss);}}
while(D>0LL)
{
ResetFlow(); DFSFlow1(src,INF,D);
if(reached) {flow+=pathflow;}
else {D=D/2LL;}
}
return flow;
}
ll MF_Dinic(ll source, ll terminator) //O(EV^2), specil case unweighted graph: min(O(EV^2/3),O(E^3/2)), special case unit network: O(EV^1/2)
{
RGConstructor(source,terminator);
ll flow=0LL; bool al=true;
while(1>0)
{
ResetFlow(); DFSFlow2(src,INF);
if(reached) {al=true; flow+=pathflow;}
else if(!al) {break;}
else {REP(i,0,N) {nxted[i]=0LL;} al=false; BFSFlow(src);}
}
return flow;
}
vector<pl> MinCut(ll source, ll terminator)
{
MF_Dinic(source, terminator);
ResetFlow(); DFSFlow1(src,INF,1);
vector<pl> ans;
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
if(visited[i] && !visited[adj[i][j].ff]) {ans.pb(mp(i,adj[i][j].ff));}
}
}
return ans;
}
Matrix SMul(Matrix A, Matrix B)
{
if(A.M!=B.N) {Matrix ANS; return ANS;}
vector<double> xx; vector<vector<double> > ans; REP(i,0,B.M) {xx.pb((double) (INF));} REP(i,0,A.N) {ans.pb(xx);}
REP(i,0,A.N)
{
REP(j,0,B.M)
{
double val=(double) INF;
REP(k,0,A.M) {val=min(val,A.a[i][k]+B.a[k][j]);}
ans[i][j]=val;
}
}
Matrix ANS(ans); return ANS;
}
Matrix fastexpS(Matrix A, ll e) //O(N^3loge)
{
if(A.N!=A.M) {Matrix ANS; return ANS;}
if(e<0) {A.RRE();if(A.rank==0) {e=0LL;} else {return fastexpS(*(A.Inv),-e);}}
if(e==0)
{Matrix ANS=A; REP(i,0,A.N) {REP(j,0,A.N) {if(i!=j) {ANS.a[i][j]=(double) INF;} else {ANS.a[i][j]=0.0;}}} return ANS;}
if(e%2LL==0)
{
Matrix V =fastexpS(A,(ll) e/2LL); return SMul(V,V);
}
else
{
Matrix V=fastexpS(A,(ll) e/2LL); return SMul(SMul(V,V),A);
}
}
void Build_Madj()
{
if(Madj.N!=0LL) {return;}
vector<vector<double> > madj; vector<double> xx; REP(i,0,N) {xx.pb((double) (INF));} REP(i,0,N) {madj.pb(xx);}
REP(i,0,N) {REP(j,0,adj[i].size()) {madj[i][adj[i][j].ff]=(double) (adj[i][j].ss);}}
Matrix B(madj); Madj=B;
}
double SP(ll a, ll b, ll length) //shortest path between a,b with fixed length, O(N^3loglength)
{
Build_Madj();
return (fastexpS(Madj,length).a[a][b]);
}
};
class Graph
{
public:
ll N;
vector<vector<ll> > adj;
vector<ll> visited; //for DFS/BFS
vector<ll> current; //for CC
vector<bool> c; //for Bip
bool bip; //for Bip
unordered_map<pair<vector<bool>,ll>,vector<ll>,hash_pair> mH; //for Hamiltonian
vector<list<ll> > ad; //for Hierholzer
unordered_map<pl,bool,hash_pair> valid; //for Hierholzer
Matrix Madj;
vector<ll> og; //node i points to value og[i]
vector<vector<ll> > dfs_tree;
Graph() {ll N=0LL;}
Graph(vector<vector<ll> > ad)
{
adj=ad; N=adj.size(); REP(i,0,N) {visited.pb(false); c.pb(-1);}
}
void Reset()
{
REP(i,0,N) {visited[i]=false;}
current.clear();
}
void DFS(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
current.pb(s); //only needed for CC
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i]]) {c[adj[s][i]]=(c[s]+1)%2; DFS(adj[s][i]);}
else if(c[adj[s][i]]==c[s]) {bip=false;}
}
return;
}
void DFS_Tree(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i]]) {dfs_tree[s].pb(adj[s][i]); dfs_tree[adj[s][i]].pb(s); DFS_Tree(adj[s][i]);}
}
return;
}
bool Connected()
{
Reset();
DFS(0);
REP(i,0,N) {if(!visited[i]) {return false;}}
return true;
}
vector<ll> BFS(ll s)
{
Reset();
vector<ll> distance; REP(i,0,N) {distance.pb(INF);}
REP(i,0,N) {visited[i]=false;}
distance[s]=0; visited[s]=true;
deque<ll> d; d.pb(s); ll cur;
while(!d.empty())
{
cur=d.front(); d.pop_front();
REP(i,0,adj[cur].size())
{
if(!visited[adj[cur][i]])
{
visited[adj[cur][i]]=true;
d.pb(adj[cur][i]);
distance[adj[cur][i]]=distance[cur]+1;
}
}
}
return distance;
}
vector<pl> BFS_MS(vector<ll> sn) //multi-sourced BFS, ans[i].ff=d(i,starting nodes), ans[i].ss=starting node closer to i
{
Reset();
ll K=sn.size();
vector<pl> distance; REP(i,0,N) {distance.pb(mp(INF,-1LL));}
REP(i,0,N) {visited[i]=false;}
REP(i,0,K) {distance[sn[i]]=mp(0LL,sn[i]); visited[sn[i]]=true;}
deque<ll> d; REP(i,0,K) {d.pb(sn[i]);} ll cur;
while(!d.empty())
{
cur=d.front(); d.pop_front();
REP(i,0,adj[cur].size())
{
if(visited[adj[cur][i]]) {continue;}
visited[adj[cur][i]]=true;
d.pb(adj[cur][i]);
distance[adj[cur][i]].ff=distance[cur].ff+1;
distance[adj[cur][i]].ss=distance[cur].ss;
}
}
return distance;
}
vector<vector<ll> > CC()
{
Reset();
ll fi=0; ll missing=N; REP(i,0,N) {visited[i]=false;}
vector<vector<ll> > ans;
while(missing>0)
{
REP(i,fi,N) {if(!visited[i]) {fi=i; break;}}
current.clear();
DFS(fi);
ans.pb(current);
missing-=current.size();
}
return ans;
}
vector<Graph> CCG()
{
Reset();
vector<Graph> ans;
vector<vector<ll> > CC=(*this).CC();
unordered_map<ll,ll> m;vector<ll> xx; vector<vector<ll> > ad;
vector<ll> ma;
REP(cc,0,CC.size())
{
m.clear(); ma.clear();
ad.clear();
ll NN=CC[cc].size();
REP(i,0,NN) {ad.pb(xx);}
REP(i,0,NN) {m[CC[cc][i]]=i; ma[i]=ma[CC[cc][i]];}
ll a,b;
REP(i,0,NN)
{
a=CC[cc][i];
REP(j,0,adj[a].size()) {b=adj[a][j]; ad[i].pb(m[b]);}
}
Graph H(ad); H.og=ma;
ans.pb(H);
}
return ans;
}
bool Bip()
{
Reset();
bip=true;
REP(i,0,N)
{
if(visited[i]) {continue;}
c[i]=0LL; DFS(i);
}
if(bip) {return true;}
else {return false;}
}
bool Eulerian()
{
Reset();
REP(i,0,N) {if(adj[i].size()%2!=0) {return false;}}
return true;
}
vector<ll> Hamiltonian()
{
bool Ore=true;
vector<bool> v; REP(i,0,N) {v.pb(true);}
REP(i,0,N)
{
REP(j,0,N) {v[j]=true;}
v[i]=false;
REP(j,0,adj[i].size()) {v[adj[i][j]]=false;}
REP(j,0,N)
{
if(v[j] && adj[i].size()+adj[j].size()<N) {Ore=false; break;}
}
}
if(Ore) {return Palmer();}
REP(i,0,N) {v[i]=true;}
REP(i,0,N)
{
if(!f(v,i).empty()) {return f(v,i);}
}
vector<ll> ans; return ans;
}
vector<ll> f(vector<bool> v, ll x) //O(N^2*2^N), for when we dont know anything about the graph
{
if(!mH[mp(v,x)].empty()) {return mH[mp(v,x)];}
ll oc=0LL; REP(i,0,N) {if(v[i]) {oc++;}}
vector<ll> ans;
if(oc==1) {ans.pb(x);}
else
{
v[x]=false; ll node;
REP(i,0,adj[x].size())
{
node=adj[x][i];
if(!v[node]) {continue;}
vector<ll> p=f(v,node);
if(!p.empty()) {p.pb(x); ans=p; break;}
}
}
mH[mp(v,x)]=ans;
return ans;
}
vector<ll> Palmer() //O(N^2), constructs Hamiltonian Cycle if Ore's condition is fullfilled
{
vector<ll> ans; REP(i,0,N) {ans.pb(i);}
vector<vector<bool> > madj; vector<bool> dummy; REP(i,0,N) {dummy.pb(false);} REP(i,0,N) {madj.pb(dummy);}
REP(i,0,N) {REP(j,0,adj[i].size()) {madj[i][adj[i][j]]=true; madj[adj[i][j]][i]=true;}}
REP(cnt,0,N)
{
ll ind1=-1LL;
REP(i,0,N)
{
if(!madj[ans[i]][ans[(i+1)%N]]) {ind1=i; break;}
}
if(ind1==-1) {break;}
ll ind2=-1LL;
REP(j,0,N)
{
if(madj[ans[ind1]][ans[j]] && madj[ans[(ind1+1)%N]][ans[(j+1)%N]]) {ind2=j; break;}
}
REP(i,0,((ind2-ind1+N)%N +1)/2LL)
{
ll node1=(ind1+1+i)%N;
ll node2=(ind2-i)%N;
swap(ans[node1],ans[node2]);
}
}
return ans;
}
void Tour(ll s)
{
current.pb(s);
if(ad[s].size()==0) {return;}
ll nxt=*ad[s].begin();
while(!valid[mp(s,nxt)])
{
valid[mp(nxt,s)]=false; ad[s].erase(ad[s].begin());
if(ad[s].size()==0) {return;}
nxt=*ad[s].begin();
}
valid[mp(s,nxt)]=false; valid[mp(nxt,s)]=false;
ad[s].erase(ad[s].begin());
Tour(nxt);
}
vector<ll> Hierholzer()
{
ll nodd=0LL; REP(i,0,N) {if(adj[i].size()%2!=0) {nodd++;}}
list<ll> ans;
if(nodd>2LL) {vector<ll> xx; return xx;}
vector<vector<ll> > indiferent=CC(); ll nsb1=0LL;
REP(i,0,indiferent.size()) {if(indiferent[i].size()>1LL) {nsb1++;}}
if(nsb1>1LL) {vector<ll> xx; return xx;}
ll sn=0LL; REP(i,0,N) {if(adj[i].size()%2!=0) {sn=i;}}
list<ll> xx;
REP(i,0,N) {xx.clear(); xx.insert(xx.begin(),adj[i].begin(),adj[i].end()); ad.pb(xx);}
ans.insert(ans.begin(),sn);
list<ll>::iterator it=ans.begin();
REP(i,0,N) {REP(j,0,adj[i].size()) {valid.insert(mp(mp(i,adj[i][j]),true));}}
REP(i,0,INF)
{
if(it==ans.end()) {break;}
current.clear();
Tour(*it);
it=ans.erase(it);
it=ans.insert(it,current.begin(),current.end());
it++;
}
it=ans.begin();
vector<ll> f_ans; REP(i,0,ans.size()) {f_ans.pb(*it); it++;}
return f_ans;
}
ll MaxMatching()
{
if(!Bip()) {return -1;}
vector<vector<pl> > Wadj; vector<pl> xx; REP(i,0,N+2) {Wadj.pb(xx);}
REP(i,0,N)
{
if(c[i]==1) {Wadj[i].pb(mp(N+1,1)); continue;}
Wadj[N].pb(mp(i,1));
REP(j,0,adj[i].size())
{
Wadj[i].pb(mp(adj[i][j],1));
}
}
WDiGraph G(Wadj);
return G.MF_Dinic(N,N+1);
}
void Build_Madj()
{
if(Madj.N!=0LL) {return;}
vector<vector<double> > madj; vector<double> xx; REP(i,0,N) {xx.pb(0.0);} REP(i,0,N) {madj.pb(xx);}
REP(i,0,N) {REP(j,0,adj[i].size()) {madj[i][adj[i][j]]=1.0;}}
Matrix B(madj); Madj=B;
}
ll cnt_path(ll a, ll b, ll length)
{
Build_Madj();
return fastexp(Madj,length).a[a][b];
}
};
class DynamicGraph
{
public:
ll N; ll nxt_id;
class node
{
public:
ll id; //unique non-negative integer id
unordered_set<ll> adj;
node() {id=-1;}
node(ll ident, vector<ll> ad) {id=ident; REP(i,0,ad.size()) {adj.insert(ad[i]);}}
};
unordered_map<ll,node> m;
unordered_set<ll> active_id; //active node ids
DynamicGraph(vector<vector<ll> > adj)
{
N=adj.size();
REP(i,0,N)
{
node X(i,adj[i]);
m[i]=X;
active_id.insert(i);
}
nxt_id=N;
}
void add_edge(pl edge)
{
m[edge.ff].adj.insert(edge.ss);
m[edge.ss].adj.insert(edge.ff);
}
void erase_edge(pl edge)
{
m[edge.ff].adj.erase(edge.ss);
m[edge.ss].adj.erase(edge.ff);
}
void add_node(vector<ll> ad)
{
N++; vector<ll> em;
node X(nxt_id,em); m[nxt_id]=X; active_id.insert(nxt_id); nxt_id++;
REP(i,0,ad.size())
{
add_edge(mp(nxt_id-1,ad[i]));
}
}
void erase_node(ll id)
{
N--;
vector<pl> toerase;
unordered_set<ll>::iterator it=m[id].adj.begin();
while(it!=m[id].adj.end())
{
toerase.pb(mp(id,*it)); it++;
}
REP(i,0,toerase.size()) {erase_edge(toerase[i]);}
active_id.erase(id);
m.erase(id);
}
};
class DynamicDiGraph
{
public:
ll N; ll nxt_id;
class node
{
public:
ll id; //unique non-negative integer id
unordered_set<ll> adj;
unordered_set<ll> adjr;
node() {id=-1;}
node(ll ident, vector<ll> ad) {id=ident; REP(i,0,ad.size()) {adj.insert(ad[i]);}}
};
unordered_map<ll,node> m;
unordered_set<ll> active_id; //active node ids
DynamicDiGraph(vector<vector<ll> > adj)
{
N=adj.size();
REP(i,0,N)
{
node X;
m[i]=X;
active_id.insert(i);
}
nxt_id=N;
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
m[i].adj.insert(adj[i][j]);
m[adj[i][j]].adjr.insert(i);
}
}
}
void add_edge(pl edge)
{
m[edge.ff].adj.insert(edge.ss);
m[edge.ss].adjr.insert(edge.ff);
}
void erase_edge(pl edge)
{
m[edge.ff].adj.erase(edge.ss);
m[edge.ss].adjr.erase(edge.ff);
}
void add_node(vector<ll> in,vector<ll> out)
{
N++; vector<ll> em;
node X(nxt_id,em); m[nxt_id]=X; active_id.insert(nxt_id); nxt_id++;
REP(i,0,in.size())
{
add_edge(mp(in[i],nxt_id-1));
}
REP(i,0,out.size())
{
add_edge(mp(nxt_id-1,out[i]));
}
}
void erase_node(ll id)
{
N--;
vector<pl> toerase;
unordered_set<ll>::iterator it;
it=m[id].adj.begin();
while(it!=m[id].adj.end())
{
toerase.pb(mp(id,*it)); it++;
}
it=m[id].adjr.begin();
while(it!=m[id].adjr.end())
{
toerase.pb(mp(*it,id)); it++;
}
REP(i,0,toerase.size()) {erase_edge(toerase[i]);}
active_id.erase(id);
m.erase(id);
}
};
class DynamicWG
{
public:
ll N; ll nxt_id;
unordered_map<pl,ll,hash_pair> we;
class node
{
public:
ll id; //unique non-negative integer id
unordered_set<ll> adj;
node() {id=-1;}
node(ll ident, vector<ll> ad) {id=ident; REP(i,0,ad.size()) {adj.insert(ad[i]);}}
};
unordered_map<ll,node> m;
unordered_set<ll> active_id; //active node ids
DynamicWG(vector<vector<pl> > adj)
{
N=adj.size();
vector<ll> em;
REP(i,0,N)
{
node X(i,em);
REP(j,0,adj[i].size()) {X.adj.insert(adj[i][j].ff); we[mp(i,adj[i][j].ff)]=adj[i][j].ss; we[mp(adj[i][j].ff,i)]=adj[i][j].ss;}
m[i]=X;
active_id.insert(i);
}
nxt_id=N;
}
void add_edge(pair<pl,ll> edge)
{
if(m[edge.ff.ff].adj.find(edge.ff.ss)!=m[edge.ff.ff].adj.end())
{
we[edge.ff]+=edge.ss; swap(edge.ff.ff,edge.ff.ss);
we[edge.ff]+=edge.ss;
}
else
{
m[edge.ff.ff].adj.insert(edge.ff.ss);
m[edge.ff.ss].adj.insert(edge.ff.ff);
we[edge.ff]=edge.ss; swap(edge.ff.ff,edge.ff.ss); we[edge.ff]=edge.ss;
}
}
void erase_edge(pl edge)
{
m[edge.ff].adj.erase(edge.ss);
m[edge.ss].adj.erase(edge.ff);
we.erase(edge);
}
void add_node(vector<pl> ad)
{
N++; vector<ll> em;
node X(nxt_id,em); m[nxt_id]=X; active_id.insert(nxt_id); nxt_id++;
REP(i,0,ad.size())
{
add_edge(mp(mp(nxt_id-1,ad[i].ff),ad[i].ss));
}
}
void erase_node(ll id)
{
N--;
vector<pl> toerase;
unordered_set<ll>::iterator it=m[id].adj.begin();
while(it!=m[id].adj.end())
{
toerase.pb(mp(id,*it)); it++;
}
REP(i,0,toerase.size()) {erase_edge(toerase[i]);}
active_id.erase(id);
m.erase(id);
}
};
class DynamicWDiGraph
{
public:
ll N; ll nxt_id;
unordered_map<pl,ll,hash_pair> we;
class node
{
public:
ll id; //unique non-negative integer id
unordered_set<ll> adj;
unordered_set<ll> adjr;
node() {id=-1;}
node(ll ident, vector<ll> ad) {id=ident; REP(i,0,ad.size()) {adj.insert(ad[i]);}}
};
unordered_map<ll,node> m;
unordered_set<ll> active_id; //active node ids
DynamicWDiGraph(vector<vector<pl> > adj)
{
N=adj.size();
REP(i,0,N)
{
node X;
m[i]=X;
active_id.insert(i);
}
nxt_id=N;
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
m[i].adj.insert(adj[i][j].ff);
m[adj[i][j].ff].adjr.insert(i);
we[mp(i,adj[i][j].ff)]=adj[i][j].ss;
}
}
}
void add_edge(pair<pl,ll> edge)
{
if(m[edge.ff.ff].adj.find(edge.ff.ss)!=m[edge.ff.ff].adj.end())
{
we[edge.ff]+=edge.ss;
}
else
{
m[edge.ff.ff].adj.insert(edge.ff.ss);
m[edge.ff.ss].adjr.insert(edge.ff.ff);
we[edge.ff]=edge.ss;
}
}
void erase_edge(pl edge)
{
m[edge.ff].adj.erase(edge.ss);
m[edge.ss].adjr.erase(edge.ff);
we.erase(edge);
}
void add_node(vector<pl> in,vector<pl> out)
{
N++; vector<ll> em;
node X(nxt_id,em); m[nxt_id]=X; active_id.insert(nxt_id); nxt_id++;
REP(i,0,in.size())
{
add_edge(mp(mp(in[i].ff,nxt_id-1),in[i].ss));
}
REP(i,0,out.size())
{
add_edge(mp(mp(nxt_id-1,out[i].ff),out[i].ss));
}
}
void erase_node(ll id)
{
N--;
vector<pl> toerase;
unordered_set<ll>::iterator it;
it=m[id].adj.begin();
while(it!=m[id].adj.end())
{
toerase.pb(mp(id,*it)); it++;
}
it=m[id].adjr.begin();
while(it!=m[id].adjr.end())
{
toerase.pb(mp(*it,id)); it++;
}
REP(i,0,toerase.size()) {erase_edge(toerase[i]);}
active_id.erase(id);
m.erase(id);
}
};
class Tree
{
public:
ll N;
vector<ll> p;
vector<vector<ll> > sons;
vector<vector<ll> > adj;
ll root;
vector<bool> visited;
vector<ll> level; //starting in 0
vector<ll> sub; //number of nodes in subtree
vector<ll> val; //node values
vector<ll> DFSarr1; //DFS Array
vector<ll> DFSarr2; //DFS Array for LCA with whole path
vector<ll> pos; //inverted DFSArr, only for LCA
vector<pl> levDFSarr; //array of levels on DFSarr, only needed for LCA
vector<ll> sumto; //weighted graph, length of path root-->i
SparseTable<pl> S; //for LCA
SucPath P; //for function f
ll max_steps; //for function f
vector<ll> prufer; //Prufer code, defines a tree uniquely
vector<ll> dist;
pair<ll,pl> diametre;
unordered_set<ll> included; //create new tree
vector<vector<ll> > back_edge; //in the case this tree is a DFS-tree
vector<pl> bridge;
vector<ll> articulation_point;
vector<ll> high_be; //highest back_edge per node
vector<ll> high_sub; //highest back_edge in subtree
vector<vector<ll> > farthest_dir;
vector<ll> farthest_down;
vector<ll> farthest_up;
vector<ll> farthest;
Tree(vector<vector<ll> > ad, ll r=0LL)
{
N=ad.size(); root=r; adj=ad;
REP(i,0,N) {visited.pb(false);}
vector<ll> xx; REP(i,0,N) {sons.pb(xx); p.pb(-1); level.pb(0); sub.pb(1LL); pos.pb(0LL); sumto.pb(0LL);}
DFS_Build(r,r);
REP(i,0,DFSarr2.size()) {pos[DFSarr2[i]]=i;}
REP(i,0,DFSarr2.size()) {levDFSarr.pb(mp(level[DFSarr2[i]],DFSarr2[i]));}
SparseTable<pl> X(levDFSarr); S=X;
max_steps=N;
SucPath Y(p,N); P=Y;
REP(i,0,N) {val.pb(0LL);}
vector<ll> xxx;
REP(i,0,N) {farthest_up.pb(0); farthest_down.pb(0); farthest_dir.pb(xxx); farthest.pb(0);}
REP(i,0,N) {REP(j,0,adj[i].size()) {farthest_dir[i].pb(0);}}
}
void Reset()
{
REP(i,0,N) {visited[i]=false;}
}
void DFS_Build(ll s, ll par)
{
DFSarr1.pb(s);
DFSarr2.pb(s);
if(s!=root) {level[s]=level[par]+1LL;}
p[s]=par;
visited[s]=true;
REP(i,0,adj[s].size())
{
if(adj[s][i]==par) {continue;}
sons[s].pb(adj[s][i]);
DFS_Build(adj[s][i],s);
sub[s]+=sub[adj[s][i]];
DFSarr2.pb(s);
}
return;
}
void DFS_sumto(ll s)
{
sumto[s]=sumto[p[s]]+val[s];
REP(i,0,sons[s].size())
{
DFS_sumto(sons[s][i]);
}
}
void DFS_distance(ll s, ll las)
{
REP(i,0,adj[s].size())
{
if(adj[s][i]==las) {continue;}
dist[adj[s][i]]=dist[s]+1;
DFS_distance(adj[s][i],s);
}
}
void distance(ll s)
{
dist.clear(); REP(i,0,N) {dist.pb(INF);}
dist[s]=0;
DFS_distance(s,s);
}
void Calc_Diametre()
{
distance(root);
vector<ll>::iterator it=max_element(whole(dist));
ll ind=it-dist.begin();
distance(ind);
diametre.ss.ff=ind;
it=max_element(whole(dist));
diametre.ss.ss=it-dist.begin();
diametre.ff=*it;
}
void DFS(ll s, ll las=-1LL)
{
REP(i,0,adj[s].size())
{
if(adj[s][i]==las) {continue;}
DFS(adj[s][i],s);
}
included.insert(s);
}
ll LCA(ll a, ll b)
{
a=pos[a]; b=pos[b];
ll l=min(a,b); ll r=max(a,b);
pl ans=S.query(l,r);
return ans.ss;
}
ll d1(ll a, ll b)
{
return level[a]+level[b]-2*level[LCA(a,b)];
}
ll d2(ll a, ll b)
{
return sumto[a]+sumto[b]-2*sumto[LCA(a,b)];
}
ll f(ll x, ll k)
{
return P.f(x,k);
}
vector<Tree> CC()
{
vector<Tree> ans;
Graph G(adj);
vector<Graph> CC_step=G.CCG();
REP(i,0,CC_step.size()) {Tree T(CC_step[i].adj,0); ans.pb(T);}
return ans;
}
void Build_Prufer() //O(N)
{
ll ptr=0LL; vector<bool> v; REP(i,0,N) {v.pb(true);}
vector<ll> nadj; REP(i,0,N) {nadj.pb(adj[i].size());}
ll leaf;
while(prufer.size()<N-2LL)
{
while(nadj[ptr]!=1LL && ptr<N) {ptr++;}
leaf=ptr;
while(leaf<=ptr && prufer.size()<N-2LL)
{
v[leaf]=false;
REP(i,0,adj[leaf].size()) {if(v[adj[leaf][i]]) {leaf=adj[leaf][i]; break;}}
prufer.pb(leaf);
nadj[leaf]--; if(nadj[leaf]>1) {break;}
}
ptr++;
}
return;
}
Tree Subtree(ll s)
{
included.clear();
DFS(s,p[s]);
unordered_map<ll,ll> m;
unordered_set<ll>::iterator it;
it=included.begin();
ll cnt=0LL;
while(it!=included.end())
{
m[*it]=cnt; cnt++; it++;
}
it=included.begin();
vector<ll> xx; vector<vector<ll> > ad;
REP(i,0,included.size()) {ad.pb(xx);}
REP(i,0,sons[s].size())
{
ad[0].pb(m[sons[s][i]]);
}
it++; cnt=1LL;
while(it!=included.end())
{
REP(i,0,adj[*it].size())
{
ad[cnt].pb(m[adj[*it][i]]);
}
it++; cnt++;
}
Tree ANS(ad);
return ANS;
}
Tree Uptree(ll s)
{
if(s==root) {vector<vector<ll> > adj; Tree T(adj); return T;}
included.clear();
DFS(p[s],s);
unordered_map<ll,ll> m;
unordered_set<ll>::iterator it;
it=included.begin();
ll cnt=0LL;
while(it!=included.end())
{
m[*it]=cnt; cnt++; it++;
}
it=included.begin();
vector<ll> xx; vector<vector<ll> > ad;
REP(i,0,included.size()) {ad.pb(xx);}
cnt=0LL;
while(it!=included.end())
{
REP(i,0,adj[*it].size())
{
if(adj[*it][i]==s) {continue;}
ad[cnt].pb(m[adj[*it][i]]);
}
it++; cnt++;
}
Tree ANS(ad);
return ANS;
}
vector<Tree> Split(ll s) //forest created by removing node s
{
vector<Tree> ANS;
REP(i,0,sons[s].size())
{
ANS.pb(Subtree(sons[s][i]));
}
if(s!=root) {ANS.pb(Uptree(s));}
return ANS;
}
ll centroid()
{
REP(i,0,N)
{
ll max_tree = 0LL;
REP(j,0,sons[i].size()) {max_tree=max(max_tree,sub[sons[i][j]]);}
max_tree=max(max_tree,N-sub[i]);
if(max_tree<=N/2) {return i;}
}
return 0LL;
}
class HeavyPath
{
public:
ll N;
ll low, high;
Tree *T;
ST S;
HeavyPath() {N=0LL;}
HeavyPath(ll x, ll y, Tree *K)
{
T=K;
low=x; high=y;
if(T->level[x]<T->level[y]) {swap(high,low);}
N = T->level[x]-T->level[y]+1LL;
vector<ll> st_val; ll c = low;
while(1>0) {st_val.pb(T->val[c]); if(c==high) {break;} c=T->p[c];}
ST R(st_val); S=R;
}
ll pos(ll x)
{
return (T->level[low]-T->level[x]);
}
ST::SV query(ll ind1, ll ind2)
{
return S.query(ind1,ind2);
}
void update(ST::LV X, ll ind1, ll ind2)
{
S.update(X,ind1,ind2);
}
};
vector<HeavyPath *> h_path; //heavy paths
unordered_map<ll,HeavyPath *> HP; //m[s] = heavy path including s
void HLD()
{
vector<ll> large; ll c;
REP(i,0,N)
{
ll node=-1; ll ls = -1LL;
REP(j,0,sons[i].size())
{
c=sons[i][j];
if(sub[c]>=ls) {ls=sub[c]; node=c;}
}
large.pb(node);
}
REP(i,0,N)
{
if(sons[i].size()>0) {continue;}
c=i;
while(c!=root && c==large[p[c]]) {c=p[c];}
HeavyPath *P = new HeavyPath(i,c,this);
c=i; while(1>0) {HP[c]=P; if(c==P->high) {break;} c=p[c];}
h_path.pb(P);
}
}
ST::SV query_ancestor(ll s, ll anc)
{
ST::SV ans;
if(level[s]<level[anc]) {return ans;}
ll c = s;
while(1>0)
{
ST::SV thispath;
if(level[HP[c]->high]>=level[anc])
{
thispath = HP[c]->query(HP[c]->pos(c),HP[c]->N-1);
}
else
{
thispath = HP[c]->query(HP[c]->pos(c),HP[c]->pos(anc));
}
ans=ans&thispath;
c=HP[c]->high; c=p[c];
if(c==root || level[c]<level[anc]) {break;}
}
return ans;
}
ST::SV query(ll a, ll b) //query along path a->b
{
ll lca = LCA(a,b);
ST::SV V1 = query_ancestor(a,lca);
ST::SV V2; if(b!=lca) {V2= query_ancestor(b,f(b,level[b]-level[lca]-1LL));}
return V1&V2;
}
void update_ancestor(ST::LV X, ll s, ll anc)
{
if(level[s]<level[anc]) {return;}
ll c = s;
while(1>0)
{
if(level[HP[c]->high]>=level[anc])
{
HP[c]->update(X,HP[c]->pos(c),HP[c]->N-1);
}
else
{
HP[c]->update(X,HP[c]->pos(c),HP[c]->pos(anc));
}
c=HP[c]->high; if(c==root) {break;} c=p[c];
if(level[c]<level[anc]) {break;}
}
}
void update(ST::LV X, ll a, ll b)
{
ll lca = LCA(a,b);
update_ancestor(X,a,lca);
if(b!=lca) {update_ancestor(X,b,f(b,level[b]-level[lca]-1LL));}
}
void High_Sub(ll s)
{
REP(i,0,sons[s].size()) {High_Sub(sons[s][i]);}
REP(i,0,sons[s].size()) {ll c=sons[s][i]; high_sub[s]=min(high_sub[s],high_sub[c]);}
}
void Init_Back_Edge(vector<vector<ll> > be)
{
back_edge=be;
REP(i,0,N) {high_be.pb(level[i]); high_sub.pb(level[i]);}
REP(i,0,N)
{
REP(j,0,back_edge[i].size())
{
ll c = back_edge[i][j];
high_be[i]=min(high_be[i],level[c]);
}
}
REP(i,0,N) {high_sub[i]=high_be[i];}
High_Sub(root);
}
void FindBridge()
{
REP(i,0,N)
{
if(i==root) {continue;}
if(high_sub[i]==level[i]) {bridge.pb(mp(i,p[i]));}
}
}
void FindArticulationPoint()
{
REP(i,0,N)
{
bool include=false;
if(i==root)
{
if(sons[i].size()>1LL) {articulation_point.pb(i);}
continue;
}
REP(j,0,sons[i].size())
{
ll c = sons[i][j];
if(high_sub[c]==level[c]) {include=true;}
}
if(include) {articulation_point.pb(i);}
}
}
void Calc_farthest_down(ll s)
{
REP(i,0,sons[s].size()) {Calc_farthest_down(sons[s][i]);}
REP(i,0,adj[s].size())
{
if(adj[s][i]==p[s]) {continue;}
farthest_dir[s][i]=farthest_down[adj[s][i]]+val[adj[s][i]];
farthest_down[s]=max(farthest_down[s],farthest_dir[s][i]);
}
}
void Calc_farthest_up(ll s)
{
if(s==root) {farthest_up[s]=0LL;}
pl best_dis=mp(0,0);
REP(i,0,adj[s].size())
{
if(farthest_dir[s][i]>best_dis.ff) {best_dis.ss=best_dis.ff; best_dis.ff=farthest_dir[s][i];}
else if(farthest_dir[s][i]>best_dis.ss) {best_dis.ss=farthest_dir[s][i];}
}
REP(i,0,adj[s].size())
{
if(adj[s][i]==p[s]) {continue;}
ll c = adj[s][i];
if(best_dis.ff == farthest_dir[s][i]) {farthest_up[c] = best_dis.ss+val[c];}
else {farthest_up[c]=best_dis.ff+val[c];}
REP(j,0,adj[c].size()) {if(adj[c][j]==s) {farthest_dir[c][j]=farthest_up[c];}}
}
REP(i,0,sons[s].size()) {Calc_farthest_up(sons[s][i]);}
}
void Calc_farthest()
{
Calc_farthest_down(root);
Calc_farthest_up(root);
REP(i,0,N) {farthest[i]=max(farthest_up[i],farthest_down[i]);}
}
};
Tree DFS_Tree(Graph G, ll s)
{
vector<ll> xx; REP(i,0,G.N) {G.dfs_tree.pb(xx);}
G.DFS_Tree(s);
Tree T(G.dfs_tree,s);
vector<vector<ll> > be; REP(i,0,T.N) {be.pb(xx);}
ll a,b,c;
REP(i,0,G.N)
{
REP(j,0,G.adj[i].size())
{
c = G.adj[i][j];
a=i; b=c;
if(a>b) {continue;}
if(T.level[a]>T.level[b]) {swap(a,b);}
if(T.p[b]!=a) {be[b].pb(a);}
}
}
T.Init_Back_Edge(be);
return T;
}
Tree Prufer(vector<ll> p) //constructs a Tree given unique Prufer code in O(N)
{
ll N=p.size()+2LL;
vector<vector<ll> > adj; vector<ll> xx; REP(i,0,N) {adj.pb(xx);}
ll ptr=0LL; vector<bool> v; REP(i,0,N) {v.pb(true);}
vector<ll> nadj; REP(i,0,N) {nadj.pb(1);}
REP(i,0,N-2) {nadj[p[i]]++;}
ll leaf; ll added=0LL;
while(added<N-2LL)
{
while(nadj[ptr]!=1LL && ptr<N) {ptr++;}
leaf=ptr;
while(leaf<=ptr && added<N-2LL)
{
v[leaf]=false; nadj[leaf]--; ll par=p[added]; nadj[par]--;
adj[leaf].pb(par); adj[par].pb(leaf);
added++;
if(nadj[par]>1) {break;}
leaf=par;
}
ptr++;
}
vector<ll> missing;
REP(i,0,N) {if(nadj[i]!=0LL) {missing.pb(i);}}
adj[missing[0]].pb(missing[1]); adj[missing[1]].pb(missing[0]);
Tree T(adj,0LL);
return T;
}
class WTree
{
public:
ll N;
vector<ll> p;
vector<vector<pl> > sons;
vector<vector<pl> > adj;
ll root;
vector<ll> level; //starting in 0
WTree(vector<vector<pl> > ad, ll r)
{
N=ad.size(); root=r; adj=ad;
vector<pl> xx; REP(i,0,N) {sons.pb(xx); p.pb(-1); level.pb(0);}
DFS_Build(r,r);
}
void DFS_Build(ll s, ll par)
{
if(s!=root) {level[s]=level[par]+1LL;}
p[s]=par;
REP(i,0,adj[s].size())
{
if(adj[s][i].ff==par) {continue;}
sons[s].pb(adj[s][i]);
DFS_Build(adj[s][i].ff,s);
}
return;
}
Tree Conv()
{
vector<vector<ll> > ad; vector<ll> xx; REP(i,0,N) {ad.pb(xx);}
vector<ll> values; REP(i,0,N) {values.pb(0LL);}
REP(i,0,N) {REP(j,0,adj[i].size()) {if(adj[i][j].ff==p[i]) {values[i]=adj[i][j].ss;} ad[i].pb(adj[i][j].ff);}}
Tree T(ad,root); T.val=values; T.DFS(T.root);
return T;
}
};
class WG //everything works for weighted directed graphs except dynamic graph
{
public:
ll N; vector<vector<pl> > adj;
vector<unordered_set<ll> > adjs; //for dynamic graph
unordered_map<pl,ll,hash_pair> we; //for dynamic graph
vector<bool> pr; vector<ll> nv;
vector<bool> deleted;
Matrix Madj;
WG(vector<vector<pl> > ad)
{
adj=ad; N=adj.size();
REP(i,0,N) {pr.pb(false); nv.pb(0);}
REP(i,0,N) {deleted.pb(false);}
unordered_set<ll> em; REP(i,0,N) {adjs.pb(em); }
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
adjs[i].insert(adj[i][j].ff); we[mp(i,adj[i][j].ff)]=adj[i][j].ss;
}
}
}
void Reset()
{
REP(i,0,N) {pr[i]=false;nv.pb(0);}
unordered_set<ll>::iterator it;
REP(i,0,N) {adj[i].clear(); it=adjs[i].begin(); while(it!=adjs[i].end()) {adj[i].pb(mp(*it,we[mp(i,*it)])); it++;}}
}
vector<ll> Djikstra(ll s)
{
Reset();
vector<ll> d; REP(i,0,N) {d.pb(INF);}
d[s]=0;
priority_queue<pl> q;
q.push(mp(0,s));
ll cur;
while(!q.empty())
{
cur=q.top().ss; q.pop();
if(pr[cur]) {continue;}
pr[cur]=true;
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff]>d[cur]+adj[cur][i].ss)
{
d[adj[cur][i].ff]=d[cur]+adj[cur][i].ss;
q.push(mp(-d[adj[cur][i].ff],adj[cur][i].ff));
}
}
}
return d;
}
vector<pl> Djikstra_MS(vector<ll> sn) //Djikstra Multi-sourced, ans[i].ff=d(i,sn), ans[i].ss=member of sn closest to i
{
Reset();
ll K=sn.size();
vector<pl> d; REP(i,0,N) {d.pb(mp(INF,-1LL));}
REP(i,0,K) {d[sn[i]]=mp(0LL,sn[i]);}
priority_queue<pl> q;
REP(i,0,K) {q.push(mp(0,sn[i]));}
ll cur;
while(!q.empty())
{
cur=q.top().ss; q.pop();
if(pr[cur]) {continue;}
pr[cur]=true;
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff].ff>d[cur].ff+adj[cur][i].ss)
{
d[adj[cur][i].ff].ff=d[cur].ff+adj[cur][i].ss;
d[adj[cur][i].ff].ss=d[cur].ss;
q.push(mp(-d[adj[cur][i].ff].ff,adj[cur][i].ff));
}
}
}
return d;
}
vector<ll> SPFA(ll s)
{
Reset();
vector<ll> d; REP(i,0,N) {d.pb(INF);}
d[s]=0;
deque<ll> tv; tv.pb(s); pr[s]=true;
ll cur; ll mv=0;
while(!tv.empty())
{
cur=tv.front(); tv.pop_front(); pr[cur]=false;
nv[cur]++; mv=max(mv,nv[cur]);
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff]>d[cur]+adj[cur][i].ss)
{
d[adj[cur][i].ff]=d[cur]+adj[cur][i].ss;
if(!pr[adj[cur][i].ff]) {tv.pb(adj[cur][i].ff);}
pr[adj[cur][i].ff]=true;
}
}
if(mv>=N) {d.clear(); break;} //negative cycle
}
return d;
}
vector<pl> SPFA_MS(vector<ll> sn)
{
ll K=sn.size();
Reset();
vector<pl> d; REP(i,0,N) {d.pb(mp(INF,-1LL));}
REP(i,0,K) {d[sn[i]]=mp(0LL,sn[i]);}
deque<ll> tv; REP(i,0,K) {tv.pb(sn[i]); pr[sn[i]]=true;}
ll cur; ll mv=0;
while(!tv.empty())
{
cur=tv.front(); tv.pop_front(); pr[cur]=false;
nv[cur]++; mv=max(mv,nv[cur]);
REP(i,0,adj[cur].size())
{
if(d[adj[cur][i].ff].ff>d[cur].ff+adj[cur][i].ss)
{
d[adj[cur][i].ff].ff=d[cur].ff+adj[cur][i].ss;
d[adj[cur][i].ff].ss=d[cur].ss;
if(!pr[adj[cur][i].ff]) {tv.pb(adj[cur][i].ff);}
pr[adj[cur][i].ff]=true;
}
}
if(mv>=N) {d.clear(); break;} //negative cycle
}
return d;
}
vector<vector<ll> > Floyd() //assumes there is no neg cycle
{
Reset();
vector<vector<ll> > d; vector<ll> xx; REP(i,0,N) {xx.pb(INF);} REP(i,0,N) {d.pb(xx);}
REP(i,0,N)
{
d[i][i]=0;
REP(j,0,adj[i].size())
{
d[i][adj[i][j].ff]=adj[i][j].ss;
}
}
REP(i,0,N)
{
REP(q1,0,N)
{
REP(q2,0,N)
{
if(q1==q2) {continue;}
d[q1][q2]=min(d[q1][q2],d[q1][i]+d[i][q2]);
}
}
}
return d;
}
WTree Kruskal() //Minimum Spanning Tree, O(MlogM)
{
vector<pair<ll,pl> > ed; vector<vector<pl> > ad; vector<pl> xx; REP(i,0,N) {ad.pb(xx);}
pair<ll,pl> cur;
REP(i,0,N)
{
cur.ss.ff=i;
REP(j,0,adj[i].size())
{
cur.ss.ss=adj[i][j].ff;
cur.ff=adj[i][j].ss;
ed.pb(cur);
}
}
sort(ed.begin(),ed.end()); DSU D(N); ll a,b,we;
REP(i,0,ed.size())
{
a=ed[i].ss.ff; b=ed[i].ss.ss; we=ed[i].ff;
if(D.find(a)!=D.find(b))
{
D.unionn(a,b); ad[a].pb(mp(b,we)); ad[b].pb(mp(a,we));
}
}
WTree T(ad,0);
return T;
}
WTree Prim() //Minimim Spanning Tree, O(MlogM)
{
vector<vector<pl> > ad; vector<pl> xx; REP(i,0,N) {ad.pb(xx);}
vector<bool> inT; REP(i,0,N) {inT.pb(false);}
priority_queue<pair<pl,pl> > q;
q.push(mp(mp(0,0),mp(0,0))); ll s;
while(!q.empty())
{
s=q.top().ff.ss; pl bef=q.top().ss; q.pop();
if(inT[s]) {continue;}
inT[s]=true;
if(s!=0) {ad[s].pb(bef); ad[bef.ff].pb(mp(s,bef.ss));}
REP(i,0,adj[s].size())
{
if(inT[adj[s][i].ff]) {continue;}
q.push(mp(mp(-adj[s][i].ss,adj[s][i].ff),mp(s,adj[s][i].ss)));
}
}
WTree T(ad,0);
return T;
}
void erase_edge(pl edge)
{
adjs[edge.ff].erase(edge.ss); adjs[edge.ss].erase(edge.ff);
}
void add_edge(pair<pl,ll> edge)
{
if(adjs[edge.ff.ff].find(edge.ff.ss)==adjs[edge.ff.ff].end())
{
we[edge.ff]=edge.ss; swap(edge.ff.ff,edge.ff.ss);
we[edge.ff]=edge.ss; swap(edge.ff.ff,edge.ff.ss);
adjs[edge.ff.ff].insert(edge.ff.ss);
adjs[edge.ff.ss].insert(edge.ff.ff);
}
else
{
we[edge.ff]+=edge.ss; swap(edge.ff.ff,edge.ff.ss);
we[edge.ff]+=edge.ss;
}
}
void erase_node(ll s)
{
deleted[s]=true;
unordered_set<ll>::iterator it; it=adjs[s].begin(); vector<pl> e;
while(it!=adjs[s].end())
{
e.pb(mp(s,*it));
it++;
}
REP(i,0,e.size()) {erase_edge(e[i]);}
}
void add_node(vector<pl> con) // adds node with adjacency list con, and index N
{
N++; pr.pb(false); nv.pb(0); deleted.pb(false); unordered_set<ll> em; vector<pl> emm; adjs.pb(em); adj.pb(emm);
REP(i,0,con.size()) {add_edge(mp(mp(N-1,con[i].ff),con[i].ss));}
}
Matrix SMul(Matrix A, Matrix B)
{
if(A.M!=B.N) {Matrix ANS; return ANS;}
vector<double> xx; vector<vector<double> > ans; REP(i,0,B.M) {xx.pb((double) (INF));} REP(i,0,A.N) {ans.pb(xx);}
REP(i,0,A.N)
{
REP(j,0,B.M)
{
double val=(double) INF;
REP(k,0,A.M) {val=min(val,A.a[i][k]+B.a[k][j]);}
ans[i][j]=val;
}
}
Matrix ANS(ans); return ANS;
}
Matrix fastexpS(Matrix A, ll e) //O(N^3loge)
{
if(A.N!=A.M) {Matrix ANS; return ANS;}
if(e<0) {A.RRE();if(A.rank==0) {e=0LL;} else {return fastexpS(*(A.Inv),-e);}}
if(e==0)
{Matrix ANS=A; REP(i,0,A.N) {REP(j,0,A.N) {if(i!=j) {ANS.a[i][j]=(double) INF;} else {ANS.a[i][j]=0.0;}}} return ANS;}
if(e%2LL==0)
{
Matrix V =fastexpS(A,(ll) e/2LL); return SMul(V,V);
}
else
{
Matrix V=fastexpS(A,(ll) e/2LL); return SMul(SMul(V,V),A);
}
}
void Build_Madj()
{
if(Madj.N!=0LL) {return;}
vector<vector<double> > madj; vector<double> xx; REP(i,0,N) {xx.pb((double) (INF));} REP(i,0,N) {madj.pb(xx);}
REP(i,0,N) {REP(j,0,adj[i].size()) {madj[i][adj[i][j].ff]=(double) (adj[i][j].ss);}}
Matrix B(madj); Madj=B;
}
double SP(ll a, ll b, ll length) //shortest path between a,b with fixed length, O(N^3loglength)
{
Build_Madj();
return (fastexpS(Madj,length).a[a][b]);
}
};
class DiGraph
{
public:
ll N;
vector<vector<ll> > adj;
vector<bool> visited;
vector<ll> current; //for CC
vector<bool> c; //for Bip
bool bip; //for Bip
vector<ll> TS;//Top Sort
vector<ll> SCC; //Attributes a number to each node
vector<vector<ll> > adjK; //reverse graph, for Kosaraju
vector<unordered_set<ll> > adjs; vector<unordered_set<ll> > adjr; //dynamic graph
vector<bool> deleted; //dynamic graph
unordered_map<pair<vector<bool>,ll>,vector<ll>,hash_pair> mH; //Hamiltonian
vector<list<ll> > ad; //for Hierholzer
Matrix Madj;
DiGraph(vector<vector<ll> > ad)
{
adj=ad; N=adj.size(); REP(i,0,N) {visited.pb(false); c.pb(-1); SCC.pb(-1LL);}
vector<ll> xx; REP(i,0,N) {adjK.pb(xx);}
REP(i,0,adj.size())
{
REP(j,0,adj[i].size()) {adjK[adj[i][j]].pb(i);}
}
unordered_set<ll> em; REP(i,0,N) {adjs.pb(em); adjr.pb(em);}
REP(i,0,N)
{
REP(j,0,adj[i].size())
{
adjs[i].insert(adj[i][j]);
adjr[adj[i][j]].insert(i);
}
}
REP(i,0,N) {deleted.pb(false);}
}
void Reset()
{
REP(i,0,N) {visited[i]=false;}
current.clear();
unordered_set<ll>::iterator it;
REP(i,0,N) {adj[i].clear();it=adjs[i].begin(); while(it!=adjs[i].end()) {adj[i].pb(*it); it++;}}
}
void DFS(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i]]) {c[adj[s][i]]=(c[s]+1)%2; DFS(adj[s][i]);}
else if(c[adj[s][i]]==c[s]) {bip=false;}
}
current.pb(s); //only needed for Kosaraju
return;
}
vector<ll> BFS(ll s)
{
vector<ll> distance; REP(i,0,N) {distance.pb(INF);}
REP(i,0,N) {visited[i]=false;}
distance[s]=0; visited[s]=true;
deque<ll> d; d.pb(s); ll cur;
while(!d.empty())
{
cur=d.front(); d.pop_front();
REP(i,0,adj[cur].size())
{
if(!visited[adj[cur][i]])
{
visited[adj[cur][i]]=true;
d.pb(adj[cur][i]);
distance[adj[cur][i]]=distance[cur]+1;
}
}
}
return distance;
}
bool Bip()
{
c[0]=0;
bip=true;
DFS(0);
if(bip) {return true;}
else {return false;}
}
void DFSTS(ll s)
{
REP(i,0,adj[s].size())
{
if(!visited[adj[s][i]]) {DFSTS(adj[s][i]);}
}
visited[s]=true; TS.pb(s);
}
void TopSort()
{
Reset();
REP(i,0,N)
{
if(visited[i]) {continue;}
DFSTS(i);
}
reverse(TS.begin(),TS.end());
}
void DFSK(ll s)
{
if(visited[s]) {return;}
visited[s]=true;
REP(i,0,adjK[s].size())
{
if(!visited[adjK[s][i]]) {DFSK(adjK[s][i]);}
}
current.pb(s); //only needed for Kosaraju
return;
}
void Kosaraju()
{
if(SCC[0]!=-1) {return;}
Reset();
REP(i,0,N)
{
if(visited[i]) {continue;}
DFS(i);
}
vector<ll> List=current;
Reset();
ll c=0LL;
for(ll i=N-1LL;i>=0LL;i--)
{
ll node=List[i];
if(visited[node]) {continue;}
DFSK(node);
REP(j,0,current.size()) {SCC[current[j]]=c;}
c++;
current.clear();
}
}
DiGraph SCCGraph()
{
Kosaraju();
set<pl> ed;
REP(i,0,adj.size())
{
REP(j,0,adj[i].size())
{
ed.insert(mp(SCC[i],SCC[adj[i][j]]));
}
}
vector<vector<ll> > a; vector<ll> xx;
ll nscc=-INF; REP(i,0,N) {nscc=max(nscc,SCC[i]+1LL);}
REP(i,0,nscc) {a.pb(xx);}
set<pl>::iterator it=ed.begin();
pl cur;
while(it!=ed.end())
{
cur=*it;
if(cur.ff!=cur.ss) {a[cur.ff].pb(cur.ss);}
it++;
}
DiGraph ans(a);
return ans;
}
void erase_edge(pl edge)
{
adjs[edge.ff].erase(edge.ss);
adjr[edge.ss].erase(edge.ff);
}
void add_edge(pl edge)
{
adjs[edge.ff].insert(edge.ss);
adjr[edge.ss].insert(edge.ff);
adj[edge.ff].pb(edge.ss);
}
void erase_node(ll s)
{
deleted[s]=true;
unordered_set<ll>::iterator it; vector<pl> e;
if(adjs[s].size()>0) {it=adjs[s].begin(); while(it!=adjs[s].end()) {e.pb(mp(s,*it)); it++;}}
if(adjr[s].size()>0) {it=adjr[s].begin(); while(it!=adjr[s].end()) {e.pb(mp(*it,s)); it++;}}
REP(i,0,e.size()) {erase_edge(e[i]);}
}
void add_node(vector<ll> in, vector<ll> out) // adds node with adjacency list con, and index N
{
unordered_set<ll> em; adjs.pb(em); adjr.pb(em); vector<ll> emm; adj.pb(emm); deleted.pb(false); N++;
SCC.pb(-1);
REP(i,0,out.size()) {add_edge(mp(N-1,out[i]));}
REP(i,0,in.size()) {add_edge(mp(in[i],N-1));}
}
vector<ll> Hamiltonian()
{
vector<bool> v; REP(i,0,N) {v.pb(true);}
REP(i,0,N) {v[i]=true;}
REP(i,0,N)
{
if(!f(v,i).empty()) {return f(v,i);}
}
vector<ll> ans; return ans;
}
vector<ll> f(vector<bool> v, ll x) //O(N^2*2^N), for when we dont know anything about the graph
{
if(!mH[mp(v,x)].empty()) {return mH[mp(v,x)];}
ll oc=0LL; REP(i,0,N) {if(v[i]) {oc++;}}
vector<ll> ans;
if(oc==1) {ans.pb(x);}
else
{
v[x]=false; ll node;
REP(i,0,adjK[x].size())
{
node=adjK[x][i];
if(!v[node]) {continue;}
vector<ll> p=f(v,node);
if(!p.empty()) {p.pb(x); ans=p; break;}
}
}
mH[mp(v,x)]=ans;
return ans;
}
void Tour(ll s)
{
current.pb(s);
if(ad[s].size()==0) {return;}
ll nxt=*ad[s].begin(); ad[s].erase(ad[s].begin());
Tour(nxt);
}
vector<ll> Hierholzer() //O(M)
{
vector<ll> indeg; vector<ll> outdeg; REP(i,0,N) {indeg.pb(0LL); outdeg.pb(0LL);}
REP(i,0,N) {REP(j,0,adj[i].size()) {outdeg[i]++; indeg[adj[i][j]]++;}}
ll onep=0LL; ll onem=0LL; ll un=0LL;
REP(i,0,N)
{
if(outdeg[i]-indeg[i]==-1) {onem++;}
else if(outdeg[i]-indeg[i]==1) {onep++;}
else if(abs(outdeg[i]-indeg[i])>1) {un++;}
}
if(un!=0LL || onem>1LL || onep>1LL) {vector<ll> xxx; return xxx;}
ll sn=0LL; REP(i,0,N) {if(outdeg[i]-indeg[i]==1LL) {sn=i;}}
Reset(); DFS(sn); REP(i,0,N) {if(!visited[i]) {vector<ll> xxx; return xxx;}}
list<ll> ans;
list<ll> xx;
REP(i,0,N) {xx.clear(); xx.insert(xx.begin(),adj[i].begin(),adj[i].end()); ad.pb(xx);}
ans.insert(ans.begin(),sn);
list<ll>::iterator it=ans.begin();
REP(i,0,INF)
{
if(it==ans.end()) {break;}
current.clear();
Tour(*it);
it=ans.erase(it);
it=ans.insert(it,current.begin(),current.end());
it++;
}
it=ans.begin();
vector<ll> f_ans; REP(i,0,ans.size()) {f_ans.pb(*it); it++;}
return f_ans;
}
ll Edge_Disjoint(ll source, ll terminator) //max number of edge disjoint pahts source --> terminator
{
vector<vector<pl> > Wadj; vector<pl> xx; REP(i,0,N) {Wadj.pb(xx);}
REP(i,0,N)
{
REP(j,0,adj[i].size()) {Wadj[i].pb(mp(adj[i][j],1LL));}
}
WDiGraph G(Wadj);
return G.MF_Dinic(source,terminator);
}
ll Node_Disjoint(ll source, ll terminator) //max number of node disjoint paths source --> terminator
{
vector<vector<pl> > Wadj; vector<pl> xx; REP(i,0,2*N) {Wadj.pb(xx);}
REP(i,0,N)
{
Wadj[2*i].pb(mp(2*i+1,1));
REP(j,0,adj[i].size()) {Wadj[2*i+1].pb(mp(2*adj[i][j],1LL));}
}
WDiGraph G(Wadj);
return G.MF_Dinic(source,terminator);
}
ll Node_Disjoint_Path_Cover() //min number of node disjoint paths to cover all nodes in DAG, O(MN^1/2)
{
vector<vector<ll> > Uadj; vector<ll> xx; REP(i,0,2*N) {Uadj.pb(xx);}
REP(i,0,N)
{
REP(j,0,adj[i].size()) {Uadj[i].pb(adj[i][j]+N); Uadj[adj[i][j]+N].pb(i);}
}
Graph G(Uadj);
return (N-G.MaxMatching());
}
ll General_Path_Cover() //min number of paths to cover all nodes in DAG (situation in Dilworths Theorem), O(N^5/2 + NM)
{
vector<vector<ll> > Uadj; vector<ll> xx; REP(i,0,2*N) {Uadj.pb(xx);}
REP(i,0,N)
{
Reset(); DFS(i);
REP(j,0,N) {if(j==i || !visited[j]) {continue;} Uadj[i].pb(j+N); Uadj[j+N].pb(i);}
}
Graph G(Uadj);
return (N-G.MaxMatching());
}
void Build_Madj()
{
if(Madj.N!=0LL) {return;}
vector<vector<double> > madj; vector<double> xx; REP(i,0,N) {xx.pb(0.0);} REP(i,0,N) {madj.pb(xx);}
REP(i,0,N) {REP(j,0,adj[i].size()) {madj[i][adj[i][j]]=1.0;}}
Matrix B(madj); Madj=B;
}
ll cnt_path(ll a, ll b, ll length)
{
Build_Madj();
return fastexp(Madj,length).a[a][b];
}
};
template<class T=ll>
class Heap
{
public:
ll N;
vector<T> a;
Heap() {N=0LL;}
Heap(vector<T> b) //O(N)
{
a=b; N=a.size(); ll cur;
REP(i,0,N)
{
cur=i;
while(cur>0LL && a[cur]>a[(cur-1)/2]) {swap(a[cur],a[(cur-1)/2]); cur=(cur-1)/2;}
}
}
void FixDown(ll node, T val) //a[node] -> val
{
a[node]=val; ll cur=node;
bool up=false;
if(node!=0 && a[node]>a[(node-1)/2]) {up=true;}
if(up)
{
while(cur>0 && a[cur]>a[(cur-1)/2]) {swap(a[cur],a[(cur-1)/2]); cur=(cur-1)/2;}
}
else
{
while(1>0)
{
if(2*cur+1<N && a[2*cur+1]>a[cur]) {swap(a[2*cur+1],a[cur]); cur=2*cur+1; continue;}
if(2*cur+2<N && a[2*cur+2]>a[cur]) {swap(a[2*cur+2],a[cur]); cur=2*cur+2; continue;}
break;
}
}
}
void addElement(T val)
{
a.pb(val); N++; FixDown(N-1,val);
}
};
ostream & operator << (ostream &out, Heap<ll> &H) {Out(H.a); return out;}
istream & operator >> (istream &in, Heap<ll> &H) {ll N; cin>>N; vector<ll> a; In(a,N); H.N=N; H.a=a; return in;}
template<class T=ll>
class AVL
{
public:
ll N;
class node
{
public:
T val;
ll h;
node *par;
node *lson, *rson;
node *prv,*nxt;
bool operator < (node A) {if(val<A.val) {return true;} return false;}
bool operator > (node A) {if(val>A.val) {return true;} return false;}
bool operator <= (node A) {if(val<=A.val) {return true;} return false;}
bool operator >= (node A) {if(val>=A.val) {return true;} return false;}
};
node * root, *beg, *en;
AVL()
{
en=(node *) malloc(sizeof(node));
en->lson=NULL; en->rson=NULL; en->par=NULL; en->h=0LL;
en->val=INF;
en->prv=NULL; en->nxt=NULL;
root=en; beg=en;
N=0LL;
}
node * begin() {return beg;}
node * end() {return en;}
node * find(T val)
{
node * cur = root;
while(1>0)
{
if(cur->val==val) {return cur;}
else if(cur->val > val && cur->lson != NULL) {cur=cur->lson;}
else if(cur->val < val && cur->rson != NULL) {cur=cur->rson;}
else {return en;}
}
}
node * lower_bound(T val)
{
node * cur = root; node * ans=root; ll mind=INF;
while(1>0)
{
if(cur->val==val) {return cur;}
if(cur->val >val && cur->val - val <mind) {mind=cur->val - val; ans=cur;}
if(cur->val > val && cur->lson != NULL) {cur=cur->lson;}
else if(cur->val < val && cur->rson != NULL) {cur=cur->rson;}
else {return ans;}
}
}
node * upper_bound(T val)
{
node * cur = root; node * ans=root; ll mind=INF;
while(1>0)
{
if(cur->val >val && cur->val - val <mind) {mind=cur->val - val; ans=cur;}
if(cur->val > val && cur->lson != NULL) {cur=cur->lson;}
else if(cur->val <= val && cur->rson != NULL) {cur=cur->rson;}
else {return ans;}
}
}
void Balance(node *X)
{
node * cur=X; bool balanced=true;
while(1>0)
{
ll h1=0, h2=0;
if(cur->lson!=NULL) {h1=cur->lson->h +1;}
if(cur->rson!=NULL) {h2=cur->rson->h +1;}
if(abs(h1-h2)>1) {balanced=false; break;}
if(cur==root) {break;}
cur=cur->par;
}
if(balanced) {return;}
ll h1=0; ll h2=0;
if(cur->lson!=NULL) {h1=cur->lson->h +1;}
if(cur->rson!=NULL) {h2=cur->rson->h +1;}
if(h2 > h1)
{
ll hl=0, hr=0;
if(cur->rson->lson!=NULL) {hl=cur->rson->lson->h +1;}
if(cur->rson->rson!=NULL) {hr=cur->rson->rson->h +1;}
if(hr>hl)
{
(cur->h)-=2;
node * A = cur->rson; if(cur->par==NULL) {root=A;}
A->par=cur->par; cur->par=A;
cur->rson=A->lson; if(A->lson!=NULL) {A->lson->par=cur;}
A->lson=cur;
if(A->par != NULL)
{
if(A->par->rson==cur) {A->par->rson=A;}
if(A->par->lson==cur) {A->par->lson=A;}
}
cur=A;
while(cur!=root)
{
cur=cur->par; (cur->h)--;
}
}
else
{
node * A = cur; node * B = A->rson; node * C = B->lson; node * D = C->lson; node * E = C->rson;
if(root==A) {root=C;}
C->par=A->par;
if(C->par != NULL)
{
if(C->par->rson==A) {C->par->rson=C;}
if(C->par->lson==A) {C->par->lson=C;}
}
A->par=C; C->lson=A;
A->rson=D; if(D!=NULL) {D->par=A;}
B->lson=E; if(E!=NULL) {E->par=B;}
B->par=C; C->rson=B;
B->h=0; if(B->rson!=NULL) {B->h=B->rson->h + 1;}
A->h=0; if(A->lson!=NULL) {A->h=A->lson->h + 1;}
(C->h)++;
cur=C;
while(cur!=root)
{
cur=cur->par; (cur->h)--;
}
}
}
else
{
ll hl=0, hr=0;
if(cur->lson->lson!=NULL) {hl=cur->lson->lson->h +1;}
if(cur->lson->rson!=NULL) {hr=cur->lson->rson->h +1;}
if(hl>hr)
{
(cur->h)-=2;
node * A = cur->lson; if(cur->par==NULL) {root=A;}
A->par=cur->par; cur->par=A;
cur->lson=A->rson; if(A->rson!=NULL) {A->rson->par=cur;}
A->rson=cur;
if(A->par != NULL)
{
if(A->par->rson==cur) {A->par->rson=A;}
if(A->par->lson==cur) {A->par->lson=A;}
}
cur=A;
while(cur!=root)
{
cur=cur->par; (cur->h)--;
}
}
else
{
node * A = cur; node * B = A->lson; node * C = B->rson; node * D = C->rson; node * E = C->lson;
if(root==A) {root=C;}
C->par=A->par; A->par=C; A->lson=D;
B->rson=E; B->par=C;
C->rson=A; C->lson=B;
if(D!=NULL) {D->par=A;}
if(E!=NULL) {E->par=B;}
B->h=0; if(B->lson!=NULL) {B->h=B->lson->h + 1;}
A->h=0; if(A->rson!=NULL) {A->h=A->rson->h + 1;}
(C->h)++;
if(C->par != NULL)
{
if(C->par->rson==cur) {C->par->rson=C;}
if(C->par->lson==cur) {C->par->lson=C;}
}
cur=C;
while(cur!=root)
{
cur=cur->par; (cur->h)--;
}
}
}
return;
}
void insert(T val)
{
node * next = lower_bound(val);
node * X = (node *) malloc(sizeof(node));
X->val=val; X->h=0; X->par=NULL; X->lson=NULL; X->rson=NULL;
node * cur=root;
N++;
while(cur->lson != NULL && cur->rson !=NULL)
{
(cur->h)++;
if(*cur>=*X) {cur=cur->lson;}
else {cur=cur->rson;}
}
(cur->h)++;
if(cur->lson==NULL && cur->rson==NULL)
{
if(*cur>=*X) {cur->lson=X; X->par=cur;}
else {cur->rson=X; X->par=cur;}
}
else if(cur->lson==NULL)
{
if(*cur>=*X) {cur->lson=X; X->par=cur;}
else
{
cur=cur->rson; (cur->h)++;
if(*X>=*cur) {cur->rson=X; X->par=cur;}
else {cur->lson=X; X->par=cur;}
}
}
else if(cur->rson==NULL)
{
if(*cur<=*X) {cur->rson=X; X->par=cur;}
else
{
cur=cur->lson; (cur->h)++;
if(*X>=*cur) {cur->rson=X; X->par=cur;}
else {cur->lson=X; X->par=cur;}
}
}
if(*X < *beg) {beg=X;}
Balance(X);
X->nxt=next; X->prv=(X->nxt->prv);
X->nxt->prv=X; if(X->prv !=NULL) {X->prv->nxt=X;}
}
void erase(node *X)
{
X->nxt->prv=X->prv;
if(X->prv!=NULL) {X->prv->nxt=X->nxt;}
if(X==beg) {beg=beg->nxt;}
if(X->lson==NULL && X->rson==NULL)
{
node * cur=X; node * p = cur->par;
cur->h=-1; cur=p;
while(1>0)
{
ll h1=0; ll h2=0;
if(cur->lson!=NULL) {h1=cur->lson->h +1;}
if(cur->rson!=NULL) {h2=cur->rson->h +1;}
cur->h=max(h1,h2);
if(cur==root) {break;}
cur=cur->par;
}
cur=X;
if((cur->par)->rson==cur) {(cur->par)->rson=NULL;}
if((cur->par)->lson==cur) {(cur->par)->lson=NULL;}
free(cur);
N--;
Balance(p);
return;
}
if(X->rson==NULL)
{
node * cur=X; node * p = cur->lson;
cur->h=-1; cur=p;
while(1>0)
{
ll h1=0; ll h2=0;
if(cur->lson!=NULL) {h1=cur->lson->h +1;}
if(cur->rson!=NULL) {h2=cur->rson->h +1;}
cur->h=max(h1,h2);
if(cur==root) {break;}
cur=cur->par;
}
cur=X;
if(X==root) {p->par=NULL; root=p; return;}
if((cur->par)->rson==cur) {(cur->par)->rson=p;}
if((cur->par)->lson==cur) {(cur->par)->lson=p;}
p->par=cur->par;
free(cur);
N--;
Balance(p);
return;
}
if(X->lson==NULL)
{
node * cur=X; node * p = cur->rson;
cur->h=-1; cur=p;
while(1>0)
{
ll h1=0; ll h2=0;
if(cur->lson!=NULL) {h1=cur->lson->h +1;}
if(cur->rson!=NULL) {h2=cur->rson->h +1;}
cur->h=max(h1,h2);
if(cur==root) {break;}
cur=cur->par;
}
cur=X;
if(X==root) {p->par=NULL; root=p; return;}
if((cur->par)->rson==cur) {(cur->par)->rson=p;}
if((cur->par)->lson==cur) {(cur->par)->lson=p;}
p->par=cur->par;
free(cur);
N--;
Balance(p);
return;
}
node * p = X->lson;
while(p->rson!=NULL) {p=p->rson;}
swap(X->val,p->val);
erase(p);
}
};
template<class T=ll>
class HashTable
{
public:
ll M; ll N;
class node
{
public:
T val;
bool visited;
node * nxt, *prv;
};
vector<node> a;
node * be, *en;
HashTable(ll m)
{
M=m; node X = *((node *) malloc(sizeof(node)));
REP(i,0,M) {a.pb(X);}
be=(node *) malloc(sizeof(node));
en=(node *) malloc(sizeof(node));
be->prv=NULL; be->nxt=en;
en->prv=be; en->nxt=NULL;
N=0;
}
node * begin() {return be;}
node * end() {return en;}
ll hash(ll i)
{
return (i%M);
}
void insert(T val)
{
ll ind=hash(val);
while(a[ind].visited)
{
if(a[ind].val==val) {return;}
ind=(ind+1)%M;
}
a[ind].visited=true; a[ind].val=val; N++;
a[ind].nxt=end(); a[ind].prv=en->prv; a[ind].prv->nxt=&a[ind]; en->prv=&a[ind];
if(N==1) {be=&a[ind]; return;}
}
node * find(T val)
{
ll ind=hash(val);
while(a[ind].visited)
{
if(a[ind].val==val) {return &a[ind];}
ind=(ind+1)%M;
}
return end();
}
void erase(node * X)
{
N--;
X->visited=false; X->val=0LL;
X->nxt->prv=X->prv;
if(X->prv !=NULL) {X->prv->nxt=X->nxt;}
if(be==X) {be=X->nxt;}
}
};
class Trie
{
public:
ll N;
vector<string> val; vector<char> c;
vector<ll> p;
vector<vector<ll> > sons;
unordered_set<string> a;
unordered_map<string,ll> pos;
Trie() {N=1; p.pb(0); val.pb(""); c.pb(' '); pos[""]=0; vector<ll> em; sons.pb(em);}
void insert(string s)
{
a.insert(s);
if(pos.find(s)!=pos.end()) {return;}
string t=""; ll node;
REP(i,0,s.size())
{
node=pos[t];
t+=s[i];
if(pos.find(t)==pos.end())
{
N++;vector<ll> em; sons.pb(em);
val.pb(t);c.pb(s[i]);
p.pb(node);
sons[node].pb(N-1);
pos[t]=N-1;
}
}
}
};
ll LIS(vector<ll> a) //Longest strictly Increasing Subsequence in O(NlogN)
{
vector<ll> dp; dp.pb(-INF);
vector<ll>::iterator it;
REP(i,0,a.size())
{
it=upper_bound(dp.begin(),dp.end(),a[i]);
if(it==dp.end()) {dp.pb(a[i]); continue;}
*it=a[i];
}
return dp.size()-1LL;
}
template<class T=string>
ll LCS_dp(ll i, ll j, vector<vector<ll> > &dp, T a, T b) //i means prefix s[0...i]
{
if(i==0) {if(a[0]==b[j]) {dp[i][j]=1;} else {dp[i][j]=0;}}
else if(j==0) {if(a[i]==b[0]) {dp[i][j]=1;} else {dp[i][j]=0;}}
else
{
if(a[i]==b[j]) {dp[i][j]=LCS_dp(i-1,j-1,dp,a,b)+1;}
else {dp[i][j]=max(LCS_dp(i-1,j,dp,a,b),LCS_dp(i,j-1,dp,a,b));}
}
return dp[i][j];
}
template<class T=string>
ll LCS(T a, T b)
{
vector<ll> xx; vector<vector<ll> > dp; REP(i,0,b.size()) {xx.pb(0);} REP(i,0,a.size()) {dp.pb(xx);}
return LCS_dp<T>(a.size()-1,b.size()-1, dp, a, b);
}
template<class T=string>
ll L_dist_dp(ll i, ll j, vector<vector<ll> > &dp, T a, T b) //i means prefix s[0...(i+1)]
{
if(i==0) {dp[i][j]=j;}
else if(j==0) {dp[i][j]=i;}
else
{
ll c = 1; if(a[i-1]==b[j-1]) {c=0;}
dp[i][j]=min(min(L_dist_dp(i-1,j,dp,a,b)+1,L_dist_dp(i,j-1,dp,a,b)+1),L_dist_dp(i-1,j-1,dp,a,b)+c);
}
return dp[i][j];
}
template<class T=string>
ll L_dist(T a, T b) //Levenshtein distance
{
vector<ll> xx; vector<vector<ll> > dp; REP(i,0,b.size()+1) {xx.pb(0LL);} REP(i,0,a.size()+1) {dp.pb(xx);}
return L_dist_dp(a.size(),b.size(),dp,a,b);
}
vector<ll> IC(ll k, vector<ll> a) //#strictly increasing subsequences of length k ending in each position
{
ll N=a.size();
unordered_map<ll,ll> m; set<ll> vals; REP(i,0,N) {vals.insert(a[i]);}
ll cnt=0LL; set<ll>::iterator it=vals.begin();
while(it!=vals.end()) {m[*it]=cnt; cnt++; it++;}
REP(i,0,N) {a[i]=m[a[i]];}
vector<ll> ans; REP(i,0,N) {ans.pb(0LL);}
if(k>N) {return ans;}
if(k==1) {REP(i,0,N) {ans[i]=1LL;} return ans;}
vector<ll> last=IC(k-1,a);
ST S(ans);
REP(i,0,N)
{
ST::LV X(last[i]);
S.update(X,a[i],a[i],1);
ans[i]=S.query(0,a[i]-1LL,1).a;
}
return ans;
}
template<class T=string>
ll subcnt(T a, T b) //#subsequences of a that are equal to b (can be upgraded if occorrence of each value in b is restricted)
{
ll N=a.size(); ll M=b.size();
if(M>N) {return 0LL;}
vector<ll> oc; REP(i,0,M) {oc.pb(0LL);}
REP(i,0,N)
{
REP(j,0,M)
{
if(a[i]==b[j])
{
if(j==0) {oc[0]++;}
else {oc[j]+=oc[j-1];}
}
}
}
return oc[M-1];
}
vector<ModInt> PrefixHash(string s, ll B) //char a = 1, b = 2, ...
{
ll oldmod=mod;
mod=B;
ModInt cur=0; ll val; ModInt x=1;
vector<ModInt> ans;
REP(i,0,s.size())
{
val=(ll) (s[i]-'a'); val++;
cur+=(x*val);
x*=26LL;
ans.pb(cur);
}
mod=oldmod;
return ans;
}
template<class T=string>
vector<ll> ZArr(T s)
{
vector<ll> ans; REP(i,0,s.size()) {ans.pb(0);}
ans[0]=s.size(); ll x=1,y=1;
REP(i,1,s.size())
{
y=max(y,i);
if(y==i)
{
ll ind=0;
while(i+ind<s.size() && s[ind]==s[i+ind]) {ind++;}
ans[i]=ind;
y=i+ind;
x=i;
}
else if(i+ans[i-x]-1<=y-2)
{
ans[i]=ans[i-x];
}
else
{
ll ind=0;
while(y+ind<s.size() && s[y+ind]==s[y+ind-i]) {ind++;}
y=y+ind; x=i;
ans[i]=y-i;
}
}
return ans;
}
template<class T=string>
ll patt(T s, T p) //#substrings of s equal to p, O(N)
{
if(p.size()>s.size()) {return 0;}
T x=p; x+=' '; x+=s;
vector<ll> a=ZArr(x);
ll ans=0LL;
REP(i,p.size()+1,a.size())
{
if(a[i]==p.size()) {ans++;}
}
return ans;
}
vector<ll> SuffixArr(string s)
{
ll N = s.size();
unordered_map<char,ll> m1; ll curi=1LL;
set<char> used; REP(i,0,N) {used.insert(s[i]);}
set<char>::iterator it=used.begin();
while(it!=used.end())
{
m1[*it]=curi; curi++;
it++;
}
vector<ll> l,nl; REP(i,0,N) {l.pb(m1[s[i]]);nl.pb(0);}
ll si = 2LL;
set<pl> old; pl cur;
set<pl>::iterator ite;
unordered_map<pl,ll,hash_pair> m;
while(si<=N)
{
old.clear();
m.clear();
REP(i,0,N)
{
cur.ff=l[i]; if(i+si/2<N) {cur.ss=l[i+si/2];} else {cur.ss=0;}
old.insert(cur);
}
ite=old.begin();
curi=1LL;
while(ite!=old.end())
{
m[*ite]=curi; curi++;
ite++;
}
REP(i,0,N)
{
cur.ff=l[i]; if(i+si/2<N) {cur.ss=l[i+si/2];} else {cur.ss=0;}
nl[i]=m[cur];
}
l=nl;
si=2*si;
}
REP(i,0,N) {l[i]--;}
vector<ll> ans; REP(i,0,N) {ans.pb(0);}
REP(i,0,N) {ans[l[i]]=i;}
return ans;
}
vector<ll> LCPArr(string s, vector<ll> SuffixArr)
{
ll N = s.size();
vector<ll> pos; vector<ll> LCP; REP(i,0,N) {pos.pb(0); LCP.pb(0);}
REP(i,0,N) {pos[SuffixArr[i]]=i;}
ll las = 0LL;
REP(i,0,N)
{
ll s1 = i; ll s2;
if(pos[i]+1<N) {s2 = SuffixArr[pos[i]+1];}
else {LCP[pos[i]]=0; las=0; continue;}
ll val=max(0LL,las-1LL);
while(s1+val<N && s2+val<N && s[s1+val]==s[s2+val]) {val++;}
LCP[pos[i]]=val;
las=val;
}
return LCP;
}
template<class T=ll>
T kSmall(vector<T> a, ll K) // K in [0,N-1], O(N)
{
if(a.size()<=50LL) {sort(a.begin(),a.end(),cmp<T>); return a[K];}
srand(time(NULL)*time(NULL));
ll x,y,z; x=rand()%a.size(); y=rand()%a.size(); z=rand()%a.size();
vector<T> dummy; dummy.pb(a[x]); dummy.pb(a[y]); dummy.pb(a[z]); sort(whole(dummy),cmp<T>);
T pivot=dummy[1LL];
vector<ll> rel; REP(i,0,a.size()) {rel.pb(0LL);}
ll sm=0LL; ll eq=0LL; ll bi=0LL;
REP(i,0,a.size())
{
if(a[i]<pivot) {rel[i]=-1;sm++;}
else if(a[i]>pivot) {rel[i]=1;bi++;}
else {rel[i]=0;eq++;}
}
if(sm<=K && sm+eq>=K+1LL) {return pivot;}
vector<T> nxt;
if(sm>=K+1LL) {REP(i,0,a.size()) {if(rel[i]==-1) {nxt.pb(a[i]);}} return kSmall(nxt,K);}
else {REP(i,0,a.size()) {if(rel[i]==1) {nxt.pb(a[i]);}} return kSmall(nxt,K-sm-eq);}
}
class LinRecursion //Linear Recursion
{
public:
ll K;
vector<double> c; //a_N = c1*a_N-1 + ... + cK*a_N-K
Matrix X; //Recursion Matrix
Matrix V0; //Initial vector
LinRecursion(vector<double> coef, vector<double> v0)
{
K=coef.size(); c=coef; vector<vector<double> > xxx; xxx.pb(v0); xxx.pb(v0); Matrix INSIG(xxx);
V0=~INSIG;
xxx.clear(); v0.clear(); REP(i,0,K) {v0.pb(0.0);} REP(i,0,K) {xxx.pb(v0);}
REP(i,0,K-1) {xxx[i][i+1]=1.0;}
REP(i,0,K) {xxx[K-1][i]=c[K-i-1];}
Matrix Y(xxx); X=Y;
}
double query(ll pos) //what's a_pos, pos from 0
{
return ((fastexp(X,pos)*V0).a[0][0]);
}
};
vector<bool> SAT2(ll N, vector<pl> a)
{
ll M=a.size();
vector<vector<ll> > adj; vector<ll> xx; REP(i,0,2*N) {adj.pb(xx);}
pl c;
REP(i,0,M)
{
if(a[i].ff==-a[i].ss) {continue;}
c.ff = -a[i].ff; c.ss=a[i].ss;
if(c.ff<0) {c.ff=2*(-c.ff)-1;}
else {c.ff=2*c.ff-2;}
if(c.ss<0) {c.ss=2*(-c.ss)-1;}
else {c.ss=2*c.ss-2;}
adj[c.ff].pb(c.ss);
swap(a[i].ff,a[i].ss);
c.ff = -a[i].ff; c.ss=a[i].ss;
if(c.ff<0) {c.ff=2*(-c.ff)-1;}
else {c.ff=2*c.ff-2;}
if(c.ss<0) {c.ss=2*(-c.ss)-1;}
else {c.ss=2*c.ss-2;}
adj[c.ff].pb(c.ss);
}
DiGraph G(adj); G.Kosaraju();
vector<bool> ans; REP(i,0,N) {if(G.SCC[2*i]==G.SCC[2*i+1]) {return ans;}}
REP(i,0,N)
{
if(G.SCC[2*i]>G.SCC[2*i+1]) {ans.pb(true);}
else {ans.pb(false);}
}
return ans;
}
vector<vector<ll> > Sum_Set_Cover(vector<vector<ll> > p, ll MAX) //given vectors p0,...,pk-1, is it possible to get sum S in [0,MAX-1] by choosing exactly one element in each vector? ans[i][S] is -1 if S is not attainable in i steps (p0,...,pi), else it is e, meaning the chosen element in pi was pi[e]. pi[j] must be non-negative. Variation of Knapsack. O(MAX*max{pi.size()})
{
vector<vector<ll> > ans; vector<ll> em; REP(i,0,MAX) {em.pb(-1);} REP(i,0,p.size()) {ans.pb(em);}
REP(i,0,p.size())
{
if(i==0)
{
REP(j,0,p[0].size())
{
if(p[0][j]>=MAX) {continue;}
ans[0][p[0][j]]=j;
}
continue;
}
REP(j,0,MAX)
{
if(ans[i-1][j]==-1) {continue;}
REP(z,0,p[i].size())
{
if(j+p[i][z]>=MAX) {continue;}
ans[i][j+p[i][z]]=z;
}
}
}
return ans;
}
bool cmpMo(pl a, pl b)
{
pl p1,p2;
p1.ff=a.ff/Mo_bucket; p1.ss=a.ss;
p2.ff=b.ff/Mo_bucket; p2.ss=b.ss;
return (p1<p2);
}
class Sym //Symmetric sum
{
public:
ll N;
vector<pair<ll,vector<ll> > > c;
Sym() {}
Sym(ll n) {N=n;}
Sym(vector<ll> coef) {N=coef.size(); c.pb(mp(1LL,coef));}
vector<ll> perm; vector<vector<ll> > perms;
void Perm(unordered_multiset<ll> left)
{
if(left.empty())
{
perms.pb(perm);
}
else
{
unordered_multiset<ll> copy = left;
unordered_multiset<ll>::iterator it=left.begin();
while(it!=left.end())
{
perm.pb(*it); copy.erase(copy.find(*it));
Perm(copy);
perm.pop_back(); copy.insert(*it);
it++;
}
}
}
Sym operator *(ll k)
{
Sym ANS=(*this);
REP(i,0,ANS.c.size()) {ANS.c[i].ff*=k;}
ANS.zip();
return ANS;
}
Sym operator + (Sym X)
{
Sym ANS = (*this);
REP(i,0,X.c.size()) {ANS.c.pb(X.c[i]);}
ANS.zip();
return ANS;
}
Sym operator * (Sym X)
{
Sym ANS(N);
REP(a,0,c.size())
{
unordered_multiset<ll> s;
REP(i,0,N) {s.insert(c[a].ss[i]);}
Perm(s);
REP(b,0,X.c.size())
{
REP(i,0,perms.size())
{
vector<ll> cur; REP(z,0,N) {cur.pb(perms[i][z]+X.c[b].ss[z]);}
ANS.c.pb(mp(c[a].ff*X.c[b].ff,cur));
}
}
perms.clear();
}
ANS.zip();
return ANS;
}
void zip()
{
REP(i,0,c.size()) {sort(whole(c[i].ss)); reverse(whole(c[i].ss));}
set<pair<vector<ll>,ll> > s; set<pair<vector<ll>,ll> >::iterator it;
REP(i,0,c.size())
{
it=s.lower_bound(mp(c[i].ss,-INF));
if(it==s.end()) {s.insert(mp(c[i].ss,c[i].ff));}
else if(it->ff==c[i].ss) {pair<vector<ll>,ll> p; p.ff=it->ff; p.ss=it->ss+c[i].ff; s.erase(it); s.insert(p);}
else {s.insert(mp(c[i].ss,c[i].ff));}
}
c.clear();
it=s.begin();
while(it!=s.end())
{
c.pb(mp(it->ss,it->ff));
it++;
}
reverse(whole(c));
}
void disp()
{
zip();
REP(i,0,c.size()) {cout<<c[i].ff<<" * ( "; REP(j,0,c[i].ss.size()) {cout<<c[i].ss[j]<<" ";} cout<<")"<<endl;}
}
};
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
return 0;
}
you have to put this code in proper documentation.. But appreciate your work.
I uploaded all this code with the sole reason that in the upcoming SWERC they allow us to use all code publicly accessible in the internet.
You could have published it on Github, pastebin or even submit it in a random problem on Codeforces. Do you think it is appropriate to publish this huge wall of code as a blog?
why