import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

import javax.sound.midi.Synthesizer;


public class Main {
	

	static int V;
	static ArrayList<Integer> adjList [];
	
	static int first(int a){
	    int idx = 0;
	    while (a > 0 && (a & 1) == 0) {
	        idx++;
	        a>>=1;
	    }
	    return idx;
	}
	static long Number_Of_Simple_Cycles () { // Time Complexity O(2 ^ n  * n ^ 2)
		long dp [][] = new long[1 << V][V];
		
		for (int i = 0 ; i < V ; ++i)
			dp[1 << i][i] = 1;
		
		for (int mask = 1 ; mask < 1 << V ; ++mask) {
				if (Integer.bitCount(mask) <= 1) continue;
				for (int current = 0 ; current < V ; ++current) {
					if (((1 << current) & mask) == 0) continue;
					
					for (int last : adjList[current])
						if (current != first(mask))
							{
								dp[mask][current] += dp[mask ^ (1 << current)][last];
							}
				}
		}
		
		long ans = 0 ;
		int allVisited = (1 << V) - 1;
		for (int mask = 1 ; mask < 1 << V ; ++mask) {
			if (Integer.bitCount(mask) < 3) continue;
			for (int u = 0 ; u < V ; ++u) {
				if (adjList[u].contains(first (mask)))
					ans += dp[mask][u];
			}
		}
		return ans >> 1;
	}
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		StringBuilder sb = new StringBuilder();
		PrintWriter out = new PrintWriter(System.out);
		V = sc.nextInt();
		adjList = new ArrayList[V];
		for (int i = 0 ; i < V ; ++i) adjList[i] = new ArrayList<>();
		int E = sc.nextInt();
		while (E -- > 0) {
			int v = sc.nextInt() - 1;
			int u = sc.nextInt() - 1;
			adjList[v].add(u);
			adjList[u].add(v);
		}
		out.print(Number_Of_Simple_Cycles());
		out.flush(); 
		out.close();
	}

	

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}
}