#pragma once
#define REP_(i, n) for (int i = 0; i < (n); i++)
#define REP2_(i, s, n) for (int i = (s); i < (n); i++)
template<typenameK,size_tN>structSquareMatrix{usingvalue_type=K;usingvec=std::array<K,N>;usingmat=std::array<vec,N>;matM;SquareMatrix(Ka=0){for(vec&v:M)v.fill(0);if(a!=0)REP_(i,N)M[i][i]=a;}SquareMatrix(constmat&A):M(A){}SquareMatrix(conststd::vector<std::vector<K>>&v){assert(v.size()==Nandv[0].size()==N);REP_(i,N)REP_(j,N)M[i][j]=v[i][j];}vec&operator[](size_tk){returnM[k];}constvec&operator[](size_tk)const{returnM[k];}SquareMatrix&operator+=(constSquareMatrix&A){REP_(i,N)REP_(j,N)M[i][j]+=A[i][j];return*this;}SquareMatrix&operator-=(constSquareMatrix&A){REP_(i,N)REP_(j,N)M[i][j]-=A[i][j];return*this;}SquareMatrixoperator+(constSquareMatrix&A)const{returnSquareMatrix(M)+=A;}SquareMatrixoperator-(constSquareMatrix&A)const{returnSquareMatrix(M)-=A;}friendSquareMatrixoperator*(constSquareMatrix&A,constSquareMatrix&B){SquareMatrixres;REP_(i,N)REP_(k,N)REP_(j,N)res[i][j]+=A[i][k]*B[k][j];returnres;}SquareMatrix&operator*=(constSquareMatrix&A){M=((*this)*A).M;return*this;}SquareMatrix&operator/=(constSquareMatrix&A){return(*this)*=A.inv();}SquareMatrixoperator/(constSquareMatrix&A)const{returnSquareMatrix(M)/=A;}booloperator==(constSquareMatrix&A){REP_(i,N)REP_(j,N)if(M[i][j]!=A[i][j])returnfalse;returntrue;}booloperator!=(constSquareMatrix&A){return!((*this)==A);}staticSquareMatrixI(){returnSquareMatrix(1);}SquareMatrixpow(longlongn)const{assert(n>=0);SquareMatrixA(M),res(1);while(n){if(n&1)res*=A;A*=A;n>>=1;}returnres;}std::pair<int,int>GaussJordan(){intrnk=0,cnt=0;REP_(k,N){if(M[rnk][k]==0)REP2_(i,rnk+1,N)if(M[i][k]!=0){std::swap(M[i],M[rnk]);cnt^=1;break;}if(M[rnk][k]==0)continue;REP_(i,N)if(i!=rnk){Kx=M[i][k]/M[rnk][k];REP_(j,N)M[i][j]-=M[rnk][j]*x;}if(++rnk==N)break;}return{rnk,cnt};}Kdet()const{SquareMatrixA(M);constauto&[rnk,cnt]=A.GaussJordan();if(rnk!=N)return0;Kres=1;REP_(i,N)res*=A[i][i];return(cnt?-res:res);}SquareMatrixinv()const{SquareMatrixA(M),B(1);REP_(k,N){if(A[k][k]==0)REP2_(i,k+1,N)if(A[i][k]!=0){std::swap(A[i],A[k]);std::swap(B[i],B[k]);}assert(A[k][k]!=0);REP_(i,N)if(i!=k){Kx=A[i][k]/A[k][k];REP_(j,N){A[i][j]-=A[k][j]*x;B[i][j]-=B[k][j]*x;}}Kx=A[k][k];REP_(j,N){A[k][j]/=x;B[k][j]/=x;}}returnB;}friendstd::ostream&operator<<(std::ostream&os,constSquareMatrix&M){REP_(i,N)REP_(j,N)os<<M.M[i][j]<<"\n "[j+1<N];returnos;}friendstd::istream&operator>>(std::istream&is,SquareMatrix&M){REP_(i,N)REP_(j,N)is>>M.M[i][j];returnis;}};#undef REP_
#undef REP2_
#line 2 "library/linearalgebra/SquareMatrix.hpp"
#define REP_(i, n) for (int i = 0; i < (n); i++)
#define REP2_(i, s, n) for (int i = (s); i < (n); i++)
template<typenameK,size_tN>structSquareMatrix{usingvalue_type=K;usingvec=std::array<K,N>;usingmat=std::array<vec,N>;matM;SquareMatrix(Ka=0){for(vec&v:M)v.fill(0);if(a!=0)REP_(i,N)M[i][i]=a;}SquareMatrix(constmat&A):M(A){}SquareMatrix(conststd::vector<std::vector<K>>&v){assert(v.size()==Nandv[0].size()==N);REP_(i,N)REP_(j,N)M[i][j]=v[i][j];}vec&operator[](size_tk){returnM[k];}constvec&operator[](size_tk)const{returnM[k];}SquareMatrix&operator+=(constSquareMatrix&A){REP_(i,N)REP_(j,N)M[i][j]+=A[i][j];return*this;}SquareMatrix&operator-=(constSquareMatrix&A){REP_(i,N)REP_(j,N)M[i][j]-=A[i][j];return*this;}SquareMatrixoperator+(constSquareMatrix&A)const{returnSquareMatrix(M)+=A;}SquareMatrixoperator-(constSquareMatrix&A)const{returnSquareMatrix(M)-=A;}friendSquareMatrixoperator*(constSquareMatrix&A,constSquareMatrix&B){SquareMatrixres;REP_(i,N)REP_(k,N)REP_(j,N)res[i][j]+=A[i][k]*B[k][j];returnres;}SquareMatrix&operator*=(constSquareMatrix&A){M=((*this)*A).M;return*this;}SquareMatrix&operator/=(constSquareMatrix&A){return(*this)*=A.inv();}SquareMatrixoperator/(constSquareMatrix&A)const{returnSquareMatrix(M)/=A;}booloperator==(constSquareMatrix&A){REP_(i,N)REP_(j,N)if(M[i][j]!=A[i][j])returnfalse;returntrue;}booloperator!=(constSquareMatrix&A){return!((*this)==A);}staticSquareMatrixI(){returnSquareMatrix(1);}SquareMatrixpow(longlongn)const{assert(n>=0);SquareMatrixA(M),res(1);while(n){if(n&1)res*=A;A*=A;n>>=1;}returnres;}std::pair<int,int>GaussJordan(){intrnk=0,cnt=0;REP_(k,N){if(M[rnk][k]==0)REP2_(i,rnk+1,N)if(M[i][k]!=0){std::swap(M[i],M[rnk]);cnt^=1;break;}if(M[rnk][k]==0)continue;REP_(i,N)if(i!=rnk){Kx=M[i][k]/M[rnk][k];REP_(j,N)M[i][j]-=M[rnk][j]*x;}if(++rnk==N)break;}return{rnk,cnt};}Kdet()const{SquareMatrixA(M);constauto&[rnk,cnt]=A.GaussJordan();if(rnk!=N)return0;Kres=1;REP_(i,N)res*=A[i][i];return(cnt?-res:res);}SquareMatrixinv()const{SquareMatrixA(M),B(1);REP_(k,N){if(A[k][k]==0)REP2_(i,k+1,N)if(A[i][k]!=0){std::swap(A[i],A[k]);std::swap(B[i],B[k]);}assert(A[k][k]!=0);REP_(i,N)if(i!=k){Kx=A[i][k]/A[k][k];REP_(j,N){A[i][j]-=A[k][j]*x;B[i][j]-=B[k][j]*x;}}Kx=A[k][k];REP_(j,N){A[k][j]/=x;B[k][j]/=x;}}returnB;}friendstd::ostream&operator<<(std::ostream&os,constSquareMatrix&M){REP_(i,N)REP_(j,N)os<<M.M[i][j]<<"\n "[j+1<N];returnos;}friendstd::istream&operator>>(std::istream&is,SquareMatrix&M){REP_(i,N)REP_(j,N)is>>M.M[i][j];returnis;}};#undef REP_
#undef REP2_