Problem:
Score : 300 points

Problem Statement

You are given an undirected unweighted graph with N vertices and M edges that contains neither self-loops nor double edges.

Here, a self-loop is an edge where a_i = b_i (1≤i≤M), and double edges are two edges where (a_i,b_i)=(a_j,b_j) or (a_i,b_i)=(b_j,a_j) (1≤i<j≤M).

How many different paths start from vertex 1 and visit all the vertices exactly once?

Here, the endpoints of a path are considered visited.

For example, let us assume that the following undirected graph shown in Figure 1 is given.

Figure 1: an example of an undirected graph

The following path shown in Figure 2 satisfies the condition.

Figure 2: an example of a path that satisfies the condition

However, the following path shown in Figure 3 does not satisfy the condition, because it does not visit all the vertices.

Figure 3: an example of a path that does not satisfy the condition

Neither the following path shown in Figure 4, because it does not start from vertex 1.

Figure 4: another example of a path that does not satisfy the condition

Constraints

2≦N≦8

0≦M≦N(N-1)/2

1≦a_i<b_i≦N

The given graph contains neither self-loops nor double edges.

Input

The input is given from Standard Input in the following format:

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print the number of the different paths that start from vertex 1 and visit all the vertices exactly once.

Sample Input 1

3 3
1 2
1 3
2 3

Sample Output 1

2

The given graph is shown in the following figure:

The following two paths satisfy the condition:

Sample Input 2

7 7
1 3
2 7
3 4
4 5
4 6
5 6
6 7

Sample Output 2

1

This test case is the same as the one described in the problem statement.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var input = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int N = input[0], M = input[1];
        List<Node> originalNodes = new List<Node>();
        List<Link> originalLinks = new List<Link>();

        for (var i = 0; i < N; i++)
        {
            originalNodes.Add(new Node(i + 1));
        }

        for (var i = 0; i < M; i++)
        {
            var link_a_b = Console.ReadLine().Split().Select(int.Parse).ToArray();
            originalLinks.Add(new Link(new Node(link_a_b[0]), new Node(link_a_b[1])));
        }

        var startNode = new Node(1);
        var graphManager = new GraphManager(new Graph(originalNodes, originalLinks, new List<Node>() { startNode }), startNode, N);

        Console.WriteLine(graphManager.CountPassableAllLinkWithNoDuplication());
    }
}

class GraphManager
{
    public Node CurrentNode { get; private set; }
    public int CountPassTheAllLink { get; private set; }

    public Dictionary<Graph, Node> graphs = new Dictionary<Graph, Node>();
    private readonly int defaultNodesCount;

    public GraphManager(Graph originalGraph, Node firstNode, int defaultNodesCount)
    {
        this.graphs.Add(originalGraph, firstNode);
        this.CountPassTheAllLink = 0;
        this.defaultNodesCount = defaultNodesCount;
    }

    public int CountPassableAllLinkWithNoDuplication()
    {
        var currentGraphs = this.graphs;
        while (currentGraphs.Count != 0)
        {
            var nextGraphs = new Dictionary<Graph, Node>();
            foreach (var graph in currentGraphs)
            {
                var graphs_nodes = MoveNext(graph.Key, graph.Value);
                foreach (var graph_node in graphs_nodes)
                {
                    nextGraphs.Add(graph_node.Key, graph_node.Value);
                }
            }

            currentGraphs = nextGraphs;
        }

        return CountPassTheAllLink;
    }

    public IDictionary<Graph, Node> MoveNext(Graph graph, Node currentNode)
    {
        var result = new Dictionary<Graph, Node>();
        IEnumerable<Link> links = graph.GetPassableLinks(currentNode);
        if (links.Count() == 0)
            return result;

        foreach (Link link in links)
        {
            var nextCurrentNode = link.GetNextNode(currentNode);
            var newGraph = graph.Clone();
            newGraph.RemoveLink(links);
            newGraph.PassNode(nextCurrentNode);
            if (newGraph.PassedNodes.Count() == defaultNodesCount)
                CountPassTheAllLink++;
            result.Add(newGraph, nextCurrentNode);
        }

        return result;
    }


}

class Graph
{
    public IEnumerable<Node> Nodes { get; private set; }
    public IEnumerable<Node> PassedNodes => passedNodes;
    public IEnumerable<Link> Links => links;

    private IList<Node> passedNodes;
    private IList<Link> links;

    public Graph(IEnumerable<Node> nodes, IEnumerable<Link> links, IEnumerable<Node> passedNodes)
    {
        this.Nodes = new List<Node>(nodes);
        this.links = new List<Link>(links);
        this.passedNodes = new List<Node>(passedNodes);
    }

    public IEnumerable<Link> GetPassableLinks(Node node)
    {
        var targetNode = Nodes.Where(n => node.Equals(n)).FirstOrDefault();
        if (targetNode == null)
            return new List<Link>();

        return Links.Where(l => l.IsNodeInLink(node));
    }

    public void RemoveLink(IEnumerable<Link> targetLinks)
    {
        foreach (var targetLink in targetLinks) links.Remove(targetLink);
    }

    public void PassNode(Node node)
    {
        passedNodes.Add(node);
    }

    public Graph Clone()
    {
        return new Graph(this.Nodes, this.Links, this.passedNodes);
    }

    public override string ToString()
    {
        var result = "";
        foreach (var link in Links)
        {
            result += link.ToString() + ',';
        }

        result += passedNodes.Count;
        return result;
    }
}

class Node
{
    public int Number { get; }

    public Node(int number)
    {
        Number = number;
    }

    public override string ToString()
    {
        return this.Number.ToString();
    }

    public override bool Equals(object obj)
    {
        return this.Number == ((Node)obj).Number;
    }
}

class Link
{
    public Node NodeA { get; }
    public Node NodeB { get; }

    public Link(Node nodeA, Node nodeB)
    {
        NodeA = nodeA;
        NodeB = nodeB;
    }

    public Node GetNextNode(Node currentNode)
    {
        if (IsNodeInLink(currentNode) == false)
            throw new Exception("No Next node");
        return this.NodeA.Equals(currentNode) ? this.NodeB : this.NodeA;
    }

    public bool IsNodeInLink(Node node)
    {
        var result = this.NodeA.Equals(node) || this.NodeB.Equals(node);
        return this.NodeA.Equals(node) || this.NodeB.Equals(node);
    }

    public override bool Equals(object obj)
    {
        var other = (Link)obj;
        return (this.NodeA.Equals(other.NodeA) && this.NodeB.Equals(other.NodeB))
            || (this.NodeA.Equals(other.NodeB) && this.NodeB.Equals(other.NodeA));
    }

    public override string ToString()
    {
        return this.NodeA.ToString() + "-" + this.NodeB.ToString();
    }
}