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++14 (Clang 3.8.0) (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <numeric>
#include <array>
#include <cmath>
#include <memory>
using namespace std;
//変数デバッグ
#define DEB(variable) cout << #variable << '=' << variable << endl

//for簡易表記(引数ミス防止)
#define FOR(LoopVariable,numberOFbegin,numberOFend) for (long long int LoopVariable = (numberOFbegin); (LoopVariable) < (numberOFend); (LoopVariable)++)
#define DEFOR(LoopVariable,numberOFbegin,numberOFend) for (long long int LoopVariable = (numberOFbegin)-1; (LoopVariable) >= (numberOFend); (LoopVariable)--)
#define REP(LoopVariable,numberOFend) for(long long int LoopVariable = 0;(LoopVariable)<(numberOFend);LoopVariable++)

using llint = long long int;

constexpr long long int linf = numeric_limits<long long int>::max()-5;
constexpr long long int inf= numeric_limits<int>::max()-5;
constexpr long long int mod = 1000000007;

class Graph{
public:
    ////////////グラフサイズを渡して作成する
    ////////////infの値は必要に応じて調整すること
    Graph(long long int n):g_size(n),edges(n,vector<long long int>(n,inf)){
        REP(i,n){
            edges[i][i] = 0;
        }


    }
    
    //////////// 枝のvector<>をわたして作成
    //////////// infの値は必要に応じて調整すること
    Graph(long long int n,vector<pair<long long int,long long int>> v):g_size(n),edges(n,vector<long long int>(n,inf)){
        REP(i,g_size){
            edges[i][i] = 0;
        }
        REP(i,v.size()){
            add_edge(v[i].first, v[i].second);
        }        
    }

    ///////////初期状態では有向
    ///////////無向にするときは
    /*  edges[b][a] = cost;  */
    //を追加
    void add_edge(long long int a,long long int b,long long int cost=1){
        edges[a][b] = cost;
        edges[b][a] = cost;
    }
      llint solve(){
        llint result = 0;
        result += search(0,1<<0);
        return result;
    }
    llint search(llint n,llint bit){
        if(bit==(1<<g_size)-1){
            return 1;
        }
        llint result = 0;
        REP(i,g_size){
            if(edges[n][i]!=1||((1<<i)&bit)){
                continue;
            }else if(((bit | (1 << i)))==(1<<g_size)-1){
                    return 1;
            }else{
                result += search(i, (bit | (1 << i)));
            }
        }
        return result;
    }
  

  
private:
    long long int g_size;
    vector<vector<long long int>> edges;
  
};

int main(){
    llint n, m;
    cin >> n >> m;
    vector<pair<long long int, long long int>> v(m);
 
    REP(i,m){
        cin >> v[i].first >> v[i].second;
        v[i].first--;
        v[i].second--;
    }
    Graph graph(n,v);
    cout << graph.solve() << endl;
    return 0;
}