#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
/*
对深搜的感悟,深搜一般先找的结果在回溯回来, 更多的是递归。
广搜是解决最短路的首选方法, 如果不能用广搜, 深搜也可以。
但是,要对找的结果进行筛选, 得到你想要的结果。
当进行试探性的扩展时, 不能用if(dfs()) return true;
这种条件只能得到一组解, 之后程序会结束搜索,
对于求多组中找最恰当的一条 用 dfs()不加判断条件,
当找的一组解时,只用结束当前递归 return 而不会影响,搜索下面一组解。
*/
using namespace std;
struct node {
int b;
int c;
int p;
int r;
node (int bb, int cc, int pp, int rr): b(bb), c(cc), p(pp), r(rr){}
};
vector<node>que[12];
int n, m;
int vist[15];
int ans;
void dfs(int k, int bsum) {
if(k == n && bsum < ans) {
ans = bsum;
return ; //在这里象征性的结束程序,
}
for(int i = 0; i < (int)que[k].size(); i++) {
node cur = que[k][i];
if(vist[cur.b] < 3) {
vist[cur.b]++;
if(vist[cur.c]) {
dfs(cur.b, bsum + cur.p); //不需要判断后面的递归是否成立。
}
else
dfs(cur.b, bsum + cur.r); //同上。
vist[cur.b]--; //把改变的状态还原。
}
}
return;
}
int main()
{
int a, b, c, d, e;
while(scanf("%d%d", &n, &m) != EOF) {
for(int i = 0; i <= n; i++)
que[i].clear();
for(int i = 1; i <= m; i++) {
scanf("%d%d%d%d%d", &a, &b, &c, &d,&e);
que[a].push_back(node(b, c, d, e));
}
memset(vist, 0, sizeof(vist));
vist[1] = 1;
ans = 3000;
dfs(1, 0);
if(ans != 3000)
printf("%d\n", ans);
else
printf("impossible\n");
}
return 0;
}