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 C (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#define MAX 8

//できてない

int sides[MAX][MAX] = {0};
int visited[MAX] = {0};

int stack[MAX+1] = {0};
int stacklen = 0;

void push(int n){
	stack[stacklen] = n;
	stacklen ++;
}

int pop(){
	if(stacklen == 0){return -1;}
	int last = stack[stacklen-1] ;
	stacklen --;
	return last;
}

int visitedall(const int citynum){
	int num=0;
	//printf("[");
	for(int i = 0; i < citynum; i++){
		//printf("%d, ", visited[i]);
		if(visited[i]==1){num++;}	
	}
	//printf("]\n");
	if(num==citynum){return 1;}
	else{return 0;}
}


int dfs(int current, int count, const int citynum){
	//visitedが全て1であればcount+1してreturn 0。 一つでもゼロであれば次を行う。
	//printf("now @ %d", current+1);
	if(visitedall(citynum)){return count+1;} //printf("finished, count +1\n"); 
	//未訪問がある
	int candidate = 0; 
	for(int i = 0; i < citynum; i++){
		if(sides[current][i] == 1 && visited[i] == 0){
			push(i);
			candidate ++;
		}
	}
	if(candidate==0){return count;} //printf("finished, count +0\n");
	for(int i = 0; i < candidate; i++){
	 	int next = pop();
	 	//printf("=> go to %d (count:%d) \n", next+1, count);
	 	visited[next] = 1; 
	 	count = dfs(next, count, citynum);
	 	//printf("return to %d from %d (count:%d)\n",current+1, next+1, count);
	 	visited[next] = 0;
	 }
	 //printf("fin_of_dfs:%d\n", count);
	 return count;
}



int main(){
	int n, m, a, b;
	if(scanf("%d %d", &n, &m)==EOF){return 0;}
	
	for(int i = 0; i<m; i++){
		if(scanf("%d %d", &a, &b)==EOF){return 0;}
		sides[a-1][b-1] = 1;
		sides[b-1][a-1] = 1;
	}
	
	push(0); //stacklenが1になる
	visited[0] = 1;
	printf("%d\n", dfs(0, 0, n));
	return 0;

}