import std.stdio, std.conv, std.array, std.string;
import std.algorithm;
import std.container;
import std.range;
import std.bitmanip;
import std.math;
import std.regex;

struct Key {
  public int price;
  public BitArray canOpen;

  this(int price, int[] boxNumbers, int maxBoxSize) {
    this.price = price;
    this.canOpen = BitArray(maxBoxSize.iota.map!(i => boxNumbers.canFind(i+1)).array);
  }
}

class State {
  public int cost;
  public Key[] restKeys;

  this(int cost, Key[] restKeys) {
    this.cost = cost;
    this.restKeys = restKeys;
  }

  public State purchase(Key key) {
    auto keys = this.restKeys.dup;
    keys.remove!(a => a == key);
    return new State(cost + key.price, keys);
  }

  public override string toString() {
    return cost.to!string;
  }
}

void main() {
  int N, M; readf("%d %d\n", &N, &M);
  Key[] keys;
  foreach(z; 0..M) {
    int price, canOpenCount; readf("%d %d\n", &price, &canOpenCount);
    keys ~= Key(price, readln.split.to!(int[]), N);
  }
  
  State[BitArray] dp;
  BitArray[] updated = [BitArray(false.repeat(N).array)];
  dp[updated[0]] = new State(0, keys);

  while(true) {
    BitArray[] nextUpdated;
    foreach(current; updated) {
      foreach(key; dp[current].restKeys) {
        auto next = current | key.canOpen;
        if (next == current) continue;

        auto purchased = dp[current].purchase(key);
        if (next in dp && dp[next].cost <= purchased.cost) continue;

        dp[next] = purchased;
        nextUpdated ~= next;
      }
    }
    debug nextUpdated.writeln;
    debug dp.writeln;
    if (nextUpdated.empty) break;
    updated = nextUpdated;
  }

  auto allOpened = BitArray(true.repeat(N).array);
  writeln(allOpened in dp ? dp[allOpened].cost.to!string : "-1");
}