Problem:
Score : 500 points

Problem Statement

We have N locked treasure boxes, numbered 1 to N.

A shop sells M keys. The i-th key is sold for a_i yen (the currency of Japan), and it can unlock b_i of the boxes: Box c_{i1}, c_{i2}, ..., c_{i{b_i}}. Each key purchased can be used any number of times.

Find the minimum cost required to unlock all the treasure boxes. If it is impossible to unlock all of them, print -1.

Constraints

All values in input are integers.

1 \leq N \leq 12

1 \leq M \leq 10^3

1 \leq a_i \leq 10^5

1 \leq b_i \leq N

1 \leq c_{i1} < c_{i2} < ... < c_{i{b_i}} \leq N

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
c_{11} c_{12} ... c_{1{b_1}}
:
a_M b_M
c_{M1} c_{M2} ... c_{M{b_M}}

Output

Print the minimum cost required to unlock all the treasure boxes.
If it is impossible to unlock all of them, print -1.

Sample Input 1

2 3
10 1
1
15 1
2
30 2
1 2

Sample Output 1

25

We can unlock all the boxes by purchasing the first and second keys, at the cost of 25 yen, which is the minimum cost required.

Sample Input 2

12 1
100000 1
2

Sample Output 2

-1

We cannot unlock all the boxes.

Sample Input 3

4 6
67786 3
1 3 4
3497 1
2
44908 3
2 3 4
2156 3
2 3 4
26230 1
2
86918 1
3

Sample Output 3

69942

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using static System.Console;
using static System.Math;

namespace AtCoder
{
    public class Program
    {
        public static void Main(string[] args)
        {
            new Program().Solve(new ConsoleInput(Console.In, ' '));
        }

        public void Solve(ConsoleInput cin)
        {
            // 解答はココに書く
            var array = cin.ReadIntArray(2);
            var N = array[0];
            var M = array[1];
            for (var i = 0; i < M; i++)
            {
                Key.SetList.Add(new Key(i, N, cin));
            }
            var success = false;
            long minimumCost = -1;
            for (var i = 0; i < M; i++)
            {
                var result = Key.SetList[i].SeekAndSum(new bool[N], new bool[M]);
                if (result.Success)
                {
                    success = true;
                    if (minimumCost == -1) minimumCost = result.Cost;
                    else minimumCost = minimumCost > result.Cost ? result.Cost : minimumCost;
                }
            }
            WriteLine(success ? minimumCost : -1);
        }

        public class Key
        {
            public static List<Key> SetList = new List<Key>();
            public readonly int ID;
            private readonly int N;
            public readonly int Cost;
            public readonly bool[] Set;
            public Key(int id, int N, ConsoleInput cin)
            {
                ID = id;
                this.N = N;
                Set = new bool[N];
                var array = cin.ReadIntArray(2);
                Cost = array[0];
                foreach (var i in cin.ReadIntArray(array[1]))
                {
                    Set[i - 1] = true;
                }
            }

            public Result SeekAndSum(bool[] callerSet, bool[] callerIDs)
            {
                var tarinai = new HashSet<long>();
                for (var i = 0; i < N; i++)
                {
                    callerSet[i] = Set[i] || callerSet[i];
                    if (!callerSet[i]) tarinai.Add(i); 
                }
                callerIDs[ID] = true;
                // 足りない数が無ければ抜ける
                if (!tarinai.Any()) return new Result(true, Cost);
                var success = false;
                long minimumCost = -1;
                for(var i = ID; i < SetList.Count; i++)
                {
                    if (callerIDs[i]) continue;
                    var key = SetList[i];
                    if (!tarinai.Any(t => key.Set[t])) continue;
                    var result
                        = key.SeekAndSum(callerSet.ToArray(), callerIDs.ToArray());
                    if (result.Success)
                    {
                        success = true;
                        if (minimumCost == -1) minimumCost = result.Cost;
                        else minimumCost 
                                = minimumCost > result.Cost ? result.Cost : minimumCost;
                    }
                }
                return success ? new Result(true, minimumCost + Cost) 
                    : new Result(false, 1001);
            }
            public class Result
            {
                public bool Success;
                public long Cost;
                public Result(bool success, long cost)
                {
                    Success = success;
                    Cost = cost;
                }
            }
        }
    }

    public class ConsoleInput
    {
        private readonly System.IO.TextReader _stream;
        private char _separator = ' ';
        private Queue<string> inputStream;
        public ConsoleInput(System.IO.TextReader stream, char separator = ' ')
        {
            this._separator = separator;
            this._stream = stream;
            inputStream = new Queue<string>();
        }
        public string Read
        {
            get
            {
                if (inputStream.Count != 0) return inputStream.Dequeue();
                string[] tmp = _stream.ReadLine().Split(_separator);
                for (int i = 0; i < tmp.Length; ++i)
                    inputStream.Enqueue(tmp[i]);
                return inputStream.Dequeue();
            }
        }
        public string ReadLine { get { return _stream.ReadLine(); } }
        public int ReadInt { get { return int.Parse(Read); } }
        public long ReadLong { get { return long.Parse(Read); } }
        public double ReadDouble { get { return double.Parse(Read); } }
        public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret; }
        public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret; }
        public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret; }
    }
}