source_code: import java.io.*;
  import java.util.*;
  public class D11 {
  	static HashMap<State, Integer> map;
  	static long[][] ans;
  	static boolean[][] connect;
  	public static void main(String[] args) throws IOException {
  		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  		StringTokenizer st = new StringTokenizer(br.readLine());
  		int n = Integer.parseInt(st.nextToken());
  		map = new HashMap<State, Integer>();
  		connect = new boolean[n][n];
  		ans = new long[n][1<<n];
  		for(int i = 0; i < n; i++)
  			Arrays.fill(ans[i], -1);
  		int m = Integer.parseInt(st.nextToken());
  		while(m-- > 0)	{
  			st = new StringTokenizer(br.readLine());
  			int a = Integer.parseInt(st.nextToken());
  			int b = Integer.parseInt(st.nextToken());
  			a--;
  			b--;
  			connect[a][b] = connect[b][a] = true;
  		}
  		long ret = 0;
  		int mask = 1 << n;
  		mask--;
  		for(int i = 0; i < n; i++)	{
  			for(int out = i+1; out < n; out++)	{
  				if(connect[i][out])	{
  					ret += solve(mask - (1<<out), out, true);
  				}
  			}
  			mask -= (1<<i);
  		}
  		System.out.println(ret/2);
  	}
  	public static long solve(int mask, int start, boolean a)	{
  		if(ans[start][mask] != -1)
  			return ans[start][mask];
  		int end = 0;
  		while((mask & (1<<end)) == 0)
  			end++;
  		long ret = 0;
  		for(int out = 0; out < connect.length; out++)	{
  			if(connect[start][out] && (mask & (1 << out)) != 0)	{
  				if(out == end)	{
  					if(!a)
  						ret++;
  				}
  				else
  					ret += solve(mask - (1<<out), out, false);
  			}
  		}
  		ans[start][mask] = ret;
  		return ret;
  	}
  	static class State	{
  		public byte start, go;
  		public int mask;
  		public State(byte a, byte b, int c)	{
  			start = a;
  			go = b;
  			mask = c;
  		}
  		public int hashCode()	{
  			return 10007*mask + 43 * start + go;
  		}
  		public boolean equals(Object o)	{
  			State s = (State)o;
  			return start == s.start && go == s.go && mask == s.mask;
  		}
  	}
  }
  