#include <bits/stdc++.h>
#pragma GCC optimize("O2")
using namespace std;
const int MAXN = 6e5 + 10;
const long long MOD = 1e9 + 7;
const long long MOD2 = 998244353;
const long long INF = 8e18;
const int LOG = 21;
long long pw(long long a, long long b, long long mod) {
  return (!b ? 1
             : (b & 1 ? (a * pw(a * a % mod, b / 2, mod)) % mod
                      : pw(a * a % mod, b / 2, mod)));
}
int M[LOG + 1][LOG + 1];
long long dp[MAXN][LOG];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    M[b][a] = M[a][b] = 1;
  }
  for (int i = 0; i < n; i++) {
    dp[1 << i][i] = 1;
  }
  long long ans = 0;
  for (int mask = 0; mask < (1 << n); mask++) {
    int f = __builtin_ctz(mask);
    int t = __builtin_popcount(mask);
    if (f == 32) f = 0;
    for (int i = 0; i < n; i++) {
      if (dp[mask][i] == 0) continue;
      if (t >= 3 && M[i][f]) {
        ans += dp[mask][i];
      }
      for (int j = 0; j < n; j++) {
        if (j > f && !((mask >> j) & 1) && M[i][j]) {
          dp[mask | (1 << j)][j] += dp[mask][i];
        }
      }
    }
  }
  cout << ans / 2;
  return 0;
}
