#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#define MAX_N ((1 << 20) + 10)
#define INF 1e15
struct edge {
int to;
long long cost;
edge (int tt, long long cc) : to(tt), cost(cc) {}
edge () {}/*定义函数的作用?*/
};
std::vector<edge> G[MAX_N];/*结构体类型的vector中所储存了边的终点(序号)和权值大小 */
int n, m;
char str[23];
int tran() {
int res = 0;
int l = strlen(str);
for (int i = 0; i < l; i++)
res = res * 2 + str[i] - '0';
return res; /*位移运算*/
}
bool inQue[MAX_N]; /*定义队列数组*/
long long dis[MAX_N]; /*储存顶标值的数组*/
std::queue<int>qwe;
long long spfa(int s,int e)
{
for(int i=0;i<MAX_N;i++){
dis[i]=INF;
}
dis[s]=0;
qwe.push(s);
inQue[s]=1;
while(qwe.size()){
int u=qwe.front();
qwe.pop();
inQue[u]=0;
for(int i=0;i<G[u].size();i++){
if(G[u][i].cost+dis[u]<dis[G[u][i].to])
{
dis[G[u][i].to]=G[u][i].cost+dis[u];
if(!inQue[G[u][i].to])
{
qwe.push(G[u][i].to);
inQue[G[u][i].to]=1;
}
}
}
}
return dis[e];
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
scanf("%s", str);
int s = tran();
scanf("%s", str);
int w = tran();
long long t;
scanf("%lld", &t);
G[s].push_back(edge(w, t));
}
long long ans=spfa(0,(1<<n)-1);/*位移运算*/
if(ans==INF)
printf("-1\n");
else
printf("%lld\n",ans);
return 0;
}