#include #include #include #include using namespace std; vector> adj, adj2 ; vector parent, depth, q, deg, head, spec, path, cache ; vector> remap ; using namespace std; void dfs(int a, int h) { if (head[a] < 0) { head[a] = h ; for (auto b: adj[a]) if (deg[b] == 0) dfs(b, h) ; } } int dfs(int a, int b, unsigned long long used) { if (a == b) return 1 ; int r = 0 ; for (auto c: adj2[a]) if (((used >> c) & 1) == 0) r += dfs(c, b, used | (1LL<= 0; ) { deg[a]-- ; int nexta = -1 ; for (int b: adj[a]) if (deg[b] > 0) { deg[b]-- ; if (deg[b] == 1) { nexta = b ; break ; } } a = nexta ; } } head.resize(n, -1) ; for (int i=0; i 0) dfs(i, i) ; remap.resize(n) ; for (int i=0; i 2) { remap[i] = {(int)spec.size(), (int)spec.size()} ; spec.push_back(i) ; } int newn = spec.size() ; for (auto a: spec) for (auto b: adj[a]) if (deg[b] > 0) { path = {a} ; while (deg[b] == 2) { path.push_back(b) ; int newb = -1 ; for (auto c: adj[b]) if (deg[c] > 0 && c != path[path.size()-2]) { newb = c ; break ; } b = newb ; } path.push_back(b) ; if (path[0] > path[path.size()-1] || (path[0] == path[path.size()-1] && (path.size() == 2 || path[1] > path[path.size()-2]))) { adj2.resize(newn+2) ; adj2[remap[a].first].push_back(newn) ; adj2[newn].push_back(newn+1) ; adj2[newn+1].push_back(remap[b].first) ; adj2[newn].push_back(remap[a].first) ; adj2[newn+1].push_back(newn) ; adj2[remap[b].first].push_back(newn+1) ; for (int j=1; j+1<(int)path.size(); j++) remap[path[j]] = {newn, newn+1} ; newn += 2 ; } } int cachesize = newn * newn ; cache.resize(cachesize, -1) ; for (int i=0; i= 0) r = cache[k] ; else { r = dfs(a, b, 1<