Dividing a set of edges into a number of extremely disjoint sets, satisfying each simple ring can be summed up by some of the collections, the answer is an approximate $\gcd$ of the size of those collections.
For a simple ring, the upper edge must not be a bridge edge, and it must not be on the other simple ring at the edge of the set. So after you delete it, these edges become bridge edges from non-bridged edges.
Enumerate each non-bridge edge run Tarjan calculate the answer.
Time Complexity $o (M (n+m)) $.
#include <cstdio>const int N=2005,buf=21000;int n,m,i,x,y,now,ans,d,cut[n],g[n],v[n<<1],nxt[n<<1 ],ed=1;int Q[n<<1],*st[n],*en[n],dfn[n],low[n],num;char buf[buf],*buf=buf;inline void Read (Int&a) {for (a= 0;*buf<48;buf++); while (*buf>47) a=a*10+*buf++-48;} inline void Add (int x,int y) {v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} void Dfs (int x,int y) {dfn[x]=low[x]=++num; for (int*i=st[x];i<en[x];i++) {int u= (*i) &2047; if (u==y) continue; if (!dfn[u]) {DFS (u,x); if (Low[x]>low[u]) low[x]=low[u]; if (Low[u]==dfn[u]) cut[(*i) >>12]=1; }else if (Low[x]>dfn[u]) low[x]=dfn[u]; }}void Tarjan (int x,int y) {dfn[x]=low[x]=++num; for (int*i=st[x];i<en[x];i++) if (((*i) >>12)!=d) {int u=*i&2047; if (u==y) continue; if (!dfn[u]) {Tarjan (u,x); if (Low[x]>low[u]) low[x]=low[u]; if (low[u]==dfn[u]&&!cut[(*i) >>12]) now++; }else if (Low[x]>dfn[u]) low[x]=dfn[u]; }}int gcd (int a,int b) {return B?GCD (b,a%b): A;} int main () {fread (Buf,1,buf,stdin), read (n), read (m); for (i=1;i<=m;i++) read (x), read (y), add (x, y), add (y,x); for (i=1;i<=n;i++) {st[i]=q+num+1; for (X=g[i];x;x=nxt[x]) q[++num]=x<<11|v[x]; en[i]=q+num+1; } for (num=0,i=1;i<=n;i++) if (!dfn[i]) DFS (i,0); for (d=1;d<=m;d++) if (!cut[d]) {for (now=i=1,num=0;i<=n;i++) dfn[i]=0; for (i=1;i<=n;i++) if (!dfn[i]) Tarjan (i,0); if (!ans) Ans=now;else ans=gcd (Ans,now); } for (i=1;i<=ans;i++) if (ans%i==0) printf ("%d%c", I,i<ans? ' ': ' \ n '); return 0;}
BZOJ4116: [wf2015]tours