source_code: import java.util.*;
  import java.io.*;
  public class ASimpleTask
  {
  
  
  	/************************ SOLUTION STARTS HERE ***********************/
  
  
  
  	private static void solve(FastScanner s1, PrintWriter out){
  
  		int V = s1.nextInt();
  		int E = s1.nextInt();
  		int graph[] = new int[V];
  		long DP[][] = new long[1 << V][V];
  
  		while(E-->0) {
  			int u = s1.nextInt() - 1;
  			int v = s1.nextInt() - 1;
  			graph[u] |= (1 << v);
  			graph[v] |= (1 << u);
  		}
  
  		for(int i=0;i<V;i++)
  			DP[1 << i][i] = 1;
  
  		for(int mask = 1 , end = 1 << V;mask < end;mask++) {
  			for(int set = mask;Integer.bitCount(set) > 1;set ^= Integer.highestOneBit(set)) {
  				int u = Integer.numberOfTrailingZeros(Integer.highestOneBit(set));
  				for(int fromSet = mask ^ (1 << u);fromSet > 0; fromSet ^= Integer.lowestOneBit(fromSet)) {
  					int v = Integer.numberOfTrailingZeros(fromSet);
  					// System.out.printf("mask = %s , u = %d , v = %d\n" , Integer.toBinaryString(mask) , u , v);
  					if((graph[u] & (1 << v)) != 0) 
  						DP[mask][u] += DP[mask ^ (1 << u)][v];
  					
  				}
  			}
  		}
  
  		long totalCycles = 0;
  		for(int mask = 1 , end = 1 << V;mask < end;mask++) {
  			if(Integer.bitCount(mask) >= 3) {
  				int start = Integer.numberOfTrailingZeros(mask);
  				for(int set = mask;Integer.bitCount(set) > 1;set ^= Integer.highestOneBit(set)) {
  					int u = Integer.numberOfTrailingZeros(Integer.highestOneBit(set));
  					if((graph[u] & (1 << start)) != 0)
  						totalCycles += DP[mask][u];
  				}
  			}
  		}
  
  		totalCycles /= 2;
  /*		for(long l[] : DP)
  			out.println(Arrays.toString(l));*/
  		out.println(totalCycles);
  	}
  
  
  
  	/************************ SOLUTION ENDS HERE ************************/
  
  
  
  
  
  	/************************ TEMPLATE STARTS HERE *********************/
  
  	public static void main(String []args) throws IOException {
  		FastScanner in  = new FastScanner(System.in);
  		PrintWriter out = 
  				new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), false); 
  		solve(in, out);
  		in.close();
  		out.close();
  	}    
  
  	static class FastScanner{
  		BufferedReader reader;
  		StringTokenizer st;
  		FastScanner(InputStream stream){reader=new BufferedReader(new InputStreamReader(stream));st=null;}	
  		String next()
  		{while(st == null || !st.hasMoreTokens()){try{String line = reader.readLine();if(line == null){return null;}		    
  		st = new StringTokenizer(line);}catch (Exception e){throw new RuntimeException();}}return st.nextToken();}
  		String nextLine()  {String s=null;try{s=reader.readLine();}catch(IOException e){e.printStackTrace();}return s;}	    	  	
  		int    nextInt()   {return Integer.parseInt(next());}
  		long   nextLong()  {return Long.parseLong(next());}		
  		double nextDouble(){return Double.parseDouble(next());}
  		char   nextChar()  {return next().charAt(0);}
  		int[]  nextIntArray(int n)         {int[] a= new int[n];   int i=0;while(i<n){a[i++]=nextInt();}  return a;}
  		long[] nextLongArray(int n)        {long[]a= new long[n];  int i=0;while(i<n){a[i++]=nextLong();} return a;}	
  		int[]  nextIntArrayOneBased(int n) {int[] a= new int[n+1]; int i=1;while(i<=n){a[i++]=nextInt();} return a;}	    	
  		long[] nextLongArrayOneBased(int n){long[]a= new long[n+1];int i=1;while(i<=n){a[i++]=nextLong();}return a;}	    	
  		void   close(){try{reader.close();}catch(IOException e){e.printStackTrace();}}				
  	}
  
  	/************************ TEMPLATE ENDS HERE ************************/
  }