import std.stdio;
import std.conv, std.array, std.algorithm, std.string;
import std.math, std.random, std.range, std.datetime;
import std.bigint;

bool[long] kset;

void main(){
	int n, m;
	{
		int[] tmp = readln.chomp.split.map!(to!int).array;
		n = tmp[0], m = tmp[1];
		}
	
	for(int j = 0; j < m; j ++){
		int[] tmp = readln.chomp.split.map!(to!int)
				.map!(x => x - 1).array;
		kset[tmp[0] * 8 + tmp[1]] = 1;
		kset[tmp[1] * 8 + tmp[0]] = 1;
		}
	
	debug kset.writeln;
	
	int[][] routes = getRoutes([], 0, n, n);
	int count = 0;
	foreach(r; routes) if(r.isValid) count += 1;
	
	debug routes.writeln;
	
	count.writeln;
	}

int[][] getRoutes(int[] r, int m, int n, int k){ // 0からn-1まで、あとk個、使用済r、使用済マップm、
	int[][] res;
	if(k == 0) return [r];
	for(int i = 0; i < n; i ++){
		if(!((2 ^^ i) & m)){
			res ~= getRoutes(r ~ i, (2 ^^ i) | m, n, k - 1);
			}
		}
	return res;
	}

bool isValid(int[] r){
	if(!r.length) return 0;
	if(r[0] != 0) return 0;
	for(int i = 0; i < r.length - 1; i ++){
		if(r[i] * 8 + r[i + 1] !in kset) return 0;
		}
	debug r.writeln;
	return 1;
	}