#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<bitset>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
const int mod = 1000000007;
const int Mod = 1000;
const int N = 155;

struct node
{
	int u, v;
	long long val;
	bool operator<(node&tmp)const {
		return val<tmp.val;
	}
}ed[210];

int n, m;

int dp[N][N];
bitset<N> arr[N], ma[N];

void mul(bitset<N> a[], bitset<N> b[])
{
	bitset<N> res[N];
	int i, j;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (a[i][j])
				res[i] |= b[j];
		}
	}
	for (i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

void QP(bitset<N> *a, int k) {
	bitset<N> res[N];
	int i, j;
	for (int i = 1; i <= n; i++)
	{
		res[i][i] = 1;
	}
	while (k) {
		if (k & 1) mul(res, a);
		k >>= 1;
		mul(a, a);
	}
	for (int i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

int main()
{
	int i, j, k;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (i = 1; i <= m; i++)
		{
			scanf("%d%d%lld", &ed[i].u, &ed[i].v, &ed[i].val);
		}
		std::sort(ed + 1, ed + 1 + m);
		memset(dp, 0x3f, sizeof(dp));
		for (i = 1; i <= n; i++)
		{
			dp[i][i] = 0;
			arr[i][i] = 1;

		}
		bitset<N> tmp[N];
		int ans = mod+200;
		int now = 0;
		for (i = 1; i <= m; i++)
		{
			int u = ed[i].u;
			int v = ed[i].v;
			int val = ed[i].val;
			for (j = 1; j <= n; j++)
			{
				for (k = 1; k <= n; k++)
				{
					dp[j][k] = min(dp[j][k], dp[j][u] + 1 + dp[v][k]);
				}
			}

			for (j = 1; j <= n; j++)
			{
				tmp[j] = ma[j];
			}
			QP(tmp, val - now);
			mul(arr, tmp);
			for (j = 1; j <= n; j++)
			{
				if (arr[1][j] && dp[j][n] != 1061109567)
				{
					ans = min(ans, val + dp[j][n]);
				}
			}
			now = val;
			ma[u][v] = 1;
		}

		if (ans == mod) printf("Impossible\n");
		else printf("%d\n", ans);
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<bitset>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
const int mod = 1000000007;
const int Mod = 1000;
const int N = 155;

struct node
{
	int u, v;
	long long val;
	bool operator<(node&tmp)const {
		return val<tmp.val;
	}
}ed[210];

int n, m;

int dp[N][N];
bitset<N> arr[N], ma[N];

void mul(bitset<N> a[], bitset<N> b[])
{
	bitset<N> res[N];
	int i, j;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (a[i][j])
				res[i] |= b[j];
		}
	}
	for (i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

void QP(bitset<N> *a, int k) {
	bitset<N> res[N];
	int i, j;
	for (int i = 1; i <= n; i++)
	{
		res[i][i] = 1;
	}
	while (k) {
		if (k & 1) mul(res, a);
		k >>= 1;
		mul(a, a);
	}
	for (int i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

int main()
{
	int i, j, k;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (i = 1; i <= m; i++)
		{
			scanf("%d%d%lld", &ed[i].u, &ed[i].v, &ed[i].val);
		}
		std::sort(ed + 1, ed + 1 + m);
		memset(dp, 0x3f, sizeof(dp));
		for (i = 1; i <= n; i++)
		{
			dp[i][i] = 0;
			arr[i][i] = 1;

		}
		bitset<N> tmp[N];
		int ans = mod+200;
		int now = 0;
		for (i = 1; i <= m; i++)
		{
			int u = ed[i].u;
			int v = ed[i].v;
			int val = ed[i].val;
			for (j = 1; j <= n; j++)
			{
				for (k = 1; k <= n; k++)
				{
					dp[j][k] = min(dp[j][k], dp[j][u] + 1 + dp[v][k]);
				}
			}

			for (j = 1; j <= n; j++)
			{
				tmp[j] = ma[j];
			}
			QP(tmp, val - now);
			mul(arr, tmp);
			for (j = 1; j <= n; j++)
			{
				if (arr[1][j] && dp[j][n] != 1061109567)
				{
					ans = min(ans, val + dp[j][n]);
				}
			}
			now = val;
			ma[u][v] = 1;
		}

		if (ans == mod+200) printf("Impossible\n");
		else printf("%d\n", ans);
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<bitset>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
const int mod = 1000000007;
const int Mod = 1000;
const int N = 155;

struct node
{
	int u, v;
	long long val;
	bool operator<(node&tmp)const {
		return val<tmp.val;
	}
}ed[210];

int n, m;

int dp[N][N];
bitset<N> arr[N], ma[N];

void mul(bitset<N> a[], bitset<N> b[])
{
	bitset<N> res[N];
	int i, j;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (a[i][j])
				res[i] |= b[j];
		}
	}
	for (i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

void QP(bitset<N> *a, int k) {
	bitset<N> res[N];
	int i, j, k;
	for (int i = 1; i <= n; i++)
	{
		res[i][i] = 1;
	}
	while (k) {
		if (k & 1) mul(res, a);
		k >>= 1;
		mul(a, a);
	}
	for (int i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

int main()
{
	int i, j, k;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (i = 1; i <= m; i++)
		{
			scanf("%d%d%lld", &ed[i].u, &ed[i].v, &ed[i].val);
		}
		std::sort(ed + 1, ed + 1 + m);
		memset(dp, 0x3f, sizeof(dp));
		for (i = 1; i <= n; i++)
		{
			dp[i][i] = 0;
			arr[i][i] = 1;

		}
		bitset<N> tmp[N];
		int ans = mod+200;
		int now = 0;
		for (i = 1; i <= m; i++)
		{
			int u = ed[i].u;
			int v = ed[i].v;
			int val = ed[i].val;
			for (j = 1; j <= n; j++)
			{
				for (k = 1; k <= n; k++)
				{
					dp[j][k] = min(dp[j][k], dp[j][u] + 1 + dp[v][k]);
				}
			}

			for (j = 1; j <= n; j++)
			{
				tmp[j] = ma[j];
			}
			QP(tmp, val - now);
			mul(arr, tmp);
			for (j = 1; j <= n; j++)
			{
				if (arr[1][j] && dp[j][n] != 1061109567)
				{
					ans = min(ans, val + dp[j][n]);
				}
			}
			now = val;
			ma[u][v] = 1;
		}

		if (ans == mod) printf("Impossible\n");
		else printf("%d\n", ans);
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<bitset>
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
const int mod = 1000000007;
const int Mod = 1000;
const int N = 155;

struct node
{
	int u, v;
	long long val;
	bool operator<(node&tmp)const {
		return val<tmp.val;
	}
}ed[210];

int n, m;

int dp[N][N];
bitset<N> arr[N], ma[N];

void mul(bitset<N> a[], bitset<N> b[])
{
	bitset<N> res[N];
	int i, j;
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (a[i][j])
				res[i] |= b[j];
		}
	}
	for (i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

void QP(bitset<N> *a, int k) {
	bitset<N> res[N];
	int i, j;
	for (int i = 1; i <= n; i++)
	{
		res[i][i] = 1;
	}
	while (k) {
		if (k & 1) mul(res, a);
		k >>= 1;
		mul(a, a);
	}
	for (int i = 1; i <= n; i++)
	{
		a[i] = res[i];
	}
}

int main()
{
	int i, j, k;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		for (i = 1; i <= m; i++)
		{
			scanf("%d%d%lld", &ed[i].u, &ed[i].v, &ed[i].val);
		}
		std::sort(ed + 1, ed + 1 + m);
		memset(dp, 0x3f, sizeof(dp));
		for (i = 1; i <= n; i++)
		{
			dp[i][i] = 0;
			arr[i][i] = 1;

		}
		bitset<N> tmp[N];
		int ans = mod;
		int now = 0;
		for (i = 1; i <= m; i++)
		{
			int u = ed[i].u;
			int v = ed[i].v;
			int val = ed[i].val;
			for (j = 1; j <= n; j++)
			{
				for (k = 1; k <= n; k++)
				{
					dp[j][k] = min(dp[j][k], dp[j][u] + 1 + dp[v][k]);
				}
			}

			for (j = 1; j <= n; j++)
			{
				tmp[j] = ma[j];
			}
			QP(tmp, val - now);
			mul(arr, tmp);
			for (j = 1; j <= n; j++)
			{
				if (arr[1][j] && dp[j][n] != 1061109567)
				{
					ans = min(ans, val + dp[j][n]);
				}
			}
			now = val;
			ma[u][v] = 1;
		}

		if (ans == mod) printf("Impossible\n");
		else printf("%d\n", ans);
	}
	return 0;
}


#include<bits/stdc++.h>

#define ll long long
#define pb push_back
#define mp make_pair
#define ld long double
#define F first
#define S second
#define pii pair<ll,ll>

using namespace :: std;

const ll maxn=152;
const ll mod=1e9+7;
const ll inf=2e9+500;

vector<pair<ll,pii> > vyal;

struct matric{
	bitset<maxn> v[maxn];
};

matric hamani;
matric sefr;

matric operator * (const matric &a,const matric &b){
	matric bt;
	for(ll i=0;i<maxn;i++){
		for(ll j=0;j<maxn;j++){
				bt.v[i][j]=b.v[j][i];
		}
	}
	matric ans;
	for(ll i=0;i<maxn;i++){
		for(ll j=0;j<maxn;j++){
			if(((a.v[i])&(bt.v[j]))==0){
				ans.v[i][j]=0;
			}else{
				ans.v[i][j]=1;
			}
		}
	}
	return ans;
}
matric operator ^ ( matric base,ll t){
	matric ans=hamani;
	while(t>0){
		if(t&1){
			ans=(ans*base);
		}
		t=(t/2);
		base=(base*base);
	}
	return ans;
}

matric yal;
matric yall;
matric av;

matric pri[40];

int main(){
	for(ll i=0;i<maxn;i++){
		sefr.v[i]=0;
	}
	hamani=sefr;
	for(ll i=0;i<maxn;i++){
		hamani.v[i][i]=1;
	}

	yal=sefr;
	yall=hamani;
	av=sefr;
	av.v[0][0]=1;

	ll n,m;
	cin>>n>>m;
	for(ll i=0;i<m;i++){
		ll a,b,w;
		cin>>a>>b>>w;
		a--;
		b--;
		vyal.pb(mp(w,mp(a,b)));
	}
	vyal.pb(mp(inf,mp(0,1)));
	sort(vyal.begin(),vyal.end());
	if(vyal[0].F!=0){
		cout<<"Impossible";
		return 0;
	}
	matric dd;
	for(ll i=0;i<(ll)vyal.size();i++){
		ll a=vyal[i].S.F;
		ll b=vyal[i].S.S;
		if(i==0 || vyal[i].F==vyal[i-1].F){
			yal.v[a][b]=1;
			yall.v[a][b]=1;
		}else{
			ll fas=vyal[i].F-vyal[i-1].F;
			dd=(av*(yall^fas));
			if(dd.v[0][n-1]){
				ll t=0;
				pri[0]=yall;
				for(ll j=1;j<40;j++){
					pri[j]=(pri[j-1]*pri[j-1]);
				}
				for(ll j=39;j>=0;j--){
					dd=av*pri[j];
					if(!dd.v[0][n-1]){
						av=dd;
						t+=(1<<j);
					}
				}
				cout<<1+t+vyal[i-1].F;
				return 0;
			}else{
				av=(av*(yal^fas));
			}
			yal.v[a][b]=1;
			yall.v[a][b]=1;
		}
	}

	cout<<"Impossible";
	return 0;

}

/*
	  .      _______    __    ___     ________      ________       _________     _________   ________
	  .     /       \  |  |  /  /    /        \    |        \     /         \   |        |  |   __   \
	  .    /   _____/  |  | /  /    /    ___   \   |   ___   \   |   _______/   |  ______|  |  |  \   \
	  .   /   /        |  |/  /    /    /   \   \  |  |   \   \  |  (______     |  |_____   |  |__/   /
	  .   |  |         |     /     |   /     \  |  |  |    |  |   \        \    |        |  |      __/
	  .   |  |         |     \     |   \     /  |  |  |    |  |    \______  \   |  ______|  |      \
	  .   \   \_____   |  |\  \    \    \___/   /  |  |___/   /    _______) |   |  |_____   |   |\  \
	  .    \        \  |  | \  \    \          /   |         /    /         /   |        |  |   | \  \
	  .     \_______/  |__|  \__\    \________/    |________/     \________/    |________|  |___|  \__\
 */


#include <bits/stdc++.h>
using namespace std;

inline int gi()
{
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	int sum = 0;
	while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar();
	return sum;
}

const int maxn = 155;

int n, m;

struct edge
{
	int u, v, w;
} e[maxn];

bitset<150> f[maxn], trans[maxn];

void mul(bitset<150> *a, bitset<150> *b)
{
	static bitset<150> res[maxn];
	for (int i = 1; i <= n; ++i) res[i].reset();
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (a[i][j]) res[i] |= b[j];
	for (int i = 1; i <= n; ++i) a[i] = res[i];
}

void fpow(bitset<150> *a, bitset<150> *b, int k)
{
	static bitset<150> x[maxn];
	for (int i = 1; i <= n; ++i) x[i] = b[i];
	while (k) {
		if (k & 1) mul(a, x);
		k >>= 1; mul(x, x);
	}
}

int main()
{
	n = gi(); m = gi();
	for (int i = 1; i <= m; ++i) e[i] = (edge) {gi(), gi(), gi()};

	sort(e + 1, e + m + 1, [](const edge &a, const edge &b) {return a.w < b.w;});
	e[m + 1].w = e[m].w + n;
	for (int i = 1; i <= n; ++i) f[i][i] = 1;

	int ans = 0;
	if (e[1].w > 0) return puts("Impossible"), 0;
	for (int i = 1; i <= m; ++i) {
		trans[e[i].u][e[i].v] = 1;
		if (e[i].w == e[i + 1].w) continue;
		for (int j = 1; j <= n && ans < e[i + 1].w; ++j, ++ans) {
			mul(f, trans);
			if (f[1][n]) return printf("%d\n", ans + 1), 0;
		}
		fpow(f, trans, e[i + 1].w - ans);
		ans = e[i + 1].w;
	}
	puts("Impossible");

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define bt bitset<160>
const int inf = 0x3f3f3f3f;
int n,m,g[160][160];
bt ans[160],a[160],c[160];
struct node {
	int x,y,z;
};
node d[160];
inline bool cmp(const node x,const node y){return x.z<y.z;}
inline void mul(bt a[160],bt b[160]){
	int i,j,k;
	for(i=1;i<=n;i++)c[i].reset();
	for(k=1;k<=n;k++)
	  for(i=1;i<=n;i++)
	    if(a[i][k])c[i]|=b[k];
	for(i=1;i<=n;i++)a[i]=c[i];
}
int main(){
	int i,j,k;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)scanf("%d%d%d",&d[i].x,&d[i].y,&d[i].z);
	sort(d+1,d+m+1,cmp);
	for(i=1;i<=n;i++)ans[i].reset();
	for(i=1;i<=n;i++)ans[i][i]=1;
	int Ans=inf;
	for(int _=1;_<=m;_++){
	  for(i=1;i<=n;i++)a[i].reset();
	  for(i=1;i<_;i++)a[d[i].x][d[i].y]=1;
	  k=d[_].z-d[_-1].z;
	  while(k){
	  	if(k&1)mul(ans,a);
	  	mul(a,a);
	  	k>>=1;
	  }
	  memset(g,0x3f,sizeof(g));
	  for(i=1;i<=n;i++)g[i][i]=0;
	  for(i=1;i<=_;i++)g[d[i].x][d[i].y]=1;
	  for(k=1;k<=n;k++)
	    for(i=1;i<=n;i++)
	      for(j=1;j<=n;j++)
	        g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
	  for(i=1;i<=n;i++)if(ans[1][i])Ans=min(Ans,d[_].z+g[i][n]);
	}
	if(Ans==inf)puts("Impossible");else printf("%d\n",Ans);
	return 0;
}


/* In the name of Allah */
#include<bits/stdc++.h>
#define debug(x) {cerr << #x << ":\n"; for(int i = 0; i < n; i++, cerr << endl) for (int j = 0; j < n; j++) cerr << x.A[i][j];}
using namespace std;

const int N = 150 + 5, INF = 1e9 + 500;
vector<int> vec = {0, INF};
int n, m, ed[N][N];
struct matrix {
	bitset<N> A[N];

	matrix() {
		for (int i = 0; i < N; i++)
			A[i][i] = true;
	}
	inline friend matrix operator*(const matrix &a, const matrix &b) {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) {
				bool ok = false;
				for (int k = 0; k < n; k++)
					ok |= (a.A[i][k] && b.A[k][j]);
				ans.A[i][j] = ok;
			}
		return ans;
	}
	inline void operator*=(const matrix &a) {
		*this = *this * a;
	}
	inline friend matrix operator^(const matrix &a, const int &k) {
		return k? ((a * a) ^ (k / 2)) * (k & 1? a: matrix()): matrix();
	}
	inline void operator^=(const int &k) {
		*this = *this ^ k;
	}
} e, can[N];

inline void set_edges(int k) {
	for (int u = 0; u < n; u++)
		for (int v = 0; v < n; v++)
			e.A[u][v] = (ed[u][v] <= k);
}

inline bool check(int k) {
	int id = --upper_bound(vec.begin(), vec.end(), k) - vec.begin();
	return set_edges(k), (can[id] * (e ^ k - vec[id])).A[0][n - 1];
}

inline void readInput() {
	cin >> n >> m;
	memset(ed, 63, sizeof ed);
	for (int i = ed[n - 1][n - 1] = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;

		u--, v--, vec.push_back(w);
		ed[u][v] = min(ed[u][v], w);
	}
	sort(vec.begin(), vec.end());
	vec.resize(m = unique(vec.begin(), vec.end()) - vec.begin());
}

inline void solve() {
	for (int i = 0; i < m; i++)
		set_edges(vec[i]), can[i + 1] = can[i] * (e ^ vec[i + 1] - vec[i]);
	int L = 0, R = INF;
	while (L + 1 < R) {
		int mid = L + R >> 1;
		(check(mid)? R: L) = mid;
	}
	if (R < INF)
		cout << R << endl;
	else
		cout << "Impossible\n";
}

int main() {
	ios:: sync_with_stdio(0), cin.tie(0), cout.tie(0);
	readInput(), solve();
	return 0;
}


/* In the name of Allah */
#include<bits/stdc++.h>
using namespace std;

const int N = 150 + 5, INF = 1e9 + 500;
vector<int> vec = {0, INF};
int n, m, ed[N][N];
struct matrix {
	bitset<N> A[N], B[N];

	matrix() {
		for (int i = 0; i < n; i++)
			set(i, i, true);
	}
	inline void set(int i, int j, bool x) {
		A[i][j] = B[j][i] = x;
	}
	inline matrix operator*(const matrix a) const {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, (A[i] & a.B[j]).any());
		return ans;
	}
	inline matrix operator|(const matrix a) const {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, A[i][j] || a.A[i][j]);
		return ans;
	}
	inline matrix operator^(const int k) const {
		return k? ((*this * *this) ^ (k / 2)) * (k & 1? *this: matrix()): matrix();
	}
} e[N], can[N];

inline bool check(int k) {
	int id = --upper_bound(vec.begin(), vec.end(), k) - vec.begin();
	return (can[id] * (e[id] ^ k - vec[id])).A[0][n - 1];
}

inline void readInput() {
	cin >> n >> m;
	memset(ed, 63, sizeof ed);
	for (int i = ed[n - 1][n - 1] = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;

		u--, v--, vec.push_back(w);
		ed[u][v] = min(ed[u][v], w);
	}
	sort(vec.begin(), vec.end());
	vec.resize(m = unique(vec.begin(), vec.end()) - vec.begin());
}

inline void prep() {
	can[0] = matrix();
	for (int u = 0; u < n; u++)
		for (int v = 0; v < n; v++)
			e[lower_bound(vec.begin(), vec.end(), ed[u][v]) - vec.begin()].set(u, v, true);
	for (int i = 0; i < m; i++) {
		e[i + 1] = e[i] | e[i + 1];
		can[i + 1] = can[i] * (e[i] ^ vec[i + 1] - vec[i]);
	}
}

inline void solve() {
	int L = 0, R = INF;
	while (L + 1 < R) {
		int mid = L + R >> 1;
		(check(mid)? R: L) = mid;
	}
	if (R < INF)
		cout << R << endl;
	else
		cout << "Impossible\n";
}

int main() {
	ios:: sync_with_stdio(0), cin.tie(0), cout.tie(0);
	readInput(), prep(), solve();
	return 0;
}


/* In the name of Allah */
#include<bits/stdc++.h>
using namespace std;

const int N = 150 + 5, INF = 1e9 + 500;
vector<int> vec = {0, INF};
int n, m, ed[N][N];
struct matrix {
	bitset<N> A[N], B[N];

	matrix() {
		for (int i = 0; i < n; i++)
			set(i, i, true);
	}
	inline void set(const int &i, const int &j, const bool &x) {
		A[i][j] = B[j][i] = x;
	}
	inline matrix operator*(const matrix &a) const {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, (A[i] & a.B[j]).any());
		return ans;
	}
	inline matrix operator|(const matrix &a) const {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, A[i][j] || a.A[i][j]);
		return ans;
	}
	matrix operator^(const int &k) const {
		return k? ((*this * *this) ^ (k / 2)) * (k & 1? *this: matrix()): matrix();
	}
} e[N], can[N];

inline bool check(const int &k) {
	int id = --upper_bound(vec.begin(), vec.end(), k) - vec.begin();
	return (can[id] * (e[id] ^ k - vec[id])).A[0][n - 1];
}

inline void readInput() {
	scanf("%d%d", &n, &m);
	memset(ed, 63, sizeof ed);
	for (int i = ed[n - 1][n - 1] = 0; i < m; i++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);

		u--, v--, vec.push_back(w);
		ed[u][v] = min(ed[u][v], w);
	}
	sort(vec.begin(), vec.end());
	vec.resize(m = unique(vec.begin(), vec.end()) - vec.begin());
}

inline void prep() {
	can[0] = matrix();
	for (int u = 0; u < n; u++)
		for (int v = 0; v < n; v++)
			e[lower_bound(vec.begin(), vec.end(), ed[u][v]) - vec.begin()].set(u, v, true);
	for (int i = 0; i < m; i++) {
		e[i + 1] = e[i] | e[i + 1];
		can[i + 1] = can[i] * (e[i] ^ vec[i + 1] - vec[i]);
	}
}

inline void solve() {
	int L = 0, R = INF;
	while (L + 1 < R) {
		int mid = L + R >> 1;
		(check(mid)? R: L) = mid;
	}
	R < INF? printf("%d", R): printf("Impossible");
}

inline void program() {
	readInput();
	prep();
	solve();
}

int main() {
	program();
	return 0;
}


/* In the name of Allah */
#include<bits/stdc++.h>
using namespace std;

const int N = 150 + 5, INF = 1e9 + 500;
vector<int> vec = {0, INF};
int n, m, ed[N][N];
struct matrix {
	bitset<N> A[N], B[N];

	matrix() {
		for (int i = 0; i < n; i++)
			set(i, i, true);
	}
	void set(int i, int j, bool x) {
		A[i][j] = B[j][i] = x;
	}
	matrix operator*(matrix a) {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, (A[i] & a.B[j]).any());
		return ans;
	}
	matrix operator|(matrix a) {
		matrix ans;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ans.set(i, j, A[i][j] || a.A[i][j]);
		return ans;
	}
	matrix operator^(int k) {
		return k? ((*this * *this) ^ (k / 2)) * (k & 1? *this: matrix()): matrix();
	}
} e[N], can[N];

int main() {
	cin >> n >> m;
	memset(ed, 63, sizeof ed);
	for (int i = ed[n - 1][n - 1] = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;

		u--, v--, vec.push_back(w);
		ed[u][v] = min(ed[u][v], w);
	}
	sort(vec.begin(), vec.end());
	vec.resize(m = unique(vec.begin(), vec.end()) - vec.begin());

	can[0] = matrix();
	for (int u = 0; u < n; u++)
		for (int v = 0; v < n; v++)
			e[lower_bound(vec.begin(), vec.end(), ed[u][v]) - vec.begin()].set(u, v, true);
	for (int i = 0; i < m; i++) {
		e[i + 1] = e[i] | e[i + 1];
		can[i + 1] = can[i] * (e[i] ^ vec[i + 1] - vec[i]);
	}

	int L = 0, R = INF;
	while (L + 1 < R) {
		int mid = L + R >> 1, id = --upper_bound(vec.begin(), vec.end(), mid) - vec.begin();
		((can[id] * (e[id] ^ mid - vec[id])).A[0][n - 1]? R: L) = mid;
	}
	if (R < INF)
		cout << R << endl;
	else
		cout << "Impossible\n";
}


#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<bitset>
#define N 200
using namespace std;
struct node{int x,y,t,nex;}e[N],a[N];
int n,m,fir[N],len,d[N],ans,tail,p[N];
bitset<N> now,A[N],f[N],g[N],r[N],T[N],b;
bool v[N];
bool cmp(node x,node y)
{
	if(x.t<y.t) return 1;
	return 0;
}
void ins(int x,int y)
{
	a[++len].y=y;a[len].nex=fir[x];fir[x]=len;
}
void solve(int t)
{
	for(int i=1;i<=n;i++) {f[i]=A[i];g[i].reset();g[i][i]=1;}
	while(t)
	{
		if(t%2)
		{
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
					r[i][j]=g[j][i];
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
				{
					b=f[i]&r[j];
					if(b.any()) T[i][j]=1;
					else T[i][j]=0;
				}
			for(int i=1;i<=n;i++) g[i]=T[i];
		}
		t/=2;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				r[i][j]=f[j][i];
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				b=f[i]&r[j];
				if(b.any()) T[i][j]=1;
				else T[i][j]=0;
			}
		for(int i=1;i<=n;i++) f[i]=T[i];
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			r[i][j]=g[j][i];
	for(int i=1;i<=n;i++)
	{
		b=now&r[i];
		if(b.any()) T[1][i]=1;
		else T[1][i]=0;
	}
	now=T[1];
}
void bfs()
{
	for(int i=1;i<=n;i++) d[i]=-1;
	d[n]=0;
	tail=1;p[1]=n;
	for(int i=1;i<=tail;i++)
	{
		int x=p[i];
		for(int k=fir[x];k;k=a[k].nex)
		{
			int y=a[k].y;
			if(d[y]==-1) {d[y]=d[x]+1;p[++tail]=y;}
		}
	}
}
void upd(int x)
{
	if(ans==-1 || x<ans) ans=x;
}
void check(int t)
{
	bfs();
	for(int i=1;i<=n;i++) if(now[i] && d[i]!=-1) upd(d[i]+t);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].t);
	sort(e+1,e+m+1,cmp);
	ans=-1;
	now.reset();
	now[1]=1;
	int i=1;
	while(i<=m)
	{
		solve(e[i].t-e[i-1].t);
		int t=e[i].t;
		while(i<=m && e[i].t==t)
		{
			int x=e[i].x,y=e[i].y;
			if(A[x][y]==0) {A[x][y]=1;ins(y,x);}
			i++;
		}
		check(t);
	}
	if(ans==-1) printf("Impossible\n");
	else printf("%d\n",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <bitset>
#include <climits>
using namespace std;
const int N = 150;
template<int n, int m> struct matrix
{
	bitset<m> a[n];
	bitset<m> &operator [](int x) { return a[x]; }
	template<int x> matrix<n, x> operator *(matrix<m, x> &b)
	{
		static matrix<n, x> c;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				c[i][j] = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				if (a[i][j]) c[i] |= b[j];
		return c;
	}
	matrix<n, m> multi(int k)
	{
		static matrix<n, m> ret, t;
		t = *this;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ret[i][j] = i == j;
		while (k > 0)
		{
			if (k & 1) ret = ret*t;
			t = t*t;
			k >>= 1;
		}
		return ret;
	}
};
struct flight { int a, b, d; } f[N];
matrix<N, N> adj, tmp;
matrix<1, N> cur;
int dis[N][N];
int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> f[i].a >> f[i].b >> f[i].d;
	sort(f, f + m, [](const flight &a, const flight &b) { return a.d < b.d; });
	if (f[0].d > 0)
	{
		cout << "Impossible" << endl;
		return 0;
	}
	cur[0] = 1;
	int ans = INT_MAX;
	for (int i = 0; i < m; i++)
	{
		adj[f[i].a - 1][f[i].b - 1] = 1;
		if (i < m - 1 && f[i].d == f[i + 1].d) continue;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
			{
				if (i == j) dis[i][j] = 0;
				else if (adj[i][j]) dis[i][j] = 1;
				else dis[i][j] = INT_MAX;
			}
		for (int k = 0; k < n; k++)
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					if (dis[i][k] < INT_MAX&&dis[k][j] < INT_MAX)
						dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
		for (int j = 0; j < n; j++)
			if (cur[0][j] && dis[j][n - 1] < INT_MAX)
				ans = min(ans, f[i].d + dis[j][n - 1]);
		if (i < m - 1)
		{
			tmp = adj.multi(f[i + 1].d - f[i].d);
			cur = cur*tmp;
		}
	}
	if (ans < INT_MAX) cout << ans << endl;
	else cout << "Impossible" << endl;
}


#include <iostream>
#include <algorithm>
#include <bitset>
#include <climits>
using namespace std;
const int N = 150;
template<int n, int m> struct matrix
{
	bitset<m> a[n];
	bitset<m> &operator [](int x) { return a[x]; }
	template<int x> matrix<n, x> operator *(matrix<m, x> &b)
	{
		static matrix<n, x> c;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				c[i][j] = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				if (a[i][j]) c[i] |= b[j];
		return c;
	}
	matrix<n, m> multi(int k)
	{
		static matrix<n, m> ret, t;
		t = *this;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ret[i][j] = i == j;
		while (k > 0)
		{
			if (k & 1) ret = ret*t;
			t = t*t;
			k >>= 1;
		}
		return ret;
	}
};
struct flight { int a, b, d; } f[N];
matrix<N, N> adj, tmp;
matrix<1, N> cur;
int dis[N][N];
int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> f[i].a >> f[i].b >> f[i].d;
	sort(f, f + m, [](const flight &a, const flight &b) { return a.d < b.d; });
	if (f[0].d > 0)
	{
		cout << "Impossible" << endl;
		return 0;
	}
	cur[0] = 1;
	int ans = INT_MAX;
	for (int i = 0; i < m; i++)
	{
		adj[f[i].a - 1][f[i].b - 1] = 1;
		if (i < n - 1 && f[i].d == f[i + 1].d) continue;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
			{
				if (i == j) dis[i][j] = 0;
				else if (adj[i][j]) dis[i][j] = 1;
				else dis[i][j] = INT_MAX;
			}
		for (int k = 0; k < n; k++)
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					if (dis[i][k] < INT_MAX&&dis[k][j] < INT_MAX)
						dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
		for (int j = 0; j < n; j++)
			if (cur[0][j] && dis[j][n - 1] < INT_MAX)
				ans = min(ans, f[i].d + dis[j][n - 1]);
		if (i < n - 1)
		{
			tmp = adj.multi(f[i + 1].d - f[i].d);
			cur = cur*tmp;
		}
	}
	if (ans < INT_MAX) cout << ans << endl;
	else cout << "Impossible" << endl;
}


#include <iostream>
#include <algorithm>
#include <bitset>
#include <climits>
using namespace std;
const int N = 150;
template<int n, int m> struct matrix
{
	bitset<m> a[n];
	bitset<m> &operator [](int x) { return a[x]; }
	template<int x> matrix<n, x> operator *(matrix<m, x> &b) const
	{
		static matrix<n, x> c;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				c[i][j] = 0;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < x; j++)
				if (a[i][j]) c[i] |= b[j];
		return c;
	}
	matrix<n, m> multi(int k)
	{
		static matrix<n, m> ret, t;
		t = *this;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ret[i][j] = i == j;
		while (k > 0)
		{
			if (k & 1) ret = ret*t;
			t = t*t;
			k >>= 1;
		}
		return ret;
	}
};
struct flight { int a, b, d; } f[N];
matrix<N, N> adj;
matrix<1, N> cur;
int dis[N][N];
int main()
{
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> f[i].a >> f[i].b >> f[i].d;
	sort(f, f + m, [](const flight &a, const flight &b) { return a.d < b.d; });
	if (f[0].d > 0)
	{
		cout << "Impossible" << endl;
		return 0;
	}
	cur[0] = 1;
	int ans = INT_MAX;
	for (int i = 0; i < m; i++)
	{
		adj[f[i].a - 1][f[i].b - 1] = 1;
		if (i < n - 1 && f[i].d == f[i + 1].d) continue;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
			{
				if (i == j) dis[i][j] = 0;
				else if (adj[i][j]) dis[i][j] = 1;
				else dis[i][j] = INT_MAX;
			}
		for (int k = 0; k < n; k++)
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					if (dis[i][k] < INT_MAX&&dis[k][j] < INT_MAX)
						dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
		for (int j = 0; j < n; j++)
			if (cur[0][j] && dis[j][n - 1] < INT_MAX)
				ans = min(ans, f[i].d + dis[j][n - 1]);
		if (i < n - 1) cur = cur*adj.multi(f[i + 1].d - f[i].d);
	}
	if (ans < INT_MAX) cout << ans << endl;
	else cout << "Impossible" << endl;
}


#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF=1e9;
const long double eps=1e-9;
const int maxn=180+10;
const int maxm=4e4+10;
int w[maxn],to[maxm],nex[maxm],beg[maxn],Lv[maxm];
int n,e;
struct Matrix{
	bitset<maxn> A[maxn];
	Matrix(){
		int i,j;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				A[i][j]=0;
	}
};
inline Matrix operator * (const Matrix &lhs,const Matrix &rhs){
	int i,j;
	Matrix ans,tmp;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			tmp.A[i][j]=rhs.A[j][i];
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			ans.A[i][j]=(lhs.A[i] & tmp.A[j]).any();
	return ans;
}
struct Edge{
	int x,y,lv;
}edge[maxm];
inline int read(){
	int x=0,flag=1;
	char ch=getchar();
	while(!isdigit(ch) && ch!='-')ch=getchar();
	if(ch=='-')flag=-1,ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x*flag;
}
inline void add(int x,int y,int z){
	to[++e]=y;
	nex[e]=beg[x];
	beg[x]=e;
	Lv[e]=z;
}
inline Matrix fpm(Matrix base,int power){
	Matrix Res;int i;
	for(i=1;i<=n;i++)Res.A[i][i]=1;
	while(power){
		if(power & 1)Res=Res*base;
		base=base*base;power/=2;
	}
	return Res;
}
int main(){
	int i,j,k,m,c;
#ifndef ONLINE_JUDGE
	freopen("griffin.in","r",stdin);
	freopen("griffin.out","w",stdout);
#endif
	n=read();m=read();c=read();
	for(i=1;i<=m;i++){
		int x=read(),y=read(),lv=read();
		add(x,y,lv);edge[i]=(Edge){x,y,lv};
	}
	for(i=1;i<=c;i++)w[i]=read();
	Matrix res;res.A[1][1]=true;
	int Ans=INF*2;
	for(i=1;i<=c+1;i++){
		Matrix A,Nex;
		int Pow=i==c+1 ? n : w[i]-w[i-1];
		for(j=1;j<=m;j++)
			if(edge[j].lv<i)
				A.A[edge[j].x][edge[j].y]=true;
		A.A[n][n]=true;
		Nex=res*fpm(A,Pow);
		if(Nex.A[1][n]){
			for(j=1;j<=n;j++){
				res=res*A;
				if(res.A[1][n])
					return printf("%d\n",w[i-1]+j),0;
			}
		}
		else if(i==c+1){
			puts("Impossible");
			return 0;
		}
		res=Nex;
	}
	return 0;
}


#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF=1e9;
const long double eps=1e-9;
const int maxn=150+10;
const int maxm=150+10;
int w[maxn],Hash[maxm];
int n,e;
struct Matrix{
	bitset<maxn> A[maxn];
	Matrix(){
		int i,j;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				A[i][j]=0;
	}
};
inline Matrix operator * (const Matrix &lhs,const Matrix &rhs){
	int i,j;
	Matrix ans,tmp;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			tmp.A[i][j]=rhs.A[j][i];
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			ans.A[i][j]=(lhs.A[i] & tmp.A[j]).any();
	return ans;
}
struct Edge{
	int x,y,lv;
}edge[maxm];
inline int read(){
	int x=0,flag=1;
	char ch=getchar();
	while(!isdigit(ch) && ch!='-')ch=getchar();
	if(ch=='-')flag=-1,ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x*flag;
}
inline Matrix fpm(Matrix base,int power){
	Matrix Res;int i;
	for(i=1;i<=n;i++)Res.A[i][i]=1;
	while(power){
		if(power & 1)Res=Res*base;
		base=base*base;power/=2;
	}
	return Res;
}
int main(){
	int i,j,k,m,c;
#ifndef ONLINE_JUDGE
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
#endif
	n=read();m=read();
	for(i=1;i<=m;i++){
		int x=read(),y=read(),lv=read();
		edge[i]=(Edge){x,y,lv};Hash[i]=lv;
	}
	sort(Hash+1,Hash+m+1);
	c=unique(Hash+1,Hash+m+1)-Hash-1;
	for(i=1;i<=m;i++)edge[i].lv=lower_bound(Hash+1,Hash+m+1,edge[i].lv)-Hash;
	for(i=1;i<=c;i++)w[i]=Hash[i];
	Matrix res;res.A[1][1]=true;
	int Ans=INF*2;
	for(i=1;i<=c+1;i++){
		Matrix A,Nex;
		int Pow=i==c+1 ? n : w[i]-w[i-1];
		for(j=1;j<=m;j++)
			if(edge[j].lv<i)
				A.A[edge[j].x][edge[j].y]=true;
		A.A[n][n]=true;
		Nex=res*fpm(A,Pow);
		if(Nex.A[1][n]){
			for(j=1;j<=n;j++){
				res=res*A;
				if(res.A[1][n])
					return printf("%d\n",w[i-1]+j),0;
			}
		}
		else if(i==c+1){
			puts("Impossible");
			return 0;
		}
		res=Nex;
	}
	return 0;
}


#include<bitset>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF=1e9;
const long double eps=1e-9;
const int maxn=150+10;
const int maxm=150+10;
int w[maxn],Hash[maxm];
int n,e;
struct Matrix{
	bitset<maxn> A[maxn];
	Matrix(){
		int i,j;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				A[i][j]=0;
	}
};
inline Matrix operator * (const Matrix &lhs,const Matrix &rhs){
	int i,j;
	Matrix ans,tmp;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			tmp.A[i][j]=rhs.A[j][i];
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			ans.A[i][j]=(lhs.A[i] & tmp.A[j]).any();
	return ans;
}
struct Edge{
	int x,y,lv;
}edge[maxm];
inline int read(){
	int x=0,flag=1;
	char ch=getchar();
	while(!isdigit(ch) && ch!='-')ch=getchar();
	if(ch=='-')flag=-1,ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x*flag;
}
inline Matrix fpm(Matrix base,int power){
	Matrix Res;int i;
	for(i=1;i<=n;i++)Res.A[i][i]=1;
	while(power){
		if(power & 1)Res=Res*base;
		base=base*base;power/=2;
	}
	return Res;
}
int main(){
	int i,j,m,c;
#ifndef ONLINE_JUDGE
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
#endif
	n=read();m=read();
	for(i=1;i<=m;i++){
		int x=read(),y=read(),lv=read();
		edge[i]=(Edge){x,y,lv};Hash[i]=lv;
	}
	sort(Hash+1,Hash+m+1);
	c=unique(Hash+1,Hash+m+1)-Hash-1;
	for(i=1;i<=m;i++)edge[i].lv=lower_bound(Hash+1,Hash+c+1,edge[i].lv)-Hash;
	for(i=1;i<=c;i++)w[i]=Hash[i];
	Matrix res;res.A[1][1]=true;
	for(i=1;i<=c+1;i++){
		Matrix A,Nex;
		int Pow=i==c+1 ? n : w[i]-w[i-1];
		for(j=1;j<=m;j++)
			if(edge[j].lv<i)
				A.A[edge[j].x][edge[j].y]=true;
		A.A[n][n]=true;
		Nex=res*fpm(A,Pow);
		if(Nex.A[1][n]){
			for(j=1;j<=n;j++){
				res=res*A;
				if(res.A[1][n])
					return printf("%d\n",w[i-1]+j),0;
			}
		}
		else if(i==c+1){
			puts("Impossible");
			return 0;
		}
		res=Nex;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=155;
int read(){
	int f=1,g=0;
	char ch=getchar();
	for (;!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
	for (;isdigit(ch);ch=getchar()) g=g*10+ch-'0';
	return f*g;
}
int n,m;
struct edge{int u,v,t;}e[N];
bool cmp(edge a,edge b){return a.t<b.t;}
struct matrix{
	bitset<N> a[N];
	bitset<N>& operator[](int i){return a[i];}
	void clear(){for (int i=1;i<=n;i++) a[i].reset();}
	void reset(){for (int i=1;i<=n;i++) a[i].reset(),a[i][i]=1;}
}cur,a,b,f[35],g[35];
matrix operator*(matrix &a,matrix &b){
	static matrix c;c.clear();
	for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
	if (a[i][j]) c[i]|=b[j];
	return c;
}
matrix operator|(matrix &a,matrix b){
	static matrix c;
	for (int i=1;i<=n;i++) c[i]=a[i]|b[i];
	return c;
}
int main(){
	n=read();m=read();
	cur.reset();
	a.clear();
	for (int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(),e[i].t=read();
	sort(e+1,e+m+1,cmp);
	int las=0;
	for (int i=1;i<=m;i++){
		int j,k=e[i].t-las;
		g[0]=a;f[0].reset();f[0]=f[0]|g[0];
		for (j=1;(1<<j)<=k;j++) g[j]=g[j-1]*g[j-1],f[j]=f[j-1]|(f[j-1]*g[j-1]);
		for (j--;j>=0;j--)
		if ((1<<j)<=k){
			b=cur*f[j];
			if (!b[1][n]) {cur=cur*g[j];k-=(1<<j);las+=(1<<j);}
		}
		if (k) {printf("%d\n",las+1);return 0;}
		a[e[i].u][e[i].v]=1;
	}

	g[0]=a;f[0].reset();f[0]=f[0]|g[0];
	for (int i=1;i<=20;i++) g[i]=g[i-1]*g[i-1],f[i]=f[i-1]|(f[i-1]*g[i-1]);
	for (int i=20;i>=0;i--){
		b=cur*f[i];
		if (!b[1][n]) {cur=cur*g[i];las+=(1<<i);}
	}
	cur=cur*a;las++;
	if (!cur[1][n]) puts("Impossible");
	else printf("%d\n",las);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <assert.h>
#include <bitset>
using namespace std;

const int N = 155;
bitset<N> can[N], dp[N], T[N];
int f[N][N];

struct edge {
	int x, y, z;
	friend bool operator < (const edge &p, const edge &q) {
		return p.z < q.z;
	}

	void read() {
		scanf("%d%d%d", &x, &y, &z);
	    x--, y--;
	}
}e[N];

int n, m;
void mul(bitset<N> a[N], bitset<N> b[N]) {
	for (int i = 0; i < n; i++) T[i].reset();
    for (int k = 0; k < n; k++)
	    for (int i = 0; i < n; i++)
		    if (a[i][k]) {
				T[i] |= b[k];
			}
	for (int i = 0; i < n; i++)
		a[i] = T[i];

}

void cal(int t) {
	while (t) {
		if (t & 1){
		   	mul(can, dp);
		}
		mul(dp, dp);
		t >>= 1;
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) e[i].read();
	sort(e + 1, e + m + 1);
	int ans = (1 << 30) - 1;

	for (int i = 0; i < n; i++) can[i][i] = 1;
	for (int t = 1; t <= m; t++) {
		for (int i = 0; i < n; i++) dp[i].reset();
		for (int i = 1; i < t; i++)
			dp[e[i].x][e[i].y] = 1;
		cal(e[t].z - e[t - 1].z);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				f[i][j] = (1 << 30) - 1;
		for (int i = 0; i < n; i++) f[i][i] = 0;
		for (int i = 1; i <= t; i++)
			f[e[i].x][e[i].y] = 1;
	    for (int k = 0; k < n; k++)
		    for (int i = 0; i < n; i++) {
			    if (f[i][k] == (1 << 30) - 1) continue;
			    for (int j = 0; j < n; j++)
				    f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
			}

	    for (int i = 0; i < n; i++)
		    if (can[0][i]) ans = min(ans, f[i][n - 1] + e[t].z);
	}

	if (ans == (1 << 30) - 1) printf("Impossible\n");
	else cout << ans << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <assert.h>
#include <bitset>
using namespace std;

const int N = 155;
bitset<N> can[N], dp[N], T[N];
int f[N][N];

struct edge {
	int x, y, z;
	friend bool operator < (const edge &p, const edge &q) {
		return p.z < q.z;
	}

	void read() {
		scanf("%d%d%d", &x, &y, &z);
	    x--, y--;
	}
}e[N];

int n, m;
void mul(bitset<N> a[N], bitset<N> b[N]) {
	for (int i = 0; i < n; i++) T[i].reset();
    for (int k = 0; k < n; k++)
	    for (int i = 0; i < n; i++)
		    if (can[i][k]) T[i] |= b[k];
	for (int i = 0; i < n; i++)
		a[i] = T[i];
}

void cal(int n) {
	while (n) {
		if (n & 1) mul(can, dp);
		mul(dp, dp);
		n >>= 1;
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) e[i].read();
	sort(e + 1, e + m + 1);
	int ans = (1 << 30) - 1;

	for (int i = 0; i < n; i++) can[i][i] = 1;
	for (int t = 1; t <= m; t++) {
		for (int i = 0; i < n; i++) dp[i].reset();
		for (int i = 1; i < t; i++)
			dp[e[i].x][e[i].y] = 1;
		cal(e[t].z - e[t - 1].z);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				f[i][j] = (1 << 30) - 1;
		for (int i = 0; i < n; i++) f[i][i] = 0;
		for (int i = 1; i <= t; i++)
			f[e[i].x][e[i].y] = 1;
	    for (int k = 0; k < n; k++)
		    for (int i = 0; i < n; i++) {
			    if (f[i][k] == (1 << 30) - 1) continue;
			    for (int j = 0; j < n; j++)
				    f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
			}

	    for (int i = 0; i < n; i++)
		    if (can[0][i]) ans = min(ans, f[i][n - 1] + e[t].z);
	}

	if (ans == (1 << 30) - 1) printf("Impossible\n");
	else cout << ans << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <assert.h>
#include <bitset>
using namespace std;

const int N = 155;
bitset<N> can[N], dp[N], T[N];
int f[N][N];

struct edge {
	int x, y, z;
	friend bool operator < (const edge &p, const edge &q) {
		return p.z < q.z;
	}

	void read() {
		scanf("%d%d%d", &x, &y, &z);
	    x--, y--;
	}
}e[N];

int n, m;
void mul(bitset<N> a[N], bitset<N> b[N]) {
	for (int i = 0; i < n; i++) T[i].reset();
    for (int k = 0; k < n; k++)
	    for (int i = 0; i < n; i++)
		    if (dp[i][k]) {
				T[i] |= b[k];
			}
	for (int i = 0; i < n; i++)
		a[i] = T[i];

}

void cal(int t) {
	while (t) {
		if (t & 1){
		   	mul(can, dp);
		}
		mul(dp, dp);
		t >>= 1;
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) e[i].read();
	sort(e + 1, e + m + 1);
	int ans = (1 << 30) - 1;

	for (int i = 0; i < n; i++) can[i][i] = 1;
	for (int t = 1; t <= m; t++) {
		for (int i = 0; i < n; i++) dp[i].reset();
		for (int i = 1; i < t; i++)
			dp[e[i].x][e[i].y] = 1;
		cal(e[t].z - e[t - 1].z);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				f[i][j] = (1 << 30) - 1;
		for (int i = 0; i < n; i++) f[i][i] = 0;
		for (int i = 1; i <= t; i++)
			f[e[i].x][e[i].y] = 1;
	    for (int k = 0; k < n; k++)
		    for (int i = 0; i < n; i++) {
			    if (f[i][k] == (1 << 30) - 1) continue;
			    for (int j = 0; j < n; j++)
				    f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
			}

	    for (int i = 0; i < n; i++)
		    if (can[0][i]) ans = min(ans, f[i][n - 1] + e[t].z);
	}

	if (ans == (1 << 30) - 1) printf("Impossible\n");
	else cout << ans << endl;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define x first
#define y second
#define mp make_pair
#define pb push_back
template <typename TYPE> inline void chkmax(TYPE &x,TYPE y){x<y?x=y:0;}
template <typename TYPE> inline void chkmin(TYPE &x,TYPE y){y<x?x=y:0;}
template <typename TYPE> void readint(TYPE &x)
{
    x=0;int f=1;char c;
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=x*10+c-'0';
    x*=f;
}
const int MAXN=155,MAXK=8,INF=2147483647;

int n,m,q[MAXN],dis[MAXN];
struct Edge
{
	int u,v,d;
	inline bool operator <(const Edge &b)const{return d<b.d;}
}e[MAXN];
struct Matrix
{
	bitset<MAXN> a[MAXN];
	Matrix(){memset(a,0,sizeof(a));}
};
Matrix G,ans;
Matrix operator *(Matrix a,Matrix b)
{
	Matrix c;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(a.a[i][j])c.a[i]|=b.a[j];
	return c;
}
Matrix power(Matrix a,int k)
{
	Matrix ans;
	for(int i=1;i<=n;++i)ans.a[i][i]=1;
	for(;k;k>>=1,a=a*a)
		if(k&1)ans=ans*a;
	return ans;
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("code.in","r",stdin);
	//freopen("code.out","w",stdout);
	#endif
	readint(n),readint(m);
	for(int i=1;i<=m;++i)readint(e[i].u),readint(e[i].v),readint(e[i].d);
	sort(e+1,e+m+1);
	for(int i=1;i<=n;++i)ans.a[i][i]=1;
	int lasd=0,fin=INF;
	for(int i=1;i<=m;++i)
	{
		ans=ans*power(G,e[i].d-lasd);
		G.a[e[i].u][e[i].v]=1;
		lasd=e[i].d;
		for(int j=1;j<=n;++j)dis[j]=INF;
		int front=1,rear=0;
		for(int j=1;j<=n;++j)
			if(ans.a[1][j])q[++rear]=j,dis[j]=0;
		while(front<=rear)
		{
			int u=q[front++];
			for(int j=1;j<=n;++j)
				if(G.a[u][j] && dis[j]==INF)
				{
					dis[j]=dis[u]+1;
					q[++rear]=j;
				}
		}
		if(dis[n]<INF)chkmin(fin,dis[n]+e[i].d);
	}
	if(fin==INF)printf("Impossible\n");
	else printf("%d\n",fin);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define fi first
#define se second
#define MOD(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,n) for (int i = 0; i < n; i++)
#define ALL(v) v.begin(), v.end()
#define pb(x) push_back(x)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<ii> vii;

const int MX = 155;
typedef vector<bitset<MX>> vbs;

int n, m, a[MX], b[MX], d[MX], q[MX], dist[MX];
vbs bs, res;
vi adj[MX];

void init (vbs &v) {
	for (int i = 0; i < n; i++)
		v[i][i] = 1;
}

void cpy (vbs &v, vbs &w) {
	for (int i = 0; i < n; i++)
		v[i] = w[i];
}

void setMat (vbs &v, int i) {
	for (int j = 0; j < n; j++)
		v[j].reset();

	for (int j = 0; j < m && d[q[j]] <= i; j++)
		v[a[q[j]]][b[q[j]]] = 1;
}

vbs mul (vbs &a, vbs &b) {
	vbs c(n), res(n);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			c[i][j] = b[j][i];

	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			res[i][j] = (a[i] & c[j]).any();

	return res;
}

vbs pot (vbs &base, int p) {
	vbs res(n); init(res);
	vbs b(n); cpy(b, base);

	while (p) {
		if (p & 1) res = mul(res, b);
		b = mul(b, b);
		p /= 2;
	}

	return res;
}

void bfs (int d) {
	queue<int> q;

	for (int i = 0; i < n; i++) dist[i] = -1;

	for (int i = 0; i < n; i++)
		if (res[0][i]) {
			q.push(i);
			dist[i] = d;
		}

	while (q.size()) {
		int u = q.front();
		q.pop();

		for (int v : adj[u])
			if (dist[v] == -1) {
				dist[v] = dist[u] + 1;
				q.push(v);
			}
	}
}

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0);

	cin >> n >> m;
	bs.resize(n);
	res.resize(n); init(res);

	for (int i = 0; i < m; i++) {
		cin >> a[i] >> b[i] >> d[i];
		a[i]--, b[i]--;
	}

	iota(q, q+m, 0);
	sort(q, q+m, [&] (int i, int j) {
		return d[i] < d[j];
	});

	if (d[q[0]]) {
		cout << "Impossible" << endl;
		return 0;
	}

	int i = 0, j;

	while (i < m) {
		j = i;

		while (j < m && d[q[i]] == d[q[j]]) {
			adj[a[q[j]]].pb(b[q[j]]);
			j++;
		}

		bfs(d[q[i]]);
		if (dist[n-1] != -1) {
			cout << dist[n-1] << endl;
			return 0;
		}

		if (j < m) {
			setMat(bs, d[q[i]]);
			bs = pot(bs, d[q[j]] - d[q[i]]);
			res = mul(res, bs);
		}

		i = j;
	}

	cout << "Impossible" << endl;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define fi first
#define se second
#define MOD(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,n) for (int i = 0; i < n; i++)
#define ALL(v) v.begin(), v.end()
#define pb(x) push_back(x)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<ii> vii;

const int MX = 155;
typedef vector<bitset<MX>> vbs;

int n, m, a[MX], b[MX], d[MX], q[MX], dist[MX];
vbs bs, res;
vi adj[MX];

void init (vbs &v) {
	for (int i = 0; i < n; i++)
		v[i][i] = 1;
}

void cpy (vbs &v, vbs &w) {
	for (int i = 0; i < n; i++)
		v[i] = w[i];
}

void setMat (vbs &v, int i) {
	for (int j = 0; j < n; j++)
		v[j].reset();

	for (int j = 0; j < n && d[q[j]] <= i; j++)
		v[a[q[j]]][b[q[j]]] = 1;
}

vbs mul (vbs &a, vbs &b) {
	vbs c(n), res(n);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			c[i][j] = b[j][i];

	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			res[i][j] = (a[i] & c[j]).any();

	return res;
}

void pot (int p) {
	vbs res(n); init(res);
	vbs b(n); cpy(b, bs);

	while (p) {
		if (p & 1) res = mul(res, b);
		b = mul(b, b);
		p /= 2;
	}

	cpy(bs, res);
}

void bfs (int d) {
	queue<int> q;

	for (int i = 0; i < n; i++) dist[i] = -1;

	for (int i = 0; i < n; i++)
		if (res[0][i]) {
			q.push(i);
			dist[i] = d;
		}

	while (q.size()) {
		int u = q.front();
		q.pop();

		for (int v : adj[u])
			if (dist[v] == -1) {
				dist[v] = dist[u] + 1;
				q.push(v);
			}
	}
}

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0);

	cin >> n >> m;
	bs.resize(n);
	res.resize(n); init(res);

	for (int i = 0; i < m; i++) {
		cin >> a[i] >> b[i] >> d[i];
		a[i]--, b[i]--;
	}

	iota(q, q+m, 0);
	sort(q, q+m, [&] (int i, int j) {
		return d[i] < d[j];
	});

	if (d[q[0]]) {
		cout << "Impossible" << endl;
		return 0;
	}

	int i = 0, j;

	while (i < m) {
		j = i;

		while (j < m && d[q[i]] == d[q[j]]) {
			adj[a[q[j]]].pb(b[q[j]]);
			j++;
		}

		bfs(d[q[i]]);
		if (dist[n-1] != -1) {
			cout << dist[n-1] << endl;
			return 0;
		}

		if (j < m) {
			setMat(bs, d[q[i]]);
			pot(d[q[j]] - d[q[i]]);
			res = mul(res, bs);
		}

		i = j;
	}

	cout << "Impossible" << endl;

	return 0;
}


#include <bits/stdc++.h>
#define rep(i, n) for (rint i = 1; i <= (n); i ++)
#define re0(i, n) for (rint i = 0; i < (int) n; i ++)
#define travel(i, u) for (rint i = head[u]; i; i = e[i].nxt)
#define rint int
using namespace std;

typedef long long lo;

template<typename tp> inline void read(tp &x) {
	x = 0; char c = getchar(); int f = 0;
	for (; c < '0' || c > '9'; f |= c == '-', c = getchar());
	for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
	if (f) x = -x;
}
const int N = 233;
int n, m, a[N], b[N], d[N], id[N];
struct mat_t {
	bitset <N> b[N];
	mat_t () { rep (i, n) b[i] = 0; }
	bitset <N> & operator [] (int x) { return b[x]; }
	inline void ovo() {
		rep (i, n) rep (j, n) cout << b[i][j] << " \n"[j == n];
		cout << "---\n";
	}
};
mat_t G, suf, mat[N];

mat_t operator * (mat_t a, mat_t b) {
	mat_t ans;
	mat_t c;
	rep (i, n) rep (j, n) c[i][j] = b[j][i];
	rep (i, n) rep (j, n) ans[i][j] = (a[i] & c[j]).count();
	return ans;
}

int main(void) {
	read(n); read(m);
	rep (i, m) {
		read(a[i]); read(b[i]); read(d[i]);
	}
	rep (i, m) id[i] = i;
	sort(id + 1, id + m + 1, [](int x, int y) {
			return d[x] < d[y];
		});
	id[m + 1] = m + 1; d[m + 1] = d[id[m]] + n + 2;
	if (d[id[1]]) {
		cout << "Impossible\n";
		return 0;
	}
    G[n][n] = 1; suf[1][1] = 1;
	for (int l = 1; l <= m; l++) {
		int r = l;
		while (r <= m && d[id[l]] == d[id[r]]) ++r; --r;
		for (int k = l; k <= r; k++) {
			G[a[id[k]]][b[id[k]]] = 1;
		}
		int K = d[id[r + 1]] - d[id[r]];
		int lim = 0;
		while ((1 << lim) <= K) ++lim; --lim;
		mat[0] = G;
		for (int i = 1; i <= lim; i++)
			mat[i] = mat[i - 1] * mat[i - 1];
		mat_t ans = suf;
		for (int i = 0; i <= lim; i++)
			if (K >> i & 1) {
				ans = ans * mat[i];
				// cout << i << "----\n";
				// mat[i].ovo();
			}
		if (ans[1][n]) {
			ans = suf;
			// suf.ovo();
			int step = 0;
			for (int i = lim; i >= 0; i--) {
				auto t = ans * mat[i];
				if (!t[1][n]) swap(ans, t), step += 1 << i;
			}
			cout << step + d[id[l]] + 1 << "\n";
			return 0;
		}
		l = r;
		swap(suf, ans);
		// G.ovo();
		// suf.ovo();
	}
	cout << "Impossible\n";
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 160;

struct mat {
    bitset<MN> T[MN];
    void O() {
        for(int i = 0; i < MN; i++) T[i].reset();
    }
    void I() {
        O();
        for(int i = 0; i < MN; i++) T[i][i] = 1;
    }
};

mat mult(mat &a, mat &b) {
    mat ret;
    ret.O();
    mat c;
    for(int i = 0; i < MN; i++) for(int j = 0; j < MN; j++) c.T[i][j] = b.T[j][i];
    for(int i = 0; i < MN; i++) {
        for(int j = 0; j < MN; j++) {
            ret.T[i][j] = (a.T[i] & c.T[j]).any();
        }
    }
    return ret;
}

mat exp(mat x, int n) {
    mat ret;
    ret.I();
    while(n) {
        if(n & 1) ret = mult(ret, x);
        x = mult(x, x);
        n >>= 1;
    }
    return ret;
}

int N, M;
struct Edge {
    int u, v, w;
    bool operator <(const Edge &i) const {
        return w < i.w;
    }
};
vector<Edge> edge;
vector<int> X;
mat A, C;

int main() {
    scanf("%d %d", &N, &M);

    for(int i = 0; i < M; i++) {
        int u, v, w; scanf("%d %d %d", &u, &v, &w);
        u--; v--;
        edge.push_back({u, v, w});
        X.push_back(w);
    }
    sort(edge.begin(), edge.end());
    sort(X.begin(), X.end());
    X.resize(unique(X.begin(), X.end()) - X.begin());

    A.O();
    A.T[N - 1][N] = 1;
    A.T[N][N] = 1;
    C.I();
    int pos = 0;
    int pre = 0;
    int ans = 2e9;
    for(int i = 0; i < X.size(); i++) {
        mat tmp = exp(A, X[i] - pre);
        C = mult(C, tmp);

        while(pos < M && edge[pos].w <= X[i]) {
            int u = edge[pos].u;
            int v = edge[pos].v;
            A.T[u][v] = 1;
            pos++;
        }

        int s = 0, e = MN, p = -1;
        while(s <= e) {
            int m = (s + e)>>1;

            mat x = exp(A, m);
            mat y = mult(C, x);
            if(y.T[0][N - 1] || y.T[0][N]) {
                p = m;
                e = m - 1;
            }
            else s = m + 1;
        }

        if(p != -1) ans = min(ans, X[i] + p);
        pre = X[i];
    }

    if(ans == 2e9) printf("Impossible");
    else printf("%d", ans);
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 160;

struct mat {
    bitset<MN> T[MN];
    void O() {
        for(int i = 0; i < MN; i++) T[i].reset();
    }
    void I() {
        O();
        for(int i = 0; i < MN; i++) T[i][i] = 1;
    }
};

mat mult(mat &a, mat &b) {
    mat ret;
    ret.O();
    mat c;
    for(int i = 0; i < MN; i++) for(int j = 0; j < MN; j++) c.T[i][j] = b.T[j][i];
    for(int i = 0; i < MN; i++) {
        for(int j = 0; j < MN; j++) {
            ret.T[i][j] = (a.T[i] & c.T[j]).any();
        }
    }
    return ret;
}

mat exp(mat x, int n) {
    mat ret;
    ret.I();
    while(n) {
        if(n & 1) ret = mult(ret, x);
        x = mult(x, x);
        n >>= 1;
    }
    return ret;
}

int N, M;
struct Edge {
    int u, v, w;
    bool operator <(const Edge &i) const {
        return w < i.w;
    }
};
vector<Edge> edge;
vector<int> X;
int dist[MN][MN];
mat A, C;

int main() {
    scanf("%d %d", &N, &M);

    for(int i = 0; i < M; i++) {
        int u, v, w; scanf("%d %d %d", &u, &v, &w);
        u--; v--;
        edge.push_back({u, v, w});
        X.push_back(w);
    }
    sort(edge.begin(), edge.end());
    sort(X.begin(), X.end());
    X.resize(unique(X.begin(), X.end()) - X.begin());

    for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) dist[i][j] = 1e9;
    for(int i = 0; i < N; i++) dist[i][i] = 0;
    A.O();
    C.I();
    int pos = 0;
    int pre = 0;
    int ans = 2e9;
    for(int i = 0; i < X.size(); i++) {
        mat tmp = exp(A, X[i] - pre);
        C = mult(C, tmp);

        while(pos < M && edge[pos].w <= X[i]) {
            int u = edge[pos].u;
            int v = edge[pos].v;
            int w = edge[pos].w;
            A.T[u][v] = 1;

            for(int a = 0; a < N; a++) {
                for(int b = 0; b < N; b++) {
                    dist[a][b] = min(dist[a][b], dist[a][u] + 1 + dist[v][b]);
                }
            }
            pos++;
        }
        for(int j = 0; j < N; j++) if(C.T[0][j] && dist[j][N - 1] != 1e9) ans = min(ans, X[i] + dist[j][N - 1]);
        pre = X[i];
    }

    if(ans == 2e9) printf("Impossible");
    else printf("%d", ans);
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 160;

struct mat {
    bitset<MN> T[MN];
    void O() {
        for(int i = 0; i < MN; i++) T[i].reset();
    }
    void I() {
        O();
        for(int i = 0; i < MN; i++) T[i][i] = 1;
    }
};

mat mult(mat &a, mat &b) {
    mat ret;
    ret.O();
    mat c;
    for(int i = 0; i < MN; i++) for(int j = 0; j < MN; j++) c.T[i][j] = b.T[j][i];
    for(int i = 0; i < MN; i++) {
        for(int j = 0; j < MN; j++) {
            ret.T[i][j] = (a.T[i] & c.T[j]).any();
        }
    }
    return ret;
}

mat exp(mat x, int n) {
    mat ret;
    ret.I();
    while(n) {
        if(n & 1) ret = mult(ret, x);
        x = mult(x, x);
        n >>= 1;
    }
    return ret;
}

int N, M;
struct Edge {
    int u, v, w;
    bool operator <(const Edge &i) const {
        return w < i.w;
    }
};
vector<Edge> edge;
vector<int> X;
mat A, C;

int main() {
    scanf("%d %d", &N, &M);

    for(int i = 0; i < M; i++) {
        int u, v, w; scanf("%d %d %d", &u, &v, &w);
        u--; v--;
        edge.push_back({u, v, w});
        X.push_back(w);
    }
    sort(edge.begin(), edge.end());
    sort(X.begin(), X.end());
    X.resize(unique(X.begin(), X.end()) - X.begin());

    A.O();
    C.I();
    int pos = 0;
    int pre = 0;
    int ans = 2e9;
    for(int i = 0; i < X.size(); i++) {
        mat tmp = exp(A, X[i] - pre);
        C = mult(C, tmp);

        while(pos < M && edge[pos].w <= X[i]) {
            int u = edge[pos].u;
            int v = edge[pos].v;
            A.T[u][v] = 1;
            pos++;
        }

        tmp = C;
        for(int j = 0; j < MN; j++) {
            if(tmp.T[0][N - 1]) {
                ans = min(ans, X[i] + j);
                break;
            }
            tmp = mult(tmp, A);
        }

        pre = X[i];
    }

    if(ans == 2e9) printf("Impossible");
    else printf("%d", ans);
}


#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define outval(x) cerr<<#x" = "<<x<<endl
#define outtag(x) cerr<<"-----------------"#x"-----------------\n"
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
                    For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> pii;
LL read(){
    LL x=0,f=0;
    char ch=getchar();
    while (!isdigit(ch))
        f=ch=='-',ch=getchar();
    while (isdigit(ch))
        x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return f?-x:x;
}
const int N=155,M=155;
int n,m;
struct Mat{
	bitset <N> v[N];
	Mat(){}
	Mat(int x){
		For(i,1,n)
			v[i].reset();
		if (x)
			For(i,1,n)
				v[i][i]=1;
	}
	friend Mat operator * (Mat a,Mat b){
		Mat c(0);
		For(i,1,n)
			For(k,1,n)
				if (a.v[i][k])
					c.v[i]|=b.v[k];
		return c;
	}
	void Out(){
		printf("Matrix {\n");
		For(i,1,n){
			printf("    ");
			For(j,1,n)
				putchar('0'+v[i][j]);
			puts("");
		}
		puts("}\n");
	}
}pre,mat(0),st[35];
struct Edge{
	int x,y,d;
}e[M];
bool cmp(Edge a,Edge b){
	return a.d<b.d;
}
int main(){
	n=read(),m=read();
	pre=Mat(1);
	For(i,1,m)
		e[i].x=read(),e[i].y=read(),e[i].d=read();
	m++;
	e[m].x=n,e[m].y=n,e[m].d=0;
	m++;
	e[m].x=n,e[m].y=n,e[m].d=1.05e9;
	sort(e+1,e+m+1,cmp);
	int now=0;
//	pre.Out(),mat.Out();
	For(i,1,m){
		int x=e[i].x,y=e[i].y,d=e[i].d;
		if (d==now){
			mat.v[x][y]=1;
			continue;
		}
		int c=0;
		st[c]=mat;
		while ((1<<(c+1))<=d)
			c++,st[c]=st[c-1]*st[c-1];
		int ans=d+1;
		Fod(i,c,0){
			if (now+(1<<i)>d)
				continue;
			Mat tmp=pre*st[i];
			if (tmp.v[1][n])
				ans=min(ans,now+(1<<i));
			else {
				now+=1<<i;
				pre=tmp;
			}
		}
		if (ans<=d)
			return printf("%d\n",ans),0;
		mat.v[x][y]=1;
//		outval(x),outval(y),outval(d),outval(c),outval(now);
//		outval(ans);
//		pre.Out(),mat.Out();
	}
	puts("Impossible");
	return 0;
}


#pragma GCC optimize ("O3")
#include<bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define ll long long
#define ld long double
#define clr(x) memset((x),0,sizeof(x))
const int MX = 160, INF = 2e9 + 7;
ll tmp, n, m, ans, dist[MX];
vector <int> adj[MX], vec;
vector <pair<int, pair<int, int>>> edge;
struct mat{
    bitset <MX> val[MX];
    ll n, m;
};
mat operator *(mat A, mat Tmp){
    mat res, B;
    res.n = A.n; res.m = Tmp.m; B.n = Tmp.m; B.m = Tmp.n;
    for(int i = 0; i < Tmp.n; i++)
        for(int j = 0; j < Tmp.m; j++)
            B.val[i][j] = Tmp.val[j][i];
    for(int i = 0; i < res.n; i++)
        for(int j = 0; j < res.m; j++)
            res.val[i][j] = ((A.val[i] & B.val[j]).count() > 0);
    return res;
}
mat Pow(mat A, ll x){
    mat res;
    res.n = A.n; res.m = A.m;
    for(int i = 0; i < A.n; i++) res.val[i][i] = 1;
    for(; x > 0; x /= 2){
        if(x % 2 == 1) res = res * A;
        A = A * A;
    }
    return res;
}
void bfs(){
    fill(dist, dist + MX, INF);
    queue <int> q;
    for(auto pa: vec) dist[pa] = 0, q.push(pa);
    while(q.size()){
        int u = q.front();
        q.pop();
        for(auto pa: adj[u]){
            if(dist[pa] > dist[u] + 1){
                dist[pa] = dist[u] + 1;
                q.push(pa);
            }
        }
    }

}
int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int u, v, d;
        cin >> u >> v >> d;
        v--; u--;
        edge.push_back({d, {u, v}});
    }
    mat A, B;
    A.n = 1; A.m = B.n = B.m = n;
    ans = INF;
    sort(edge.begin(), edge.end());
    if(edge[0].F) return cout << "Impossible", 0;
    int last = 0;
    A.val[0][0] = 1;
    for(int i = 0; i < m; i++){
        int v = edge[i].S.F, u = edge[i].S.S, d = edge[i].F;
        A = A * Pow(B, d - last);
        adj[v].push_back(u);
        for(int j = 0; j < n; j++)
            if(A.val[0][j]) vec.push_back(j);
        bfs();
        vec.clear();
        ans = min(ans, d + dist[n - 1]);
        B.val[v][u] = 1;
        last = d;
    }
    if(ans == INF) return cout << "Impossible", 0;
    cout << ans << endl;

}


#include <bits/stdc++.h>
using namespace std;
const int N = 151;
const int INF = 0x3f3f3f3f;
struct Edge{
    int u,v,d;
}e[N];
bool cmp(Edge a,Edge b){
    return a.d<b.d;
}
vector<int> G[N]; int n,m,p;
struct Matrix{
    int a[N][N];
    void set(){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j) a[i][j]=i==j?1:0;
    }
    void clear(){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j) a[i][j]=0;
    }
}mt,mp,tp;
bitset<N> f[N],g[N],o;
Matrix operator*(Matrix a,Matrix b){
    Matrix rs;
    for(int i=1;i<=n;++i){
        f[i].reset(); g[i].reset();
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(a.a[i][j]) f[i].set(j);
            if(b.a[i][j]) g[j].set(i);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            o=f[i]&g[j];
            if(o.count()) rs.a[i][j]=1;
            else rs.a[i][j]=0;
        }
    }
    return rs;
}
Matrix mpow(Matrix x,int p){
    Matrix rs; rs.set();
    while(p){
        if(p&1) rs=rs*x;
        x=x*x; p>>=1;
    }
    return rs;
}
int dis[N];
bool bfs(int lim){
    queue<int> Q;
    for(int i=1;i<=n;++i) dis[i]=INF;
    for(int i=1;i<=n;++i){
        if(mt.a[1][i]){
            Q.push(i); dis[i]=0;
        }
    }
    while(!Q.empty()){
        int u=Q.front(); Q.pop();
        for(auto i:G[u]){
            int v=e[i].v;
            if(dis[v]==INF){
                dis[v]=dis[u]+1;
                Q.push(v);
            }
        }
    }
    return dis[n]<=lim;
}
int main(){
    scanf("%d %d",&n,&m); p=0;
    for(int i=1;i<=m;++i)
        scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].d);
    sort(e+1,e+1+m,cmp); e[m+1].d=INF;
    mp.clear(); mt.set();
    for(int i=1;i<=m;++i){
        if(bfs(e[i].d)) break;
        mt=mt*mpow(mp,e[i].d-p); p=e[i].d;
        mp.a[e[i].u][e[i].v]=1;
        G[e[i].u].push_back(i);
    }
    if(bfs(INF-1)) printf("%d\n",p+dis[n]);
    else printf("Impossible\n");
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <bitset>
using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <int, pii> pip;

const int MAX_N = 15e1 + 15, inf = 2000 * 1000 * 1000;
ll n, m, ans = inf;
pip edge[MAX_N];
ll dis[MAX_N][MAX_N];

struct matrix {
	bitset <MAX_N> col[MAX_N];
	bitset <MAX_N> row[MAX_N];
	int N, M;

	matrix (int a, int b, int type = 0) {
		N = a, M = b;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < M; j++)
				row[i][j] = col[j][i] = type * (i == j);
	}

	void operator *= (matrix &tmp) {
		if (M != tmp.N)
			exit(-1);

		matrix res(N, tmp.M);
		for (int i = 0; i < N; i++)
			for (int j = 0; j < tmp.M; j++) {
				res.row[i][j] = res.col[j][i] = !(row[i] & tmp.col[j]).none();
			}

		(*this) = res;
	}

	void operator ^= (int val) {
		matrix res(N, M, 1), tmp(N, M);
		tmp = (*this);

		while (val) {
			if (val & 1)
				res *= tmp;

			tmp *= tmp;
			val >>= 1;
		}

		(*this) = res;
	}
};

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int v, u, w;
		cin >> v >> u >> w;

		v--, u--;
		edge[i] = {w, {v, u}};
	}
	matrix A(1, n), B(n, n), C(n, n);

	for (int i = 0; i < n; i++)
		fill(dis[i], dis[i] + MAX_N, inf);

	for (int i = 0; i < n; i++)
		dis[i][i] = 0;

	A.row[0][0] = A.col[0][0] = true;
	sort(edge, edge + m);
	int T = 0;
	for (int i = 0; i < m; i++) {
		C = B;
		C ^= edge[i].first - T;

		T = edge[i].first;
		A *= C;

		int V = edge[i].second.first;
		int U = edge[i].second.second;
		dis[V][U] = min(dis[V][U], 1LL);

		for (int v = 0; v < n; v++)
			for (int u = 0; u < n; u++)
				dis[v][u] = min(dis[v][u], dis[v][V] + dis[V][U] + dis[U][u]);

		for (int i = 0; i < n; i++)
			if (A.row[0][i])
				ans = min(ans, T + dis[i][n - 1]);

		B.row[V][U] = true;
		B.col[U][V] = true;
	}

	if (ans == inf)
		cout << "Impossible\n";
	else
		cout << ans << "\n";
	return 0;
}

// S -> 12:15


#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <bitset>
using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <int, pii> pip;

const int MAX_N = 15e1 + 15, inf = 2000 * 1000 * 1000;
ll n, m, ans = inf;
pip edge[MAX_N];
ll dis[MAX_N][MAX_N];

struct matrix {
	bitset <MAX_N> col[MAX_N];
	bitset <MAX_N> row[MAX_N];
	int N, M;

	matrix (int a, int b, int type = 0) {
		N = a, M = b;
		for (int i = 0; i < N; i++)
			for (int j = 0; j < M; j++)
				row[i][j] = col[j][i] = type * (i == j);
	}

	void operator *= (matrix &tmp) {
		if (M != tmp.N)
			exit(-1);

		matrix res(N, tmp.M);
		for (int i = 0; i < N; i++)
			for (int j = 0; j < tmp.M; j++) {
				res.row[i][j] = res.col[j][i] = !(row[i] & tmp.col[j]).none();
			}

		(*this) = res;
	}

	void operator ^= (int val) {
		matrix res(N, M, 1), tmp(N, M);
		tmp = (*this);

		while (val) {
			if (val & 1)
				res *= tmp;

			tmp *= tmp;
			val >>= 1;
		}

		(*this) = res;
	}
};

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int v, u, w;
		cin >> v >> u >> w;

		v--, u--;
		edge[i] = {w, {v, u}};
	}
	matrix A(1, n), B(n, n), C(n, n);

	for (int i = 0; i < n; i++)
		fill(dis[i], dis[i] + MAX_N, inf);

	for (int i = 0; i < n; i++)
		dis[i][i] = 0;

	A.row[0][0] = A.col[0][0] = true;
	sort(edge, edge + m);
	int T = 0;
	for (int i = 0; i < m; i++) {
		C = B;
		C ^= edge[i].first - T;
		T = edge[i].first;
		A *= C;

		int V = edge[i].second.first;
		int U = edge[i].second.second;
		dis[V][U] = 1;

		for (int v = 0; v < n; v++)
			for (int u = 0; u < n; u++)
				dis[v][u] = min(dis[v][u], dis[v][V] + dis[V][U] + dis[U][u]);

		for (int i = 0; i < n; i++)
			if (A.row[0][i])
				ans = min(ans, T + dis[i][n - 1]);

		B.row[V][U] = true;
		B.col[U][V] = true;
	}

	if (ans == inf)
		cout << "Impossible\n";
	else
		cout << ans << "\n";
	return 0;
}

// S -> 12:15


#include <bits/stdc++.h>
using namespace std;
const int N = 151, INF = 1e9+200;

int n, m, ans = INF, a[N], b[N], d[N];
bool f[N][N], dp[31][N][N];
vector<int> g[N];

void calc(int k, int u, int v) {
	if(dp[k][u][v]) return;
	dp[k][u][v] = true;
	if(k >= 30) return;
	for(int i = 1; i <= n; i++) {
		if(dp[k][i][u]) calc(k+1, i, v);
		if(dp[k][v][i]) calc(k+1, u, i);
	}
}

int bfs(int i) {
	queue<int> q;
	int dist[N];
	fill(dist+1, dist+n+1, INF);
	for(int u = 1; u <= n; u++) if(f[i][u]) {
		q.push(u);
		dist[u] = 0;
	}
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		for(int v: g[u]) if(dist[v] == INF) {
			dist[v] = dist[u] + 1;
			q.push(v);
		}
	}
	return d[i] + dist[n];
}

int main() {
	cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		cin >> a[i] >> b[i] >> d[i];
		for(int j = i; j >= 1 && d[j] < d[j-1]; j--) {
			swap(a[j], a[j-1]);
			swap(b[j], b[j-1]);
			swap(d[j], d[j-1]);
		}
	}
	int start = 1;
	while(start <= m && !d[start]) {
		calc(0, a[start], b[start]);
		g[a[start]].push_back(b[start]);
		f[start][1] = true;
		ans = min(bfs(start), ans);
		++start;
	}

	for(int i = start; i <= m; i++) {
		for(int u = 1; u <= n; u++) f[i][u] = f[i-1][u];
		for(int j = 30; j >= 0; j--) if(d[i] - d[i-1] >> j & 1) {
			bool tmp[N];
			fill(tmp+1, tmp+n+1, 0);
			for(int u = 1; u <= n; u++) for(int v = 1; v <= n; v++) tmp[v] |= f[i][u] & dp[j][u][v];
			for(int u = 1; u <= n; u++) f[i][u] = tmp[u];
		}

		calc(0, a[i], b[i]);
		g[a[i]].push_back(b[i]);

		ans = min(bfs(i), ans);
	}
	if(ans == INF) cout << "Impossible";
	else cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 151, INF = 1e9+1;

int n, m, ans = INF, a[N], b[N], d[N];
bool f[N][N], dp[31][N][N];
vector<int> g[N];

void calc(int k, int u, int v) {
	if(dp[k][u][v]) return;
	dp[k][u][v] = true;
	if(k >= 30) return;
	for(int i = 1; i <= n; i++) {
		if(dp[k][i][u]) calc(k+1, i, v);
		if(dp[k][v][i]) calc(k+1, u, i);
	}
}

int main() {
	cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		cin >> a[i] >> b[i] >> d[i];
		for(int j = i; j >= 1 && d[j] < d[j-1]; j--) {
			swap(a[j], a[j-1]);
			swap(b[j], b[j-1]);
			swap(d[j], d[j-1]);
		}
	}
	int start = 1;
	while(start <= m && !d[start]) {
		calc(0, a[start], b[start]);
		g[a[start]].push_back(b[start]);
		f[start][1] = true;
		++start;
	}

	for(int i = start; i <= m; i++) {
		// get f[i]
		for(int u = 1; u <= n; u++) f[i][u] = f[i-1][u];
		for(int j = 30; j >= 0; j--) if(d[i] - d[i-1] >> j & 1) {
			bool tmp[N];
			fill(tmp+1, tmp+n+1, 0);
			for(int u = 1; u <= n; u++) for(int v = 1; v <= n; v++) tmp[v] |= f[i][u] & dp[j][u][v];
			for(int u = 1; u <= n; u++) f[i][u] = tmp[u];
		}

		//update
		calc(0, a[i], b[i]);
		g[a[i]].push_back(b[i]);

		// bfs
		queue<int> q;
		int dist[N];
		fill(dist+1, dist+n+1, INF);
		for(int u = 1; u <= n; u++) if(f[i][u]) {
			q.push(u);
			dist[u] = 0;
		}
		while(!q.empty()) {
			int u = q.front();
			q.pop();
			for(int v: g[u]) if(dist[v] == INF) {
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
		ans = min(d[i] + dist[n], ans);
	}
	if(ans == INF) cout << "Impossible";
	else cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 151, INF = 1e9+1;

int n, m, ans = INF, a[N], b[N], d[N];
bool f[N][N], dp[31][N][N];
vector<int> g[N];

void calc(int k, int u, int v) {
	if(dp[k][u][v]) return;
	dp[k][u][v] = true;
	if(k >= 30) return;
	for(int i = 1; i <= n; i++) {
		if(dp[k][i][u]) calc(k+1, i, v);
		if(dp[k][v][i]) calc(k+1, u, i);
	}
}

int bfs(int i) {
	queue<int> q;
	int dist[N];
	fill(dist+1, dist+n+1, INF);
	for(int u = 1; u <= n; u++) if(f[i][u]) {
		q.push(u);
		dist[u] = 0;
	}
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		for(int v: g[u]) if(dist[v] == INF) {
			dist[v] = dist[u] + 1;
			q.push(v);
		}
	}
	return d[i] + dist[n];
}

int main() {
	cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		cin >> a[i] >> b[i] >> d[i];
		for(int j = i; j >= 1 && d[j] < d[j-1]; j--) {
			swap(a[j], a[j-1]);
			swap(b[j], b[j-1]);
			swap(d[j], d[j-1]);
		}
	}
	int start = 1;
	while(start <= m && !d[start]) {
		calc(0, a[start], b[start]);
		g[a[start]].push_back(b[start]);
		f[start][1] = true;
		ans = min(bfs(start), ans);
		++start;
	}

	for(int i = start; i <= m; i++) {
		for(int u = 1; u <= n; u++) f[i][u] = f[i-1][u];
		for(int j = 30; j >= 0; j--) if(d[i] - d[i-1] >> j & 1) {
			bool tmp[N];
			fill(tmp+1, tmp+n+1, 0);
			for(int u = 1; u <= n; u++) for(int v = 1; v <= n; v++) tmp[v] |= f[i][u] & dp[j][u][v];
			for(int u = 1; u <= n; u++) f[i][u] = tmp[u];
		}

		calc(0, a[i], b[i]);
		g[a[i]].push_back(b[i]);

		ans = min(bfs(i), ans);
	}
	if(ans == INF) cout << "Impossible";
	else cout << ans;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
template<typename tn> void read(tn &a){
	tn x=0,f=1; char c=' ';
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	a=x*f;
}
int n,m,ans,dis[150];
vector<int> e[150];
map<int,vector<pair<int,int> > > mp;
struct matrix{
	bitset<160> a[160],b[160];
	void set(int x,int y){a[x][y]=1;b[y][x]=1;}
	matrix operator * (const matrix&p){
		matrix ans;
		memset(&ans,0,sizeof(ans));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				ans.b[j][i]=ans.a[i][j]=(a[i]&p.b[j]).any();
		return ans;
	}
}M,T;
matrix mfp(matrix a,ll k){
	matrix ans;
	memset(&ans,0,sizeof(ans));
	for(int i=1;i<=n;i++) ans.set(i,i);
	for(;k;k>>=1,a=a*a)
		if(k&1) ans=a*ans;
	return ans;
}
void solve(int now){
	memset(dis,63,sizeof(dis));
	queue<int> q;
	for(int i=1;i<=n;i++)
		if(T.a[i][1]) dis[i]=now,q.push(i);
	while(!q.empty()){
		int u=q.front();q.pop();
		if(u==n) ans=min(ans,dis[u]);
		for(int v:e[u]) if(dis[v]>dis[u]+1){
			dis[v]=dis[u]+1;
			q.push(v);
		}
	}
}
int main(){
	read(n);read(m);
	ans=2e9;
	for(int i=1;i<=m;i++){
		int x,y,z;read(x);read(y);read(z);
		mp[z].emplace_back(x,y);
	}
	T.set(1,1);
	int lst=0;
	for(auto p:mp){
		for(auto E:p.second) e[E.first].push_back(E.second);
		T=mfp(M,p.first-lst)*T;
		solve(p.first);
		for(auto E:p.second)
			M.set(E.second,E.first);
		lst=p.first;
	}
	if(ans>1.1e9) cout<<"Impossible\n";
	else cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
template<typename tn> void read(tn &a){
	tn x=0,f=1; char c=' ';
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	a=x*f;
}
int n,m,ans,dis[160];
vector<int> e[160];
map<int,vector<pair<int,int> > > mp;
struct matrix{
	bitset<160> a[160],b[160];
	void set(int x,int y){a[x][y]=1;b[y][x]=1;}
	matrix operator * (const matrix&p){
		matrix ans;
		memset(&ans,0,sizeof(ans));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				ans.b[j][i]=ans.a[i][j]=(a[i]&p.b[j]).any();
		return ans;
	}
}M,T;
matrix mfp(matrix a,ll k){
	matrix ans;
	memset(&ans,0,sizeof(ans));
	for(int i=1;i<=n;i++) ans.set(i,i);
	for(;k;k>>=1,a=a*a)
		if(k&1) ans=a*ans;
	return ans;
}
void solve(int now){
	memset(dis,63,sizeof(dis));
	queue<int> q;
	for(int i=1;i<=n;i++)
		if(T.a[i][1]) dis[i]=now,q.push(i);
	while(!q.empty()){
		int u=q.front();q.pop();
		if(u==n) ans=min(ans,dis[u]);
		for(int v:e[u]) if(dis[v]>dis[u]+1){
			dis[v]=dis[u]+1;
			q.push(v);
		}
	}
}
int main(){
	read(n);read(m);
	ans=2e9;
	for(int i=1;i<=m;i++){
		int x,y,z;read(x);read(y);read(z);
		mp[z].emplace_back(x,y);
	}
	T.set(1,1);
	int lst=0;
	for(auto p:mp){
		for(auto E:p.second) e[E.first].push_back(E.second);
		T=mfp(M,p.first-lst)*T;
		solve(p.first);
		for(auto E:p.second)
			M.set(E.second,E.first);
		lst=p.first;
	}
	if(ans>1.1e9) cout<<"Impossible\n";
	else cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 155;
int n,m,dis[N];
struct Edge {int u,v,w;} e[N];
using B = bitset<N>;
struct Matrix
{
    B a[N];
    B &operator[](const size_t &n) {return a[n];}
};
// a[i][j] == 1:There is a way from j to i
B operator*(B a,Matrix b)
{
    B c;
    for (int i = 0;i < n;i++) c[i] = (a & b[i]).any();
    return c;
}
Matrix operator*(Matrix a,Matrix b)
{
    Matrix c;
    for (int i = 0;i < n;i++)
        for (int j = 0;j < n;j++)
            if (a[i][j]) c[i] |= b[j];
    return c;
}
void qpow(Matrix a,int b,B &c)
{
    while (b)
    {
        if (b & 1) c = c * a;
        a = a * a;b >>= 1;
    }
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= m;i++)
        cin >> e[i].u >> e[i].v >> e[i].w,--e[i].u,--e[i].v;
    B vis;vis[0] = 1;Matrix a;
    int ans = INT_MAX;sort(e + 1,e + m + 1,[](Edge a,Edge b) {return a.w < b.w;});
    for (int i = 1;i <= m && e[i].w <= ans;i++)
    {
        qpow(a,e[i].w - e[i - 1].w,vis);
        a[e[i].v][e[i].u] = 1;queue<int> q;
        for (int j = 0;j < n;j++)
            if (!vis[j]) dis[j] = -1;else dis[j] = 0,q.push(j);
        while (q.size())
        {
            int nd = q.front();q.pop();
            for (int j = 0;j < n;j++)
                if (a[j][nd] && dis[j] == -1) dis[j] = dis[nd] + 1,q.push(j);
        }
        if (dis[n - 1] != -1) ans = min(ans,e[i].w + dis[n - 1]);
    }
    if (ans != INT_MAX) cout << ans << endl;
    else cout << "Impossible" << endl;
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
#include<bitset>
using namespace std;
const int N=155;
int n,m,dis[N],q[N],hd,tl,ans=1<<30;vector<int>E[N];
struct edge{
	int x,y,z;
	bool operator < (const edge &b)const{
		return z<b.z;
	}
}a[N];
struct matrix{
	bitset<N>s[N];
	matrix(){
		for(int i=1;i<=n;++i)s[i].reset();
	}
	matrix operator * (matrix b){
		matrix c;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				c.s[j][i]=b.s[i][j];
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				b.s[i][j]=(s[i]&c.s[j]).any();
		return b;
	}
}now,G;
matrix fastpow(matrix x,int y){
	matrix res;
	for(int i=1;i<=n;++i)res.s[i][i]=1;
	while(y){if(y&1)res=res*x;x=x*x;y>>=1;}
	return res;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i)
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1);now.s[1][1]=1;
	for(int i=1;i<=m;++i)
		E[a[i].x].push_back(i);
	for(int i=1;i<=m;++i){
		now=now*fastpow(G,a[i].z-a[i-1].z);
		G.s[a[i].x][a[i].y]=1;
		hd=1;tl=0;
		for(int j=1;j<=n;++j)
			if(now.s[1][j])dis[q[++tl]=j]=0;
			else dis[j]=1<<30;
		while(hd<=tl){
			int u=q[hd++];
			for(int e:E[u])
				if(e<=i&&dis[a[e].y]>dis[u]+1)
					dis[q[++tl]=a[e].y]=dis[u]+1;
		}
		ans=min(ans,a[i].z+dis[n]);
	}
	if(ans==1<<30)puts("Impossible");
	else printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 155, inF = 1e9 + N;

int n, m, dis[N][N];
int ans = inF;

struct EDGE {
	int u, v, d;
	void input() {
		cin >> u >> v >> d;
		u--, v--;
	}
	bool operator<(EDGE x) {
		return d < x.d;
	}
} edge[N];

struct MAT {
	bitset<N> b[N];
	MAT(bool B = true) {
		for (int i = 0; i < N; i++) {
			b[i].reset();
			b[i][i] = B;
		}
	}
	MAT operator*(MAT x) {
		MAT res(false);
		for (int u = 0; u < n; u++)
			for (int v = 0; v < n; v++)
				if(b[u][v])
					res.b[u] |= x.b[v];
		return res;
	}
	void operator*=(MAT x) {
		*this = (*this) * x;
	}
} now, updater(false);

MAT power(MAT a, int b) {
	MAT res;
	while(b) {
		if(b & 1)
			res *= a;
		a *= a;
		b >>= 1;
	}
	return res;
}

void add_edge(int u, int v) {
	updater.b[u][v] = true;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			dis[i][j] = min(dis[i][j], dis[i][v] + dis[u][j] + 1);
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0);
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		fill(dis[i], dis[i] + n, inF);
		dis[i][i] = 0;
	}
	for (int i = 0; i < m; i++)
		edge[i].input();
	sort(edge, edge + m);
	int last = 0;
	for (int i = 0; i < m; i++) {
		now *= power(updater, edge[i].d - last);
		add_edge(edge[i].u, edge[i].v);
		last = edge[i].d;
		for (int i = 0; i < n; i++)
			if(now.b[0][i])
				ans = min(ans, last + dis[n - 1][i]);
	}
	if(ans == inF)
		cout << "Impossible";
	else
		cout << ans;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define per(i, a, b) for(int i=(b)-1; i>=(a); i--)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int P = 1e9 + 7;
int add(int a, int b) {if((a += b) >= P) a -= P; return a;}
int sub(int a, int b) {if((a -= b) < 0) a += P; return a;}
int mul(int a, int b) {return 1ll * a * b % P;}
int kpow(int a, int b) {int r=1;for(;b;b>>=1,a=mul(a,a)) {if(b&1)r=mul(r,a);}return r;}
//---

const int N = 155;

int n, mm;
pair<int, pii> e[N];

struct M {
	static const int N = ::N;
	bool a[N][N];
	bitset<N> hang[N], lie[N];
	M() {rep(i, 0, n) rep(j, 0, n) a[i][j] = 0;}
	M operator * (const M &c) const {
		M r;
		rep(i, 0, n) rep(j, 0, n) {
			auto t = (hang[i] & c.lie[j]);
			bool _ = t.count();
			r.a[i][j] = r.hang[i][j] = r.lie[j][i] = _;
		}
		return r;
	}
	vi operator * (const vi &c) const {
		vi r;
		rep(j, 0, n) {
			int t = 0;
			rep(i, 0, n) t |= (a[i][j] & c[i]);
			r.pb(t);
		}
		return r;
	}
	void set() { rep(i, 0, n) a[i][i] = hang[i][i] = lie[i][i] = 1; }
	void print() {
		rep(i, 0, n) {
			rep(j, 0, n) cout << a[i][j];
			cout << endl;
		}
		cout << endl;
	}
};

M m, t;
vi v;

void print(vi v) {
	for(auto u : v) cout << u;
	cout << endl << endl;
}

M kpow(M a, int b) {
	M r;
	r.set();
	while(b) {
		if(b & 1) r = r * a;
		a = a * a;
		b >>= 1;
	}
	return r;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	cin >> n >> mm;
	rep(i, 1, mm+1) cin >> e[i].se.fi >> e[i].se.se >> e[i].fi, --e[i].se.fi, --e[i].se.se;
	sort(e + 1, e + 1 + mm);
	int now = 0, cnt = 0;
	rep(i, 0, n) v.pb(i == 0);
	rep(i, 1, mm+1) {
		if(e[i].fi == now) {
			int u = e[i].se.fi, v = e[i].se.se;
			m.a[u][v] = m.hang[u][v] = m.lie[v][u] = 1;
		} else {
			int x = e[i].fi - now;
			now = e[i].fi;
			t = kpow(m, x);
			vi k = t * v;
			if(k[n-1]) break;
			else v = k, cnt += x;
			--i;
		}
	}
	for(int i = 1; i < n + n && !v[n-1]; ++i) {
		v = m * v;
		++cnt;
	}
	if(v[n-1]) cout << cnt << endl;
	else cout << "Impossible" << endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(d[y]==inf)d[y]=d[x]+1,q.push(y);
	}return d[n];
}
void Ins(int i){
	int x=p[i].x,y=p[i].y;
	G[x].push_back(y),E.p[x][y]=1;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp);
	for(int i=1;i<=m;i++){
		Matrix R=KSM(E,p[i].v);Ins(i);
		while(i<m&&p[i+1].v==p[i].v)Ins(++i);
		Ans=min(Ans,BFS(R)+p[i].v);
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;
	memset(vis,0,sizeof(vis)),memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])vis[i]=1,d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(!vis[y])vis[y]=1,d[y]=d[x]+1,q.push(y);
	}return d[n];
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp);
	if(p[m].v==1e9)for(int i=1;i<=m;i++)cout<<p[i].v<<" ";cout<<endl;
	for(int i=1;i<=m;i++){
		int x=p[i].x,y=p[i].y;
		G[x].push_back(y);
		Ans=min(Ans,BFS(KSM(E,p[i].v))+p[i].v);
		E.p[x][y]=1;
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;
	memset(vis,0,sizeof(vis)),memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])vis[i]=1,d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(!vis[y])vis[y]=1,d[y]=d[x]+1,q.push(y);
	}return d[n];
}
void Ins(int i){
	int x=p[i].x,y=p[i].y;
	G[x].push_back(y),E.p[x][y]=1;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp);
	for(int i=1;i<=m;i++){
		Matrix R=KSM(E,p[i].v);Ins(i);
		while(i<m&&p[i+1].v==p[i].v)Ins(++i);
		Ans=min(Ans,BFS(R)+p[i].v);
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E,T;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(d[y]==inf)d[y]=d[x]+1,q.push(y);
	}return d[n];
}
void Ins(int i){
	int x=p[i].x,y=p[i].y;
	G[x].push_back(y),E.p[x][y]=1;
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp),T.Init();
	for(int i=1;i<=m;i++){
		T=T*KSM(E,p[i].v-p[i-1].v);Ins(i);
//		while(i<m&&p[i+1].v==p[i].v)Ins(++i);
		Ans=min(Ans,BFS(T)+p[i].v);
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;
	memset(vis,0,sizeof(vis)),memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])vis[i]=1,d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(!vis[y])vis[y]=1,d[y]=d[x]+1,q.push(y);
	}return d[n];
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp);
	for(int i=1;i<=m;i++){
		int x=p[i].x,y=p[i].y;
		G[x].push_back(y);
		Ans=min(Ans,BFS(KSM(E,p[i].v))+p[i].v);
		E.p[x][y]=1;
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define re register
#define ull unsigned ll
using namespace std;
inline int read(){
	int s=0,t=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*t;
}
#define Node bitset<N>
const int N=155;
const int inf=0x3f3f3f3f;
vector<int> G[N];
int n,m,Ans=inf,vis[N],d[N];
struct edge{int x,y,v;}p[N];
struct Matrix{
	Node p[N];
	Matrix(){for(int i=1;i<=n;i++)p[i].reset();}
	void Init(){for(int i=1;i<=n;i++)p[i][i]=1;}
	friend Matrix operator*(Matrix A,Matrix B){
		Matrix C;
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)if(A.p[i][j])C.p[i]|=B.p[j];
		return C;
	}
}E;
bool cmp(edge A,edge B){return A.v<B.v;}
Matrix KSM(Matrix A,int k){
	Matrix R;R.Init();
	while(k){
		if(k&1)R=R*A;
		A=A*A,k>>=1;
	}return R;
}
int BFS(Matrix R){
	queue<int> q;
	memset(vis,0,sizeof(vis)),memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)if(R.p[1][i])vis[i]=1,d[i]=0,q.push(i);
	while(q.size()){
		int x=q.front();q.pop();
		for(auto y:G[x])if(!vis[y])vis[y]=1,d[y]=d[x]+1,q.push(y);
	}return d[n];
}
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=m;i++)p[i]=(edge){read(),read(),read()};
	sort(p+1,p+m+1,cmp);

	if(p[m].v==1e9)cout<<p[1].x<<" "<<p[1].y<<endl;
	for(int i=1;i<=m;i++){
		int x=p[i].x,y=p[i].y;
		G[x].push_back(y);
		Ans=min(Ans,BFS(KSM(E,p[i].v))+p[i].v);
		E.p[x][y]=1;
	}
	if(Ans==inf)printf("Impossible");
	else printf("%d",Ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long MOD=1000000009;
const int MAXN = 151;
typedef long long ll;
struct matrix{
    int n;
    bitset < MAXN > A[MAXN] , B[MAXN];
    matrix(){}
    matrix(int x){
        n = x;
        for(int j = 1 ; j <= n ; j++)
            A[j].reset() , B[j].reset();
    }
    matrix operator * (matrix &mat){
        matrix res(n);
        for(int j = 1 ; j <= n ; j++)
            for(int i = 1 ; i <= n ; i++){
                bitset < MAXN > jd3 = (A[j]&mat.B[i]);
                if(jd3.any()) res.A[j][i] = res.B[i][j] = 1;
            }
        return res;
    }
    matrix power(long long K){
        matrix res(n) , b(n);
        for(int j=0;j<n;j++) res.A[j][j] = res.B[j][j] = 1;
        b = (*this);
        while(K>0){
            if( (K&1) )
                res = res * b;
            K/=2;
            b = b * b;
        }
        return res;
    }
};
const int MX = 160 , inf = (1<<29);
int lim[MX] , uu[MX] , vv[MX];
bool cmp(int a , int b){
    return lim[a] < lim[b];
}
int n , floyd[MX][MX];
void init(){
    for(int a = 1 ; a <= n ; a++){
        for(int b = 1 ; b <= n ; b++)
            floyd[a][b] = inf;
        floyd[a][a] = 0;
    }
}
void go(){
      for(int a = 1 ; a <= n ; a++)
            for(int b = 1 ; b <= n ; b++)
                for(int c = 1 ; c <= n ; c++)
                    floyd[b][c] = min(floyd[b][c] , floyd[b][a] + floyd[a][c]);
}
int m;
int main(){
    cin>>n>>m;
    vector < int > sorted;
    for(int j =1 ; j <= m ;j++){
        cin>>uu[j]>>vv[j]>>lim[j];
        sorted.push_back(j);
    }
    for(int j = 1 ; j <= m ; j++)
        for(int i = j + 1 ; i <= m ; i++)
            if(lim[j] > lim[i])
                swap(lim[j] , lim[i]) , swap(uu[j] , uu[i]) , swap(vv[j] , vv[i]);
    if(lim[1] != 0){
        puts("Impossible");
        return 0;
    }
    int it1 = 1;
    init();
    while(lim[it1] == 0){
        floyd[uu[it1]][vv[it1]] = 1;
        ++it1;
    }
    int ans = inf;
    ans = min(ans , floyd[1][n]);
    matrix MAT = matrix(n);
    for(int j = 1 ; j <= n ; j++) MAT.A[j][j] = MAT.B[j][j] = 1;
    for(it1 ; it1 <= n ;){
        //cout<<"#step "<<it1<<endl;
        matrix MUL = matrix(n);
        for(int j = 1 ; j < it1 ; j++){
            MUL.A[uu[j]][vv[j]] = 1;
            MUL.B[vv[j]][uu[j]] = 1;
           // cout<<uu[j]<<' '<<vv[j]<<endl;
        }
        int K = lim[it1] - lim[it1 - 1];
        MUL = MUL.power(K);
        MAT = MAT * MUL;
        int it2 = it1;
        while(lim[it2+1] == lim[it1]) ++it2;
        init();
        for(int j = 1 ; j <= it2 ; j++)
            floyd[uu[j]][vv[j]] = 1;
        go();
        for(int a = 1 ; a <= n ; a++){
            if(MAT.A[1][a]){
                ans = min(ans , lim[it1] + floyd[a][n]);
               // cout<<it1<<' '<<1<<' '<<a<<endl;
            }
        }
        it1 = it2 + 1;

    }
    if(ans == inf) puts("Impossible");
    else cout<<ans<<endl;

}


#include<bits/stdc++.h>
using namespace std;
long long MOD=1000000009;
const int MAXN = 151;
typedef long long ll;
struct matrix{
    int n;
    bitset < MAXN > A[MAXN] , B[MAXN];
    matrix(){}
    matrix(int x){
        n = x;
        for(int j = 1 ; j <= n ; j++)
            A[j].reset() , B[j].reset();
    }
    matrix operator * (matrix &mat){
        matrix res(n);
        for(int j = 1 ; j <= n ; j++)
            for(int i = 1 ; i <= n ; i++){
                bitset < MAXN > jd3 = (A[j]&B[i]);
                if(jd3.any()) res.A[j][i] = res.B[i][j] = 1;
            }
        return res;
    }
    matrix power(long long K){
        matrix res(n) , b(n);
        for(int j=0;j<n;j++) res.A[j][j] = res.B[j][j] = 1;
        b = (*this);
        while(K>0){
            if( (K&1) )
                res = res * b;
            K/=2;
            b = b * b;
        }
        return res;
    }
};
const int MX = 160 , inf = (1<<29);
int lim[MX] , uu[MX] , vv[MX];
bool cmp(int a , int b){
    return lim[a] < lim[b];
}
int n , floyd[MX][MX];
void init(){
    for(int a = 1 ; a <= n ; a++){
        for(int b = 1 ; b <= n ; b++)
            floyd[a][b] = inf;
        floyd[a][a] = 0;
    }
}
void go(){
      for(int a = 1 ; a <= n ; a++)
            for(int b = 1 ; b <= n ; b++)
                for(int c = 1 ; c <= n ; c++)
                    floyd[b][c] = min(floyd[b][c] , floyd[b][a] + floyd[a][c]);
}
int m;
int main(){
    cin>>n>>m;
    vector < int > sorted;
    for(int j =1 ; j <= m ;j++){
        cin>>uu[j]>>vv[j]>>lim[j];
        sorted.push_back(j);
    }
    for(int j = 1 ; j <= m ; j++)
        for(int i = j + 1 ; i <= m ; i++)
            if(lim[j] > lim[i])
                swap(lim[j] , lim[i]) , swap(uu[j] , uu[i]) , swap(vv[j] , vv[i]);
    if(lim[1] != 0){
        puts("Impossible");
        return 0;
    }
    int it1 = 1;
    init();
    while(lim[it1] == 0){
        floyd[uu[it1]][vv[it1]] = 1;
        ++it1;
    }
    int ans = inf;
    ans = min(ans , floyd[1][n]);
    matrix MAT = matrix(n);
    for(int j = 1 ; j <= n ; j++) MAT.A[j][j] = MAT.B[j][j] = 1;
    for(it1 ; it1 <= n ;){
        matrix MUL = matrix(n);
        for(int j = 1 ; j < it1 ; j++){
            MUL.A[uu[j]][vv[j]] = 1;
            MUL.B[vv[j]][uu[j]] = 1;
        }
        int K = lim[it1] - lim[it1 - 1];
        MUL = MUL.power(K);
        MAT = MAT * MUL;
        int it2 = it1;
        while(lim[it2+1] == lim[it1]) ++it2;
        init();
        for(int j = 1 ; j <= it2 ; j++)
            floyd[uu[j]][vv[j]] = 1;
        go();
        for(int a = 1 ; a <= n ; a++)
            if(MAT.A[1][a])
                ans = min(ans , lim[it1] + floyd[a][n]);
        it1 = it2 + 1;

    }
    if(ans == inf) puts("Impossible");
    else cout<<ans<<endl;

}


#include<bits/stdc++.h>
using namespace std;
long long MOD=1000000009;
const int MAXN = 151;
typedef long long ll;
struct matrix{
    int n;
    bitset < MAXN > A[MAXN] , B[MAXN];
    matrix(){}
    matrix(int x){
        n = x;
        for(int j = 1 ; j <= n ; j++)
            A[j].reset() , B[j].reset();
    }
    matrix operator * (matrix &mat){
        matrix res(n);
        for(int j = 1 ; j <= n ; j++)
            for(int i = 1 ; i <= n ; i++){
                bitset < MAXN > jd3 = (A[j]&mat.B[i]);
                if(jd3.any()) res.A[j][i] = res.B[i][j] = 1;
            }
        return res;
    }
    matrix power(long long K){
        matrix res(n) , b(n);
        for(int j=0;j<n;j++) res.A[j][j] = res.B[j][j] = 1;
        b = (*this);
        while(K>0){
            if( (K&1) )
                res = res * b;
            K/=2;
            b = b * b;
        }
        return res;
    }
};
const int MX = 160 , inf = (1<<29);
int lim[MX] , uu[MX] , vv[MX];
bool cmp(int a , int b){
    return lim[a] < lim[b];
}
int n , floyd[MX][MX];
void init(){
    for(int a = 1 ; a <= n ; a++){
        for(int b = 1 ; b <= n ; b++)
            floyd[a][b] = inf;
        floyd[a][a] = 0;
    }
}
void go(){
      for(int a = 1 ; a <= n ; a++)
            for(int b = 1 ; b <= n ; b++)
                for(int c = 1 ; c <= n ; c++)
                    floyd[b][c] = min(floyd[b][c] , floyd[b][a] + floyd[a][c]);
}
int m;
int main(){
    cin>>n>>m;
    vector < int > sorted;
    for(int j =1 ; j <= m ;j++){
        cin>>uu[j]>>vv[j]>>lim[j];
        sorted.push_back(j);
    }
    for(int j = 1 ; j <= m ; j++)
        for(int i = j + 1 ; i <= m ; i++)
            if(lim[j] > lim[i])
                swap(lim[j] , lim[i]) , swap(uu[j] , uu[i]) , swap(vv[j] , vv[i]);
    if(lim[1] != 0){
        puts("Impossible");
        return 0;
    }
    int it1 = 1;
    init();
    while(lim[it1] == 0){
        floyd[uu[it1]][vv[it1]] = 1;
        ++it1;
    }
    int ans = inf;
    ans = min(ans , floyd[1][n]);
    matrix MAT = matrix(n);
    for(int j = 1 ; j <= n ; j++) MAT.A[j][j] = MAT.B[j][j] = 1;
    //cout<<it1<<endl;
    for(it1 ; it1 <= m ;){
        //cout<<"#step "<<it1<<endl;
        matrix MUL = matrix(n);
        for(int j = 1 ; j < it1 ; j++){
            MUL.A[uu[j]][vv[j]] = 1;
            MUL.B[vv[j]][uu[j]] = 1;
           // cout<<uu[j]<<' '<<vv[j]<<endl;
        }
        int K = lim[it1] - lim[it1 - 1];
        MUL = MUL.power(K);
        MAT = MAT * MUL;
        int it2 = it1;
        while(lim[it2+1] == lim[it1]) ++it2;
        init();
        for(int j = 1 ; j <= it2 ; j++)
            floyd[uu[j]][vv[j]] = 1;
        go();
        for(int a = 1 ; a <= n ; a++){
            if(MAT.A[1][a]){
                ans = min(ans , lim[it1] + floyd[a][n]);
                //cout<<lim[it1]<<' '<<a<<' '<<floyd[a][n]<<endl;
               // cout<<it1<<' '<<1<<' '<<a<<endl;
            }
        }
        it1 = it2 + 1;

    }
    if(ans == inf) puts("Impossible");
    else cout<<ans<<endl;

}