#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <functional>
#include <limits.h>
#include <set>
#include <map>
#include <tuple>
using namespace std;

#include <chrono>

#define ll long long
#define ull unsigned long long
#define rep(i,N) for (ll i=0;i<N;i++)
#define loop(i,N,M) for(ll i=N;i<M;i++)
#define MAX(v) *max_element(v.begin(),v.end())
#define MIN(v) *min_element(v.begin(),v.end())
#define SORTL2S(type,v) sort(v.begin(),v.end(),greater<type>())
#define SORTS2L(type,v) sort(v.begin(),v.end())
#define SORTMF(v,func) sort(v.begin(),v.end(),func)

ll debugFlag = false;
template<typename T> void debug(T&);
template<typename T> void debug(T&, bool);
template<typename T> void debug(vector<T>&);
template<typename T> void debug(vector<T>&, bool);
template<typename T, typename U> void debug(pair<T, U>&);
template<typename T, typename U> void debug(pair<T, U>&, bool);

template<typename T>
void debug(T& obj) {
	debug(obj, true);
}

template<typename T>
void debug(T& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << obj;
	//if (lnFlag) cout << endl;////////////////////////////////////
}

template<typename T>
void debug(vector<T>& obj) {
	debug(obj, true);
}

template<typename T>
void debug(vector<T>& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << "[";
	rep(i, obj.size()) {
		if (i != 0) cout << ",";
		debug(obj[i], true);//////////////////////////////////////
	}
	cout << "]";
	if (lnFlag) cout << endl;
}

template<typename T, typename U>
void debug(pair<T, U>& obj) {
	debug(obj, true);
}

template<typename T, typename U>
void debug(pair<T, U>& obj, bool lnFlag) {
	if (!debugFlag) return;
	cout << "(";
	debug(obj.first, false);
	cout << ",";
	debug(obj.second, false);
	cout << ")";
	if (lnFlag) cout << endl;
}

void solve() {

	ll N, M;
	cin >> N >> M;
	vector<ll> cost(M);

	vector<bool> keycheck(N, false);

	vector<vector<ll>> key(M, vector<ll>());
	rep(i, M) {
		cin >> cost[i];
		ll b;
		cin >> b;
		key[i].resize(b);
		rep(j, b) {
			cin >> key[i][j];
			key[i][j]--;
			keycheck[key[i][j]] = true;
		}
	}

	rep(i, N) {
		if (keycheck[i] == false) {
			cout << -1;
			return;
		}
	}

	vector<vector<ll>> table(1 << N, vector<ll>(M, -1));

	rep(j, M) {
		//j番目の鍵を見たとき，

		rep(i, 1 << N) {
			//状態iであるのは

			//jの鍵を選択せずに，もとから状態iである　のと，
			//jのカバーする要素のうちいくつかが状態iから抜けている状態で鍵jを選択する の
			//いずれか

			//状態iにはならない
			bool flag = false;
			for (auto k : key[j]) {
				if ((1 & i >> k) == 0) flag = true;
			}
			if (flag) {
				table[i][j] = (j==0 ? -1 : table[i][j - 1]);
				continue;
			}

			ll best = -1;
			//もとから状態iである
			if (j != 0) {
				best = table[i][j - 1];
			}

			//不足分を鍵jで補う
			rep(n, 1 << key[j].size()) {
				if (n == 0) continue;

				ll state = i;
				rep(m, key[j].size()) {
					if ((1 & n >> m) == 1) state = state ^ (1 << key[j][m]);
				}

				if (state == 0) best = (best == -1 ? cost[j] : min(best, cost[j]));
				else {
					if (j!=0 && table[state][j - 1] != -1) best = (best == -1 ? table[state][j - 1] + cost[j] : min(best, table[state][j - 1] + cost[j]));
				}
				/*
				if (j != 0 && table[state][j - 1] != -1) {
					if (best == -1) best = table[state][j - 1];
					else best = min(best, table[state][j - 1] + cost[j]);
				}
				else {
					if (best == -1) best = cost[j];
					else best = min(best, cost[j]);
				}
				*/
			}

			table[i][j] = best;
		}

	}

	debug(table);

	cout << table[(1 << N) - 1][M - 1];

}


int main(int argc, char* argv[]) {
	if (argc == 2 && string(argv[1]) == "debug") debugFlag = true;
	solve();
	return 0;
}


Measured memory_bytes: 32512