#pragma once
template<classT,intSIZE>structMatrix:array<array<T,SIZE>,SIZE>{Matrix(Tval=T(0)){for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++){this->at(i).at(j)=val;}}}staticconstexprMatrixadditive_identity(){returnMatrix();}staticconstexprMatrixmultiplicative_identity(){Matrixres;for(inti=0;i<SIZE;i++){res[i][i]=1;}returnres;}Matrix&operator+=(constMatrix&rhs){for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++){this->at(i).at(j)+=rhs[i][j];}}return*this;}Matrix&operator-=(constMatrix&rhs){for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++){this->at(i).at(j)-=rhs[i][j];}}return*this;}Matrix&operator*=(constMatrix&rhs){Matrixres;for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++){for(intk=0;k<SIZE;k++){res[i][j]+=this->at(i).at(k)*rhs[k][j];}}}return*this=res;}Matrix&operator*=(constT&val){for(inti=0;i<SIZE;i++){for(intj=0;j<SIZE;j++){this->at(i).at(j)*=val;}}return*this;}constexprMatrixoperator-()const{returnMatrix(*this)*=-1;}friendconstexprMatrixoperator+(constMatrix&lhs,constMatrix&rhs){returnMatrix(lhs)+=rhs;}friendconstexprMatrixoperator-(constMatrix&lhs,constMatrix&rhs){returnMatrix(lhs)-=rhs;}friendconstexprMatrixoperator*(constMatrix&lhs,constMatrix&rhs){returnMatrix(lhs)*=rhs;}friendconstexprMatrixoperator*(constMatrix&lhs,constT&rhs){returnMatrix(lhs)*=rhs;}friendconstexprMatrixoperator*(constll&lhs,constMatrix&rhs){returnMatrix(rhs)*=lhs;}constexprMatrixpow(lln){Matrixbase=*this;Matrixres=multiplicative_identity();while(n>0){if(n&1)res*=base;base*=base;n>>=1;}returnres;}};