1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #include<cstdio> #include<cstring> #include<algorithm> using namespace std;
typedef pair<int,int> pii; const int N=33,M=N*N,V=153000,MOD=998244353;
#define fir first #define sec second #define cs const int & inline int Add(cs a,cs b){return a+b>=MOD? a+b-MOD:a+b;} inline int Sub(cs a,cs b){return a-b<0? a-b+MOD:a-b;} inline int Mul(cs a,cs b){return 1ll*a*b%MOD;} inline int Pow(int a,int b){int r=1;while(b){if(b&1)r=Mul(a,r);a=Mul(a,a),b>>=1;}return r;} inline int Div(cs a,cs b){return Mul(a,Pow(b,MOD-2));}
pii operator +(const pii &A,const pii &B){return make_pair(Add(A.fir,B.fir),Add(A.sec,B.sec));} pii operator -(const pii &A,const pii &B){return make_pair(Sub(A.fir,B.fir),Sub(A.sec,B.sec));} pii operator *(const pii &A,const pii &B){return make_pair(Mul(A.fir,B.fir),Add(Mul(A.fir,B.sec),Mul(B.fir,A.sec)));} bool operator ~(const pii &A){return A.fir!=0 || A.sec!=0;} pii operator -(const pii &A){return make_pair(Sub(0,A.fir),Sub(0,A.sec));} pii operator *(const pii &A,const int &B){return make_pair(Mul(A.fir,B),Mul(A.sec,B));} pii Inv(const pii &A){return make_pair(Pow(A.fir,MOD-2),Sub(0,Div(A.sec,Mul(A.fir,A.fir))));}
int n,m; int edg[M][3],cnt[V],phi[V],prn[V]; bool vis[V]; pii E[N][N];
int Det(int siz){ pii ret(1,0); for(int i=1;i<siz;i++){ int it=-1,better=-1; for(int j=i;j<siz;j++) if(~E[j][i]){ if(E[j][i].fir) better=j; it=j; break; } if(~better) it=better; if(it==-1) return 0; if(i!=it){ ret=-ret; for(int j=i;j<siz;j++) swap(E[i][j],E[it][j]); } ret=ret*E[i][i]; if(E[i][i].fir){ pii dv=Inv(E[i][i]); for(int j=i;j<siz;j++) E[i][j]=E[i][j]*dv; for(int j=i+1;j<siz;j++) if(~E[j][i]){ pii mul=E[j][i]; for(int k=i;k<siz;k++) E[j][k]=E[j][k]-E[i][k]*mul; } } else{ int dv=Pow(E[i][i].sec,MOD-2); for(int j=i;j<siz;j++) E[i][j].sec=Mul(E[i][j].sec,dv); for(int j=i+1;j<siz;j++) if(~E[j][i]){ int mul=E[j][i].sec; for(int k=i;k<siz;k++) E[j][k]=E[j][k]-E[i][k]*mul; } } } return ret.sec; } void Prepare(){ int nprn=0; phi[1]=1; for(int i=2;i<V;i++){ if(!vis[i]) prn[++nprn]=i,phi[i]=i-1; for(int j=1;j<=nprn && prn[j]*i<V;j++){ vis[i*prn[j]]=true; if(i%prn[j]) phi[i*prn[j]]=Mul(phi[i],phi[prn[j]]); else{ phi[i*prn[j]]=Mul(phi[i],prn[j]); break; } } } } inline int Ri(){ register int r=0,c=getchar(); while(c<'0' || '9'<c) c=getchar(); while('0'<=c && c<='9') r=(r<<1)+(r<<3)+c-'0',c=getchar(); return r; } int main(){ Prepare(); n=Ri(),m=Ri(); for(int i=1;i<=m;i++){ edg[i][0]=Ri(),edg[i][1]=Ri(),edg[i][2]=Ri(); for(int j=1;j*j<=edg[i][2];j++) if(edg[i][2]%j==0){ cnt[j]++; if(edg[i][2]!=j*j) cnt[edg[i][2]/j]++; } } int ans=0; for(int d=1;d<=V;d++){ if(cnt[d]<n-1) continue; for(int i=1;i<=m;i++){ if(edg[i][2]%d) continue; pii thi(1,edg[i][2]); int u=edg[i][0],v=edg[i][1]; E[u][u]=E[u][u]+thi,E[v][v]=E[v][v]+thi; E[u][v]=E[u][v]-thi,E[v][u]=E[v][u]-thi; } int res=Det(n); ans=Add(ans,Mul(phi[d],res)); memset(E,0,sizeof E); } printf("%d\n",ans); return 0; }
|