Solution Notes (Neal Wu): Let us say that an edge points to a vertex if that vertex was responsible for building the edge. We would like to know how many assignments there are such that each edge points to some vertex, and each vertex has at most one edge pointing to it.

Our first observation is that we can solve the problem for each connected component and then multiply the answers together since the components are independent. Now let us assume a connected component has n vertices. We have three different cases for the number of edges:

Our solution is simply a DFS to find and categorize each connected component, as in the below implementation from problem author Mark Gordon:


#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>

using namespace std;

#define MOD 1000000007
#define MAXM 100000

bool vis[MAXM];
vector<int> E[MAXM];

pair<int, int> dfs(int x) {
  if(vis[x]) return make_pair(0, 0);
  vis[x] = true;

  pair<int, int> ret(1, E[x].size());
  for(int i = 0; i < E[x].size(); i++) {
    pair<int, int> res = dfs(E[x][i]);
    ret.first += res.first;
    ret.second += res.second;
  }
  return ret;
}

int main() {
  freopen("alliance.in", "r", stdin);
  freopen("alliance.out", "w", stdout);
  int N, M;
  cin >> N >> M;

  for(int i = 0; i < M; i++) {
    int u, v; cin >> u >> v; u--; v--;
    E[u].push_back(v);
    E[v].push_back(u);
  }

  int result = 1;
  for(int i = 0; i < N; i++) {
    if(vis[i] || E[i].empty()) continue;

    pair<int, int> res = dfs(i);
    if(res.second % 2) cerr << "PROBLEM" << endl;
    res.second /= 2;
    if(res.first == res.second + 1) {
      result = (1ll * result * res.first) % MOD;
    } else if(res.first == res.second) {
      result = (2 * result) % MOD;
    } else {
      result = 0;
    }
  }

  cout << result << endl;
}