stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<n; i++)



using namespace std;

typedef long long ll;



using Graph = vector<vector<int>>;

typedef pair<int, int> P;



int N,M;



bool check(Graph G, vector<int> v){

    rep(i,N-1){

        if(!G[v[i]][v[i+1]]){

            return false;

        }

    }

    return true;

}



int main(){

    cin >> N >> M;

    Graph G(N,(vector<int>(N,0)));

    rep(i,M) {

        int a,b;

        cin >> a >> b;

        a--;b--;

        G[a][b] = G[b][a] = 1;

    }

    vector<int> v(N);

    rep(i,N) v[i] = i;

    long long ans = 0;

    do{

        if(v[0]==0 && check(G, v)) ans++;

    }while(next_permutation(v.begin(), v.end()));

    cout << ans << endl;

}




// Faster C++ solution for the same problem (measured speedup: 1.23332127607297x):
#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;





int main() {

    int N, M;

    cin >> N >> M;

    vector<vector<bool>> path(N, vector<bool>(N, false));



    rep(i, M){

        int x, y;

        cin >> x >> y;

        x--; y--;

        path[x][y] = path[y][x] = true;

    }

    vector<int> v(N);

    rep(i, N) v[i] = i;



    int ans = 0;



    do{

        

        if (v[0]!=0) continue;

        bool flag = true;

        rep(i, N-1) {

            if (!path[v[i]][v[i+1]]) {

                flag = false;

                break;

            }

        }

        if(flag) ans++;

    }while(next_permutation(v.begin(), v.end()));



    cout << ans << endl;

}
// Slower C++ solution:
#include <stdio.h>

#include <string>

#include <cstring>

#include <stdlib.h>

#include <math.h>

#include <algorithm>

#include <vector>

#include <set>

#include <map>

#include <queue>

#include <iterator>

#pragma warning(disable:4996)

 

typedef long long ll;

#define MIN(a, b) ((a)>(b)? (b): (a))

#define MAX(a, b) ((a)<(b)? (b): (a))

#define LINF 9223372036854775807

#define INF 2147483647

#define MOD 1000000007

using namespace std;



long n,m;

vector<vector<long> > z;

long vis[10];

long cnt;

ll   ans;



void dfs( long curr )

{

    if(cnt==n) {

        ans++;

        return;

    }



    long i;

    for(i=0; i<(long)z[curr].size(); i++) {

        if(!vis[z[curr][i]]) {

            vis[z[curr][i]]=1;

            cnt++;

            dfs( z[curr][i] );

            vis[z[curr][i]]=0;

            cnt--;

        }

    }

    return;

}



int main(int argc, char* argv[])

{

    scanf("%ld%ld", &n, &m);



    z.resize(n);

    long i;

    for(i=0; i<m; i++) {

        long a, b;

        scanf("%ld%ld", &a, &b);

        z[a-1].push_back(b-1);

        z[b-1].push_back(a-1);

    }



    ans=0;

    vis[0]=1;

    cnt = 1;

    dfs( 0 );



    printf("%lld\n", ans);



    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.434734944737363x):
#include <stdio.h>

#include <string>

#include <cstring>

#include <stdlib.h>

#include <math.h>

#include <algorithm>

#include <vector>

#include <set>

#include <map>

#include <queue>

#include <list>

#include <iterator>

#include <assert.h>

#pragma warning(disable:4996) 



typedef long long ll;

#define MIN(a, b) ((a)>(b)? (b): (a))

#define MAX(a, b) ((a)<(b)? (b): (a))

#define LINF 9223300000000000000

#define INF 2140000000

const long long MOD = 1000000007;

using namespace std;



ll dp[1<<8][8];



int main(int argc, char* argv[])

{

    int n,m;

    scanf("%d%d", &n, &m);



    int g[8][8]={0};

    int i;

    for(i=0; i<m; i++) {

        int a,b;

        scanf("%d%d", &a, &b);

        g[a-1][b-1]=1;

        g[b-1][a-1]=1;

    }



    dp[1][0]=1;

    for(i=2; i<(1<<n); i++) {

        int k;

        for(k=0; k<n; k++) {

            if(i & (1<<k)) {

                int prev = (i & ~(1<<k));

                int j;

                for(j=0; j<n; j++) {

                    if(dp[prev][j] && (prev & (1<<j)) && g[k][j]) {

                        dp[i][k] += dp[prev][j];

                    }

                }

            }

        }

    }

    ll ans=0;

    for(i=1; i<n; i++) {

        ans += dp[(1<<n)-1][i];

    }

    printf("%lld\n", ans);



    return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>

#include <cmath>

#include <queue>

#include <limits>

#include <map>

#define REP(i,n) for(int (i)=0;(i)<(n);(i)++)

#define IREP(i,j,n) for(int (i)=(j);(i)<(n);(i)++)

#define INF numeric_limits<double>::infinity()

constexpr long MOD = 1e9 + 7;

using namespace std;



int n, m;

vector<int> adj[10];



bool connected(int i, int j) {

    int f = false;

    REP(k,adj[i].size()) {

        if (adj[i][k] == j) f = true;

    }

    return f;

}



int main() {

    cin >> n >> m;

    int a, b;

    REP(i,m) {

        cin >> a >> b;

        a--;

        b--;

        adj[a].push_back(b);

        adj[b].push_back(a);

    }

    

    int cnt = 0;

    vector<int> v;

    REP(i,n) {

        v.push_back(i);

    }

    

    do {

        int c = true;

        REP(i,v.size()-1) {

            if (!connected(v[i], v[i+1])) {

                c = false;

            }

        }

        if (v[0] == 0 && c) cnt++;

    } while (next_permutation(v.begin(), v.end()));

    

    cout << cnt << endl;

}


// Faster C++ solution for the same problem (measured speedup: 1.1814116765525904x):
#include <bits/stdc++.h>

using namespace std;



int main() {

    int n, m;

    cin >> n >> m;

    set<pair<int, int>> edges;

    for (int i = 0; i < m; i++) {

        int a, b;

        cin >> a >> b;

        edges.insert({min(a, b), max(a, b)});

    }



    int cnt = 0;

    vector<int> perm(n - 1);

    iota(perm.begin(), perm.end(), 2);



    do {

        bool ok = true;

        vector<int> path = {1};

        for (int v : perm) {

            path.push_back(v);

        }

        for (int i = 0; i < n - 1; i++) {

            int a = path[i], b = path[i + 1];

            if (edges.count({min(a, b), max(a, b)}) == 0) {

                ok = false;

                break;

            }

        }

        if (ok) cnt++;

    } while (next_permutation(perm.begin(), perm.end()));



    cout << cnt << '\n';

}
// Slower C++ solution:
#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

#define all(v) v.begin(), v.end()

using ll = long long;

using vi = vector<int>;

using pii = pair<int, int>;



int main()

{

    int n, m;

    cin >> n >> m;

    vector<vi> g(n, vi(n));

    rep(i, m)

    {

        int a, b;

        cin >> a >> b;

        a--;

        b--;

        g[a][b] = g[b][a] = 1;

    }

    vi p(n);

    rep(i, n)

    {

        p[i] = i + 1;

    }

    int ans = 0;

    do

    {

        if (p[0] != 1)

            break;

        bool flag = true;

        rep(i, n - 1)

        {

            if (g[p[i] - 1][p[i + 1] - 1] == 0)

                flag = false;

        }

        if (flag)

            ans++;

    } while (next_permutation(all(p)));

    cout << ans << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.761858509214244x):
#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

using ll = long long;

using P = pair<int, int>;



int main()

{

  int n, m;

  cin >> n >> m;

  vector<vector<int>> vec(n + 1, vector<int>(n + 1));

  rep(i, m)

  {

    int a, b;

    cin >> a >> b;

    vec[a][b] = 1;

    vec[b][a] = 1;

  }

  vector<int> v(n);

  rep(i, n) v[i] = i + 1;

  int ans = 0;

  sort(v.begin(), v.end());

  do

  {

    if (v[0] != 1)

      break;

    bool ok = true;

    rep(i, n - 1)

    {

      if (vec[v[i]][v[i + 1]] == 0)

        ok = false;

    }

    if (ok)

      ans++;

  } while (next_permutation(v.begin(), v.end()));

  cout << ans << endl;

  return 0;

}
// Slower C++ solution:
#include <vector>

#include <iostream>



using namespace std;



int N, M;

bool e[8][8];

int ans = 0;

int p[8];



void dfs(int pos, int mask) {

		if (pos == N) {

				for (int i = 0; i < N-1; i++) {

						if (p[0] != 0) return;

						else if (!e[p[i]][p[i+1]]) return;

				}

				ans++;

				return;

		}



		for (int i = 0; i < N; i++) {

				if (mask & (1<<i)) {

						p[pos] = i;

						dfs(pos+1, (mask^(1<<i)));

				}

		}

}



int main() {

		cin >> N >> M;

		vector<int> v[N];

		for (int i = 0; i < M; i++) {

				int a, b;

				cin >> a >> b;

				a--; b--;

				e[a][b] = true;

				e[b][a] = true;

		}



		dfs(0, (1<<N) - 1);

		cout << ans << endl;

		return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1643770144487884x):
#include <iostream>

#include <vector>



using namespace std;



int N, M;

vector<int> e[8];

int ans = 0;



void dfs(int pos, int visited) {

		visited |= (1<<pos);

		if (__builtin_popcount(visited) == N) {

				ans++;

				return;

		}



		for (auto itr = e[pos].begin(); itr < e[pos].end(); itr++) {

				if (visited & (1<<(*itr))) continue;

				dfs(*itr, visited);

		}

}



int main() {

		cin >> N >> M;

		for (int i = 0; i < M; i++) {

				int a, b;

				cin >> a >> b;

				a--; b--;

				e[a].push_back(b);

				e[b].push_back(a);

		}



		dfs(0, 0);



		cout << ans << endl;



		return 0;

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#include<cstring>

#include <cstdlib>  

#include <cmath>   

#include<cctype>

#include<string>

#include <map>

#include<algorithm>

#include <functional>

#include<vector>

#include<climits>

#include<stack>

#include<queue>

#include <deque>

#include <utility> 



#define rep(i,m,n) for(int i = m;i < n;++i)

using namespace std;

using ll = long long;

using R = double;

const ll inf = 1LL << 50;

const ll MOD = 1e9 + 7;











int main(){

	vector< pair<int, int> > edge;

	

	int n, m;

	cin >> n >> m;



	

	rep(i, 0, m) {

		int a, b;

		cin >> a >> b;

		auto p1 = make_pair(a, b);

		auto p2 = make_pair(b, a);

		edge.push_back(p1);

		edge.push_back(p2);



	}



	vector<int> node;

	rep(i, 1, n + 1) {

		node.push_back(i);

	}





	int ans = 0;

	do {

		int match = 0;

		rep(i, 0, n - 1) {

			int from = node[i];

			int to = node[i + 1];

			for (auto x : edge) {

				if (from == x.first && to == x.second) {

					match++;

				}

			}

		}

		if (match == n - 1 && node[0]==1)ans++;

	} while (next_permutation(node.begin(), node.end()));



	cout << ans << endl;

	









	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.4332985119358446x):
#include<iostream>

#include<cstdio>

#include<cstring>

#include <cstdlib>  

#include <cmath>   

#include<cctype>

#include<string>

#include <map>

#include<algorithm>

#include <functional>

#include<vector>

#include<climits>

#include<stack>

#include<queue>

#include <deque>

#include <utility> 



#define rep(i,m,n) for(int i = m;i < n;++i)

using namespace std;

using ll = long long;

using R = double;

const ll inf = 1LL << 50;

const ll MOD = 1e9 + 7;





bool graph[8][8];





int dfs(int v, int n, bool visited[8]) {

	bool all_visited = true;

	rep(i, 0, n) {

		if (visited[i] == false)

			all_visited = false;

	}



	if (all_visited)return 1;





	int ret=0;

	rep(i, 0, n) {

		if (visited[i] == true)continue;

		if (graph[v][i] == false)continue;



		visited[i] = true;

		ret += dfs(i,n,visited);

		//次の頂点に移る前にvisitedを初期化

		visited[i] = false;

	}



	return ret;



}





int main(){

	int n, m;

	cin >> n >> m;



	rep(i, 0, m) {

		int a, b;

		cin >> a >> b;

		graph[a - 1][b - 1] = graph[b - 1][a - 1] = true;

	}



	bool visited[8];

	rep(i, 0, n)visited[i] = false;



	visited[0] = true;

	cout << dfs(0, n, visited) << endl;

	return 0;

}
// Slower C++ solution:
#include<iostream>

#include<cstdio>

#include<cstring>

#include <cstdlib>  

#include <cmath>   

#include<cctype>

#include<string>

#include <map>

#include<algorithm>

#include <functional>

#include<vector>

#include<climits>

#include<stack>

#include<queue>

#include <deque>

#include <utility> 



#define rep(i,m,n) for(int i = m;i < n;++i)

using namespace std;

using ll = long long;

using R = double;

const ll inf = 1LL << 50;

const ll MOD = 1e9 + 7;











int main(){

	vector< pair<int, int> > edge;

	

	int n, m;

	cin >> n >> m;



	

	rep(i, 0, m) {

		int a, b;

		cin >> a >> b;

		auto p1 = make_pair(a, b);

		auto p2 = make_pair(b, a);

		edge.push_back(p1);

		edge.push_back(p2);



	}



	vector<int> node;

	rep(i, 1, n + 1) {

		node.push_back(i);

	}





	int ans = 0;

	do {

		int match = 0;

		rep(i, 0, n - 1) {

			int from = node[i];

			int to = node[i + 1];

			for (auto x : edge) {

				if (from == x.first && to == x.second) {

					match++;

				}

			}

		}

		if (match == n - 1 && node[0]==1)ans++;

	} while (next_permutation(node.begin(), node.end()));



	cout << ans << endl;

	









	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.42875553385372x):
#include<iostream>

#include<cstdio>

#include<cstring>

#include <cstdlib>  

#include <cmath>   

#include<cctype>

#include<string>

#include<set>

#include<iomanip>

#include <map>

#include<algorithm>

#include <functional>

#include<vector>

#include<climits>

#include<stack>

#include<queue>

#include <deque>

#include <climits>

#include <typeinfo>

#include <utility> 

#define all(x) (x).begin(),(x).end()

#define rep(i,m,n) for(int i = m;i < n;++i)

#define pb push_back

#define fore(i,a) for(auto &i:a)

#define rrep(i,m,n) for(int i = m;i >= n;--i)

#define INF INT_MAX/2

using namespace std;

using ll = long long;

using R = double;

using Data = pair<ll, vector<int>>;

const ll MOD = 1e9 + 7;

const ll inf = 1LL << 50;

struct edge { ll from; ll to; ll cost; };



vector<int>e[10];

int used[10];

int n, m;



int dfs(int now,int sum) {

	if (sum == n)return 1;

	int ret = 0;

	fore(x,e[now]) {

		if (used[x] == 0) {

			used[x] = 1;

			ret += dfs(x,sum+1);

			used[x] = 0;

		}

	}

	return ret;

}





int main() {

	cin >> n >> m;



	rep(i, 0, m) {

		int a, b;

		cin >> a >> b;

		a--, b--;

		e[a].pb(b);

		e[b].pb(a);

	}



	used[0] = 1;

	cout << dfs(0, 1) << endl;



	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define all(x) (x).begin(),(x).end()

#define rep(i, n) for(ll i = 0; i < n; i++)

const ll INF = 100100100100;





ll combination(ll n, ll r){

    if(n < r) return 0;

    if(r == 0||r == n) return 1;

    else if(r == 1) return n;

    return (combination(n - 1, r - 1) + combination(n - 1, r));

}



bool checkKaibun(string str){

    string checkStr = str;

    reverse(checkStr.begin(), checkStr.end());

    if(str == checkStr) return true;

    else return false;

}



int keta(ll num){

    int digits = 0;

    while(num > 0){

        num /= 10;

        digits++;

    }

    return digits;

}





int main(){

    int N, M;

    cin >> N >> M;

    vector<int> a(2 * M), b(2 * M);

    rep(i, M) cin >> a.at(i) >> b[i];

    rep(i, M) a.at(i + M) = b.at(i);

    rep(i, M) b.at(i + M) = a.at(i);

    vector<int> order(N);

    rep(i, N) order[i] = i + 1;

    int ans = 0;

    do{//すべての周り方を調べて道がつながっているのか調べる。

        bool flag = true;

        rep(i, N - 1){

            auto itr = a.begin();

            while(1){

                itr = find(itr, a.end(), order[i]);

                if(itr == a.end()){

                    flag = false;

                    break;

                }

                int index = itr - a.begin();

                if(b[index] == order[i + 1]){

                    break;

                }

                itr++;

            }

        }

        if(flag == true && order[0] == 1){

            ans++;

        }

    }while(next_permutation(all(order)));

    cout << ans << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.4933521903458828x):
#include<bits/stdc++.h>

#include<unordered_map>

using namespace std;

using Graph = vector<vector<int>>;

#define ll long long

#define all(x) (x).begin(),(x).end()

#define rep(i, n) for(ll i = 0; i < n; i++)

const ll INF = 1LL << 60;



vector<bool> seen;

int ans = 0;



void dfs(Graph &G, int v){

    seen[v] = true;

    int test = 0;

    rep(i, seen.size())if(seen[i] == true) test++;

    if(test == seen.size())ans++;

    for(auto x: G[v]){

        if(seen[x] == true)continue;

        dfs(G, x);

        seen[x] = false;

    }

}



int main(){

    int N, M;

    cin >> N >> M;

    Graph g(N);

    rep(i, M){

        int a, b;

        cin >> a >> b;

        a--;

        b--;

        g[a].push_back(b);

        g[b].push_back(a);

    }

    for(auto x: g[0]){

        seen.assign(N, false);

        seen[0] = true;

        dfs(g, x);

    }

    cout << ans << endl;



}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <algorithm>



using namespace std;



bool check_edge(vector<int> vv, int i, vector<int> e) {

    if(min(vv[i], vv[i+1])==e[0] && max(vv[i], vv[i+1])==e[1]) return true;

    else return false;

}



int main() {

    int N, M;

    cin >> N >> M;

    vector<vector<int> > edge(M, vector<int>(2));

    for(int i=0; i<M; i++) {

        for(int j=0; j<2; j++) {

            cin >> edge[i][j];

        }

    }

    

    vector<int> v(N);

    

    for(int i=0; i<N; i++) {

        v[i] = i+1;

    }



    int ans=0;

    bool flag;



    do {

        if(v[0]!=1) continue;

        for(int j=0; j<N-1; j++) {

            flag=false;

            for(int k=0; k<M; k++) {

                if(check_edge(v, j, edge[k])) {

                    flag=true;

                    break;

                }

            }

            if(flag) continue;

            else break;

        }

        

        if(flag) ans++;



        // for(int i=0; i<N; i++) {

        //     cout << v[i] << " ";

        // }

        // cout << endl;



        

        

    } while(next_permutation(v.begin(), v.end()));



    cout << ans << endl;



    return 0;

    

}

// Faster C++ solution for the same problem (measured speedup: 1.2453979114317264x):
#include <iostream>

#include <vector>

#include <algorithm>



using namespace std;



typedef vector<vector<int> > Graph;

#define rep(i, n) for(int i=0; i<n; i++) 



int main() {

    int N, M;

    cin >> N >> M;

    

    Graph G(N, vector<int>(N, 0));

    rep(i, M) {

        int u, v;

        cin >> u >> v;

        u--;

        v--;

        

        G[u][v] = 1;

        G[v][u] = 1;

    }

    

    int array[N-1];

    rep(i, N-1) {

        array[i] = i+1;

    }



    int ans=0;

    

    do {

        int st = 0;

        bool flag;

        

        rep(i, N-1) {

            flag=false;

            if(G[st][array[i]]) flag=true;

            if(!flag) break;

            st = array[i];

        }

        

        if(flag) ans++;

        

    } while(next_permutation(array, array+N-1));



    cout << ans << endl;



    return 0;

    

}
// Slower C++ solution:
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll big=1e18;

const double PI=2*asin(1);



vector<vector<int> > edge(10);



int main() {

  int N, M;

  cin>>N>>M;

  int a, b;

  for(int i=0;i<M;++i) {

    cin>>a>>b;

    a--;

    b--;

    edge[a].push_back(b);

    edge[b].push_back(a);

  }

  vector<int> node;

  for(int i=0;i<N;++i) node.push_back(i);

  int ans = 0;

  bool can, tmp;

  do {

    if(node[0]!=0) can = false;

    else can = true;

    for(int i=0;i<N-1;++i) {

      tmp = false;

      for(int j=0;j<edge[node[i]].size();++j) {

        if(edge[node[i]][j]==node[i+1]) tmp = true;

      }

      can = min(can, tmp);

    }

    if(can) {

      ans++;

    }

  }while(next_permutation(node.begin(), node.end()));

  cout<<ans<<endl;

}




// Faster C++ solution for the same problem (measured speedup: 1.1415246549766944x):
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



int main() {

  int N, M;

  cin>>N>>M;

  vector<vector<int> > edge(N);

  int a, b;

  for(int i=0;i<M;++i) {

    cin>>a>>b;

    a--;

    b--;

    edge[a].push_back(b);

    edge[b].push_back(a);

  }

  vector<int> arr(N);

  for(int i=0;i<N;++i) arr[i] = i;

  bool can;

  bool tmpcan;

  int ans = 0;

  do {

    if(arr[0]!=0) continue;

    can = true;

    for(int i=0;i<N-1;++i) {

      tmpcan = false;

      for(int j=0;j<edge[arr[i]].size();++j) {

        if(edge[arr[i]][j]==arr[i+1]) tmpcan = true;

      }

      if(!tmpcan) can = false;

    }

    if(can) {

      ans++;

    }

  }while(next_permutation(arr.begin(), arr.end()));

  cout<<ans<<endl;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

#include <string>

using namespace std;



int n,m,ans=0;

bool used[10];

int perm[10],a[50],b[50];



bool che(int x,int y){

    for(int i=0;i<m;i++){

        if(a[i]==x&&b[i]==y)return true;

        if(a[i]==y&&b[i]==x)return true;

    }

    return false;

}



void solve(){

    bool res=true;

    for(int i=0;i<n-1;i++){

        int x=perm[i],y=perm[i+1];

        if(!che(x,y))res=false;

    }

    if(res)ans++;

}



void permutation1(int pos,int n){

    if(pos==n){

        if(perm[0]==1)solve();

        return ;

    }

    

    for(int i=0;i<n;i++){

        if(!used[i]){

            perm[pos]=i+1;

            used[i]=true;

            permutation1(pos+1,n);

            used[i]=false;

        }

    }

    return ;

}



int main(void){

    cin>>n>>m;

    for(int i=0;i<m;i++){

        cin>>a[i]>>b[i];

    }

    permutation1(0,n);

    cout<<ans<<endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.1466857697198871x):
#include <bits/stdc++.h>

#define INF 1e18

#define int long long

#define Rep(i, a, n) for (int i = (a); i < (n); i++)

#define rep(i, n) Rep(i, 0, n)

#define all(a) (a).begin(), (a).end()

using namespace std;

typedef pair<int, int> P;

typedef pair<int, P> PP;

const int mod = 1000000007;



signed main()

{

    ios::sync_with_stdio(false);

    cin.tie(0);



    int n, m;

    cin >> n >> m;

    int e[10][10] = {};

    rep(i, m)

    {

        int a, b;

        cin >> a >> b;

        a--, b--;

        e[a][b] = e[b][a] = 1;

    }

    vector<int> perm(n);

    rep(i, n) perm[i] = i;

    int ans = 0;

    do

    {

        if (perm[0] != 0)

            break;

        bool f = true;

        rep(i, n - 1) if (!e[perm[i]][perm[i + 1]]) f = false;

        if (f)

            ans++;

    } while (next_permutation(all(perm)));

    cout << ans << endl;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



int main()

{

	int n;

	cin>>n;

	if(n%10 == 3) cout<<"bon"<<endl;

	else if(n%10 == 0 || n%10 == 1 || n%10 == 6 || n%10 == 8)

	    cout<<"pon"<<endl;

	else cout<<"hon"<<endl;

	

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.31599776789868x):
#include <stdio.h>

int main()

{

          int x,a;

          scanf("%d",&x);

          a=x%10;

          if (a==2||a==4||a==5||a==7||a==9)

                    printf("hon\n");

          else if(a==0||a==1||a==6||a==8)

                    printf("pon\n");

          else

                    printf("bon\n");

          return 0;

}