Problem:
Score : 300 points

Problem Statement

You are given an undirected unweighted graph with N vertices and M edges that contains neither self-loops nor double edges.

Here, a self-loop is an edge where a_i = b_i (1≤i≤M), and double edges are two edges where (a_i,b_i)=(a_j,b_j) or (a_i,b_i)=(b_j,a_j) (1≤i<j≤M).

How many different paths start from vertex 1 and visit all the vertices exactly once?

Here, the endpoints of a path are considered visited.

For example, let us assume that the following undirected graph shown in Figure 1 is given.

Figure 1: an example of an undirected graph

The following path shown in Figure 2 satisfies the condition.

Figure 2: an example of a path that satisfies the condition

However, the following path shown in Figure 3 does not satisfy the condition, because it does not visit all the vertices.

Figure 3: an example of a path that does not satisfy the condition

Neither the following path shown in Figure 4, because it does not start from vertex 1.

Figure 4: another example of a path that does not satisfy the condition

Constraints

2≦N≦8

0≦M≦N(N-1)/2

1≦a_i<b_i≦N

The given graph contains neither self-loops nor double edges.

Input

The input is given from Standard Input in the following format:

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print the number of the different paths that start from vertex 1 and visit all the vertices exactly once.

Sample Input 1

3 3
1 2
1 3
2 3

Sample Output 1

2

The given graph is shown in the following figure:

The following two paths satisfy the condition:

Sample Input 2

7 7
1 3
2 7
3 4
4 5
4 6
5 6
6 7

Sample Output 2

1

This test case is the same as the one described in the problem statement.

Solution in Rust (1.15.1) (judge verdict: Accepted)


use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
  let stdin = stdin();
  let stdin = stdin.lock();
  let token: String = stdin
    .bytes()
    .map(|c| c.expect("failed to read char") as char)
    .skip_while(|c| c.is_whitespace())
    .take_while(|c| !c.is_whitespace())
    .collect();
  token.parse().ok().expect("failed to parse token")
}

use std::cmp::{max, min};
use std::collections::HashMap;

fn main() {
  let n = read::<usize>();
  let m = read::<usize>();
  let mut map: Vec<Vec<usize>> = vec![vec![0; n + 1]; n + 1];

  for _ in 0..m {
    let a = read::<usize>();
    let b = read::<usize>();
    map[a][b] = 1;
    map[b][a] = 1;
  }

  let mut visited: Vec<usize> = vec![];
  let mut node = 1;
  let mut cnt = 0;

  dfs(node, &mut visited, &map, n, &mut cnt);
  println!("{}", cnt);
}


fn dfs(node: usize, visited: &mut Vec<usize>, map: &Vec<Vec<usize>>, n: usize, cnt: &mut i64) {
  if visited.contains(&node) {
    return;
  }
  visited.push(node);


  if visited.len() == n {
    *cnt += 1;
    return;
  }

  for (i, v) in map[node].iter().enumerate() {
    if *v == 1 {
      let mut copy_visited = visited.clone();
      dfs(i, &mut copy_visited, map, n, cnt);
    }
  }
}