#include <algorithm>
#include <bits/stdc++.h>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <queue>
#include <type_traits>
#include <vector>

// lib/pow2.hpp
#ifndef POW2_HPP
#define POW2_HPP

/*
usage:

tools::pow2(5) => 32
*/


namespace tools {
  template <typename T, typename std::enable_if<std::is_unsigned<T>::value, std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(1) << x;
  }

  template <typename T, typename std::enable_if<std::is_signed<T>::value, std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(static_cast<typename std::make_unsigned<T>::type>(1) << static_cast<typename std::make_unsigned<T>::type>(x));
  }
}

#endif

// lib/util.hpp
#ifndef UTIL_HPP
#define UTIL_HPP


typedef ::std::int_fast64_t i64;
typedef ::std::uint_fast64_t u64;
typedef ::std::int_fast32_t i32;
typedef ::std::uint_fast32_t u32;

namespace tools {
  template <typename T>
  void read(::std::istream& is, ::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    vector.reserve(size);
    ::std::copy_n(::std::istream_iterator<T>(is), size, ::std::back_inserter(vector));
  }
  template <typename T>
  void read(::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    ::tools::read(::std::cin, vector, size);
  }

  template <typename T, ::std::size_t N>
  void read(::std::istream& is, ::std::array<T, N>& array) {
    ::std::copy_n(std::istream_iterator<T>(is), N, array.begin());
  }
  template <typename T, ::std::size_t N>
  void read(::std::array<T, N>& array) {
    ::tools::read(::std::cin, array);
  }
}

#endif

// lib/dijkstra.hpp
#ifndef DIJKSTRA_HPP
#define DIJKSTRA_HPP


/*
usage:

tools::dijkstra<std::int_fast64_t> dijkstra(node_count);
dijkstra.add_edge(from_node, to_node, cost);
const tools::dijkstra<std::int_fast64_t>::result result = dijkstra.calc(start_node);
for (const std::int_fast64_t& distance : result.distances) {
  // ...
}
*/

namespace tools {
  template <typename T>
  class dijkstra {
  private:
    class edge {
    public:
      std::size_t from;
      std::size_t to;
      T distance;
      edge(const std::size_t from, const std::size_t to, const T distance) :
        from(from),
        to(to),
        distance(distance) {
      }
    };

    class task {
    public:
      std::size_t vertex;
      T distance;
      task(const std::size_t vertex, const std::size_t distance) :
        vertex(vertex), distance(distance) {
      }
    };

    std::vector<std::vector<edge>> edges;

  public:
    static constexpr T INF = std::numeric_limits<T>::max();
    static constexpr std::size_t NONE = std::numeric_limits<std::size_t>::max();

    class result {
    public:
      std::vector<T> distances;
      std::vector<std::size_t> prev_nodes;
      result(const std::size_t node_count, const std::size_t start_node) :
        distances(node_count, INF),
        prev_nodes(node_count, NONE) {
        this->distances[start_node] = 0;
      }
    };

    dijkstra(const std::size_t node_count) :
      edges(node_count) {
    }

    std::size_t node_count() const {
      return this->edges.size();
    }

    void add_edge(const std::size_t from, const std::size_t to, const T distance) {
      this->edges[from].emplace_back(from, to, distance);
    }

    result calc(const std::size_t start_node) const {
      assert(start_node < this->node_count());

      result result(this->node_count(), start_node);
      std::vector<bool> visited(this->node_count(), false);
      std::priority_queue<task, std::vector<task>, std::function<bool(task, task)>> tasks([](const task& x, const task& y) {
        return x.distance > y.distance;
      });
      tasks.emplace(start_node, 0);

      while (!tasks.empty()) {
        const task task = tasks.top();
        tasks.pop();
        if (visited[task.vertex]) continue;
        visited[task.vertex] = true;
        for (const edge& edge : this->edges[task.vertex]) {
          const T new_distance = task.distance + edge.distance;
          if (new_distance < result.distances[edge.to]) {
            result.distances[edge.to] = new_distance;
            result.prev_nodes[edge.to] = edge.from;
            tasks.emplace(edge.to, new_distance);
          }
        }
      }

      return result;
    }
  };
}

#endif

// main.cpp

namespace std {
  template <>
  struct hash<std::pair<u32, u32>> {
    static std::size_t seed;
    static constexpr std::hash<u32> hasher = std::hash<u32>();
    typedef std::size_t result_type;
    typedef std::pair<u32, u32> argument_type;
    std::size_t operator()(const std::pair<u32, u32>& key) const {
      std::size_t hash1 = hasher(key.first);
      std::size_t hash2 = hasher(key.second);
      std::size_t result = 0;
      result ^= hash1 + static_cast<u32>(0x9e3779b9) + (result << static_cast<u32>(6)) + (result >> static_cast<u32>(2));
      result ^= hash2 + static_cast<u32>(0x9e3779b9) + (result << static_cast<u32>(6)) + (result >> static_cast<u32>(2));
      result ^= seed + static_cast<u32>(0x9e3779b9) + (result << static_cast<u32>(6)) + (result >> static_cast<u32>(2));
      return result;
    }
  };
}
std::size_t std::hash<std::pair<u32, u32>>::seed = static_cast<std::size_t>(std::random_device()());

class key {
  i64 m_price;
  u32 m_mask;

public:
  key(const i64& price, const u32& mask) :
    m_price(price), m_mask(mask) {
  }

  i64 price() const {
    return this->m_price;
  }
  u32 mask() const {
    return this->m_mask;
  }
};

int main() {
  u32 N;
  i64 M;
  std::cin >> N >> M;
  std::vector<key> keys;
  keys.reserve(M);
  for (i64 i = 0; i < M; ++i) {
    i64 a_i, b_i;
    std::cin >> a_i >> b_i;
    std::vector<u32> treasures;
    tools::read(treasures, b_i);
    u32 mask = 0;
    for (const u32& treasure : treasures) {
      mask |= static_cast<u32>(1) << (treasure - static_cast<u32>(1));
    }
    keys.emplace_back(a_i, mask);
  }

  std::unordered_map<std::pair<u32, u32>, i64> edges;
  edges.reserve(tools::pow2(2 * N));
  for (u32 from = 0; from < tools::pow2(N); ++from) {
    for (const key& key : keys) {
      const u32 to = from | key.mask();
      if (from == to) continue;
      const std::pair<u32, u32> edge = std::make_pair(from, to);
      auto it = edges.find(edge);
      if (it == edges.end()) {
        edges.emplace(edge, key.price());
      } else {
        it->second = std::min(it->second, key.price());
      }
    }
  }

  tools::dijkstra<i64> dijkstra(tools::pow2(N));
  for (const std::pair<std::pair<u32, u32>, i64>& pair : edges) {
    dijkstra.add_edge(pair.first.first, pair.first.second, pair.second);
  }
  const auto result = dijkstra.calc(0);

  if (result.distances.back() == std::numeric_limits<i64>::max()) {
    std::cout << -1 << std::endl;
  } else {
    std::cout << result.distances.back() << std::endl;
  }
  return 0;
}

Measured memory_bytes: 171904