#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
#include <bitset>
using namespace std;
#define N 155
bool vis[N];bitset<N> a[N];
int dis[N],n,m;
struct node
{
	bitset<N> a[N];
	friend node operator*(const node &a,const node &b)
	{
		node c;memset(c.a,0,sizeof(c.a));
		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;
	}
}map,ret;
struct no
{
	int x,y,d;
	friend bool operator<(const no &a,const no &b)
	{
		return a.d<b.d;
	}
}E[N];
/*
void print(const node &a)
{
	puts("");
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			printf("%d ",a.a[i][j]);
		}
		puts("");
	}
	puts("");
}
*/
void q_pow(int x)
{
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map.a[i][j]=a[i][j];
	while(x)
	{
		if(x&1)ret=ret*map;
		map=map*map,x=x>>1;
	}
}
bool bfs()
{
	queue <int >q;memset(dis,0,sizeof(dis));memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++)if(ret.a[1][i])q.push(i),vis[i]=1,dis[i]=0;
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int i=1;i<=n;i++)
		{
			if(a[x][i]&&!vis[i])vis[i]=1,dis[i]=dis[x]+1,q.push(i);
		}
	}
	return vis[n];
}
int main()
{
	// freopen("travel.in","r",stdin);
	// freopen("travel.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].d);
	sort(E+1,E+m+1);int last=0,j=0;ret.a[1][1]=1;
	while(1)
	{
		for(int i=j+1;i<=m;i++)
		{
			if(E[i].d>last)break;
			a[E[i].x][E[i].y]=1;j++;
		}
		if(bfs()){printf("%d\n",last+dis[n]);break;}
		if(j==m)return 0;
		q_pow(E[j+1].d-last);//print(ret);
		last=E[j+1].d;
	}
	return 0;
}


#include<cstdio>
#include<bitset>
#include<algorithm>
using namespace std;
const int N=155,oo=1050000000;
int i,j,k,n,m,ans;
struct cc {
	int x,y,v;
	bool operator < (const cc &n) const {
		return v<n.v;
	}
} A[N];
struct matrix {
	bitset<N> a[N];
	matrix operator * (const matrix &nt) const {
		matrix t;
		int i,j;
		for (i=1;i<=n;i++)
			for (j=1;j<=n;j++) if (a[i][j]) t.a[i]|=nt.a[j];
		return t;
	}
} now,tmp,B[32];
int main() {
	scanf("%d%d",&n,&m);
	ans=-1;
	now.a[1][1]=1;
	B[0].a[n][n]=1;
	for (i=1;i<=m;i++) scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].v);
	sort(A+1,A+m+1);
	if (A[1].v) return puts("Impossible"),0;
	A[m+1].v=oo;
	for (i=1;i<=m;i++) {
		//printf("%d\n",i);
		j=i;
		while (A[i].v==A[j].v) {
			B[0].a[A[j].x][A[j].y]=1;
			j++;
		}
		int t=A[j].v-A[i].v,tt=0;
		while ((1<<tt+1)<=t) tt++;
		//printf("%d\n",tt);
		for (k=1;k<=tt;k++) B[k]=B[k-1]*B[k-1];
		//printf("%d %d %d\n",(int) B[0].a[1][2],(int) B[0].a[2][3],(int) B[0].a[1][3]);
		//printf("%d %d %d\n",(int) B[1].a[1][2],(int) B[1].a[2][3],(int) B[1].a[1][3]);
		for (k=tt;k>=0;k--) if (ans+(1<<k)<A[j].v) {
			tmp=now*B[k];
			if (tmp.a[1][n]) continue;
			now=tmp;ans+=1<<k;
		}
		if (ans+1<A[j].v) {
			ans++;
			printf("%d\n",ans+1);
			return 0;
		}
		i=j-1;
		//printf("%d %d %d\n",(int) now.a[1][2],(int) now.a[2][3],(int) now.a[1][3]);
		//printf("%d %d %d\n",(int) B[1].a[1][2],(int) B[1].a[2][3],(int) B[1].a[1][3]);
	}
	puts("Impossible");
}


#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
using namespace std;
const int N=160,inf=0x3f3f3f3f;
struct cyc{int x,y,d;}e[N];
int n,m,mp[N][N];
bitset<N>a[N],ans[N],c[N],z[N];
bool cmp(cyc a,cyc b){return a.d<b.d;}
void mul(bitset<N>a[N],bitset<N>b[N]){
	for(int i=1;i<=n;i++)c[i].reset();
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	if(a[i][k])c[i]|=b[k];
	for(int i=1;i<=n;i++)a[i]=c[i];
}
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].d);
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++)ans[i].reset();
	for(int i=1;i<=n;i++)ans[i][i]=1;
	int ANS=inf;
	for(int b=1;b<=m;b++){
		for(int i=1;i<=n;i++)a[i].reset();
		for(int i=1;i<b;i++)a[e[i].x][e[i].y]=1;
		int k=e[b].d-e[b-1].d;
		while(k){
			if(k&1)mul(ans,a);
			mul(a,a);
			k>>=1;
		}
		memset(mp,0x3f,sizeof(mp));
		for(int i=1;i<=n;i++)mp[i][i]=0;
		for(int j=1;j<=b;j++)mp[e[j].x][e[j].y]=1;
		for(int k=1;k<=n;k++)
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
					mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
		for(int i=1;i<=n;i++)if(ans[1][i])ANS=min(ANS,e[b].d+mp[i][n]);
	}
	if(ANS==inf)printf("Impossible");else printf("%d",ANS);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<bitset>
#define N 160
using namespace std;
struct e{
	int l,r,w;
}edge[N];
struct matrix{
	int n,a[N][N];
	matrix()
	{
	 memset(a,0,sizeof(a));
	}
}I,M,f;
int n,m,i,ans,l,j,k;
int dis[N][N];
bitset<160> s1[N],s2[N];
bool cmp(e a,e b)
{
	return a.w<b.w;
}

matrix operator *(const matrix &A,const matrix &B)
{
	matrix C;
	C.n=A.n;
	int i,j;
	for (i=1;i<=A.n;i++)
	{
		s1[i].reset();
		s2[i].reset();
		for (j=1;j<=A.n;j++)
		{
			if (A.a[i][j]) s1[i].set(j);
			if (B.a[j][i]) s2[i].set(j);
		}
	}

	for (i=1;i<=A.n;i++)
	for (j=1;j<=A.n;j++)
	if ((s1[i]&s2[j]).count())
		C.a[i][j]=1;
	return C;
}
matrix ksm(int x)
{
	matrix ans;
	if (x==0)
		ans=I;
	else
	{
		ans=ksm(x/2);
		ans=ans*ans;
		if (x&1)
		ans=ans*M;
	}
	return ans;
}
int main()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++)
		scanf("%d%d%d",&edge[i].l,&edge[i].r,&edge[i].w);
	sort(edge+1,edge+1+m,cmp);
	memset(dis,63,sizeof(dis));
	for (i=1;i<=n;i++)
	{
		dis[i][i]=0;
		I.a[i][i]=1;
		f.a[i][i]=1;
	}
	I.n=f.n=M.n=n;
	ans=dis[0][0];
	for (i=1;i<=m;i++)
	{
		f=f*ksm(edge[i].w-l);
		l=edge[i].w;
		M.a[edge[i].l][edge[i].r]=1;
		for (j=1;j<=n;j++)
		for (k=1;k<=n;k++)
		dis[j][k]=min(dis[j][k],dis[j][edge[i].l]+dis[edge[i].r][k]+1);

		for (j=1;j<=n;j++)
		if (f.a[1][j])
		ans=min(ans,l+dis[j][n]);
	}
	if (ans==dis[0][0])
	printf("Impossible");
	else
	printf("%d\n",ans);
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

int n,m;

struct City{
    bool visited;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int h,w;
    int F[159][159];
};

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix startroads, Matrix roads ){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (i=1;i<=n;i++){
            if (roads.F[ i ][ act ] && !c[ i ].visited){
                c[ i ].visited = true;
                c[ i ].depth = c[ act ].depth + 1;
                city_queue.push( i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

Matrix MatrixMultiplication(Matrix &a, Matrix& b){

    Matrix res;
    res.h = min( a.h, b.h );
    res.w = min( a.w, b.w );

    int minlength = min( res.h, res.w );
    int x,y,k;

    for (x=1;x<=res.w;x++){
        for (y=1;y<=res.h;y++){
            res.F[ x ][ y ] = 0;
            for (k=1; k<=minlength; k++){
                res.F[ x ][ y ] = res.F[ x ][ y ] || ( a.F[ k ][ y ] && b.F[ x ][ k ] );
            }
        }
    }

    return res;
}

Matrix initMatrix( int w, int h, bool diognal ){
    Matrix res;
    res.w = w;
    res.h = h;
    int x,y;
    for ( x=1; x<=res.w; x++ ){
        for ( y=1; y<=res.h; y++ ){
            res.F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res.w == res.h ){
        for ( x=1; x <= res.w; x++)
            res.F[ x ][ x ] = 1;
    }

    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + 159;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix actualmap, actualtmpmap, tmpmap, tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix road_map = initMatrix( n, n, false);
    actualmap = initMatrix( n, n, true);

    while ( act <= m ){

        // Pievienojam jaunus celus
        while ( act <= m && r[ act ].d <= depth ){
            road_map.F[ r[ act ].to ][ r[ act ].from ] = 1;
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;
        tmpres = initMatrix( n, n, true );
        tmpmap = road_map;

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) tmpres = MatrixMultiplication( tmpres, tmpmap );
            tmpmap = MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        actualtmpmap = actualmap;  // Prieks BFS, ja ir iespejams noklut galapunkta

        if ( ldepth == 0 ) actualmap = tmpres;
        else actualmap = MatrixMultiplication( actualmap, tmpres );

        // PALAIZAM BFS - JA NU GADIJUMA NONAKAM GALAPUNKTA
        answer = BFS( actualtmpmap, road_map );
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }
    }

    printf("Impossible");
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <list>

using namespace std;

int n,m;

struct City{
    bool visited;
    list<int> roads;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int h,w;
    int F[159][159];
};

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix startroads){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (list<int>::iterator i = c[ act ].roads.begin(); i!= c[act].roads.end(); i++){
            if (!c[ *i ].visited){
                c[ *i ].visited = true;
                c[ *i ].depth = c[ act ].depth + 1;
                city_queue.push( *i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

void MatrixMultiplication(Matrix &a, Matrix& b){

    Matrix res;
    res.h = min( a.h, b.h );
    res.w = min( a.w, b.w );

    int minlength = min( res.h, res.w );
    int x,y,k;

    for (x=1;x<=res.w;x++){
        for (y=1;y<=res.h;y++){
            res.F[ x ][ y ] = 0;
            for (k=1; k<=minlength; k++){
                res.F[ x ][ y ] = res.F[ x ][ y ] || ( a.F[ k ][ y ] && b.F[ x ][ k ] );
            }
        }
    }

    a = res;
}

Matrix initMatrix( int w, int h, bool diognal ){
    Matrix res;
    res.w = w;
    res.h = h;
    int x,y;
    for ( x=1; x<=res.w; x++ ){
        for ( y=1; y<=res.h; y++ ){
            res.F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res.w == res.h ){
        for ( x=1; x <= res.w; x++)
            res.F[ x ][ x ] = 1;
    }

    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + 159;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix actualmap, tmpmap, tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix road_map = initMatrix( n, n, false);
    actualmap = initMatrix( n, n, true);

    while ( act < m ){

        // Pievienojam jaunus celus
        while ( act < m && r[ act ].d <= depth ){
            road_map.F[ r[ act ].to ][ r[ act ].from ] = 1;
            c[ r[ act ].from ].roads.push_back( r[ act ].to );
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;

        answer = BFS( actualmap );
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }

        tmpres = initMatrix( n, n, true );
        tmpmap = road_map;

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) MatrixMultiplication( tmpres, tmpmap );
            MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        if ( ldepth == 0 ) actualmap = tmpres;
        else MatrixMultiplication( actualmap, tmpres );
    }

    printf("Impossible");
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <list>

using namespace std;

int n,m;

struct City{
    bool visited;
    list<int> roads;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int h,w;
    int F[159][159];
};

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix startroads){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (list<int>::iterator i = c[ act ].roads.begin(); i!= c[act].roads.end(); i++){
            if (!c[ *i ].visited){
                c[ *i ].visited = true;
                c[ *i ].depth = c[ act ].depth + 1;
                city_queue.push( *i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

Matrix MatrixMultiplication(Matrix &a, Matrix& b){

    Matrix res;
    res.h = min( a.h, b.h );
    res.w = min( a.w, b.w );

    int minlength = min( res.h, res.w );
    int x,y,k;

    for (x=1;x<=res.w;x++){
        for (y=1;y<=res.h;y++){
            res.F[ x ][ y ] = 0;
            for (k=1; k<=minlength; k++){
                res.F[ x ][ y ] = res.F[ x ][ y ] || ( a.F[ k ][ y ] && b.F[ x ][ k ] );
            }
        }
    }

    return res;
}

Matrix initMatrix( int w, int h, bool diognal ){
    Matrix res;
    res.w = w;
    res.h = h;
    int x,y;
    for ( x=1; x<=res.w; x++ ){
        for ( y=1; y<=res.h; y++ ){
            res.F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res.w == res.h ){
        for ( x=1; x <= res.w; x++)
            res.F[ x ][ x ] = 1;
    }

    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + 159;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix actualmap, actualtmpmap, tmpmap, tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix road_map = initMatrix( n, n, false);
    actualmap = initMatrix( n, n, true);

    while ( act <= m ){

        // Pievienojam jaunus celus
        while ( act <= m && r[ act ].d <= depth ){
            road_map.F[ r[ act ].to ][ r[ act ].from ] = 1;
            c[ r[ act ].from ].roads.push_back( r[ act ].to );
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;
        tmpres = initMatrix( n, n, true );
        tmpmap = road_map;

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) tmpres = MatrixMultiplication( tmpres, tmpmap );
            tmpmap = MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        actualtmpmap = actualmap;  // Prieks BFS, ja ir iespejams noklut galapunkta

        if ( ldepth == 0 ) actualmap = tmpres;
        else actualmap = MatrixMultiplication( actualmap, tmpres );

        // PALAIZAM BFS - JA NU GADIJUMA NONAKAM GALAPUNKTA
        answer = BFS( actualtmpmap);
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }
    }

    printf("Impossible");
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <list>

using namespace std;

int n,m;

struct City{
    bool visited;
    list<int> roads;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int id;
    int h,w;
    int F[159][159];
}mat[20];

int cntmat;
int freemat[20];

void AddMat(Matrix *mat ){
    freemat[cntmat] = mat->id;
    cntmat++;
}

Matrix* PopMat(){
    cntmat--;
    return &mat[freemat[cntmat]];
}

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix &startroads ){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (list<int>::iterator i = c[ act ].roads.begin(); i!= c[act].roads.end(); i++){
            if (!c[ *i ].visited){
                c[ *i ].visited = true;
                c[ *i ].depth = c[ act ].depth + 1;
                city_queue.push( *i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

unsigned int A[159][9],B[159][9];

void MatrixMultiplication(Matrix*& a, Matrix*& b){

    Matrix *res = PopMat();

    res->h = min( a->h, b->h );
    res->w = min( a->w, b->w );

    int x,y,k;

    // PRECOMPUTE bitsets 32bit

    for (y=1;y<=res->h;y++){
        for (x=0; x*32 <= n ; x++){
            A[y][x] = 0;
            for (k=0; k<32 && x*32 + k <= n; k++){
                A[ y ][ x ] |= (a->F[ x*32 + k ][y] << k);
            }
        }
    }

    for (x=1; x<=res->w; x++){
        for (y=0; y*32 <= n ; y++){
            B[ x ][ y ]=0;
            for (k=0; k<32 && y*32 + k <=n; k++){
                B[ x ][ y ] |= ( b->F[ x ][ y*32 + k ] << k);
            }
        }
    }

    for (x=1;x<=res->w;x++){
        for (y=1;y<=res->h;y++){
            res->F[ x ][ y ] = 0;
            for (k=0; k*32 <= n; k++){
                if ( (A[ y ][ k ] & B[ x ][ k ]) > 0 ){
                    res->F[ x ][ y ] = 1;
                    break;
                }
            }
        }
    }

    AddMat(a);
    a = res;
}

Matrix* initMatrix( int w, int h, bool diognal ){
    Matrix *res = PopMat();
    res->w = w;
    res->h = h;
    int x,y;
    for ( x=1; x<=res->w; x++ ){
        for ( y=1; y<=res->h; y++ ){
            res->F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res->w == res->h ){
        for ( x=1; x <= res->w; x++)
            res->F[ x ][ x ] = 1;
    }

    return res;
}

Matrix* CopyMatrix( Matrix* matrix ){
    Matrix* res = PopMat();
    int id = res->id;
    *res = *matrix;
    res->id = id;
    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){
    cntmat = 0;
    for (int i=0;i<10;i++){
        mat[i].id = i;
        AddMat( &mat[i] );
    }

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + 159;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix *actualmap, *tmpmap, *tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix *road_map = initMatrix( n, n, false);
    actualmap = initMatrix( n, n, true);

    while ( act < m ){

        // Pievienojam jaunus celus
        while ( act < m && r[ act ].d <= depth ){
            road_map->F[ r[ act ].to ][ r[ act ].from ] = 1;
            c[ r[ act ].from ].roads.push_back( r[ act ].to );
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;

        answer = BFS( *actualmap );
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }

        tmpres = initMatrix( n, n, true );
        tmpmap = CopyMatrix( road_map );

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) MatrixMultiplication( tmpres, tmpmap );
            MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        AddMat( tmpmap );

        if ( ldepth == 0 ) {AddMat(actualmap); actualmap = tmpres;}
        else {MatrixMultiplication( actualmap, tmpres ); AddMat(tmpres); }

    }

    printf("Impossible");
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

int n,m;

struct City{
    bool visited;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int h,w;
    int F[159][159];
};

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix startroads, Matrix roads ){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (i=1;i<=n;i++){
            if (roads.F[ i ][ act ] && !c[ i ].visited){
                c[ i ].visited = true;
                c[ i ].depth = c[ act ].depth + 1;
                city_queue.push( i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

Matrix MatrixMultiplication(Matrix &a, Matrix& b){

    Matrix res;
    res.h = min( a.h, b.h );
    res.w = min( a.w, b.w );

    int minlength = min( res.h, res.w );
    int x,y,k;

    for (x=1;x<=res.w;x++){
        for (y=1;y<=res.h;y++){
            res.F[ x ][ y ] = 0;
            for (k=1; k<=minlength; k++){
                res.F[ x ][ y ] = res.F[ x ][ y ] || ( a.F[ k ][ y ] && b.F[ x ][ k ] );
            }
        }
    }

    return res;
}

Matrix initMatrix( int w, int h, bool diognal ){
    Matrix res;
    res.w = w;
    res.h = h;
    int x,y;
    for ( x=1; x<=res.w; x++ ){
        for ( y=1; y<=res.h; y++ ){
            res.F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res.w == res.h ){
        for ( x=1; x <= res.w; x++)
            res.F[ x ][ x ] = 1;
    }

    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + n;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix actualmap, actualtmpmap, tmpmap, tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix road_map = initMatrix( n, n, false);

    while ( act <= m ){

        // Pievienojam jaunus celus
        while ( act <= m && r[ act ].d <= depth ){
            road_map.F[ r[ act ].to ][ r[ act ].from ] = 1;
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;
        tmpres = initMatrix( n, n, true );
        tmpmap = road_map;

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) tmpres = MatrixMultiplication( tmpres, tmpmap );
            tmpmap = MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        actualtmpmap = actualmap;  // Prieks BFS, ja ir iespejams noklut galapunkta

        if ( ldepth == 0 ) actualmap = tmpres;
        else actualmap = MatrixMultiplication( actualmap, tmpres );

        // PALAIZAM BFS - JA NU GADIJUMA NONAKAM GALAPUNKTA
        answer = BFS( actualtmpmap, road_map );
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }
    }

    printf("Impossible");
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <list>

using namespace std;

int n,m;

struct City{
    bool visited;
    list<int> roads;
    int depth;
}c[159];

queue<int> city_queue;

struct Matrix{
    int id;
    int h,w;
    int F[159][159];
}mat[20];

int cntmat;
int freemat[20];

void AddMat(Matrix *mat ){
    freemat[cntmat] = mat->id;
    cntmat++;
}

Matrix* PopMat(){
    cntmat--;
    return &mat[freemat[cntmat]];
}

struct Roads{
    int from, to, d;
    bool operator<( Roads &rhs)const{
        return d<rhs.d;
    }
}r[159];

int BFS( Matrix &startroads ){

    int act,i;

    for (i=1;i<=n;i++){
        if (startroads.F[ i ][ 1 ]){
            c[ i ].visited = true;
            c[ i ].depth = 0;
            city_queue.push( i );
        }else{
            c[ i ].visited = false;
        }
    }

    while ( !city_queue.empty() ){

        act = city_queue.front();
        city_queue.pop();

        for (list<int>::iterator i = c[ act ].roads.begin(); i!= c[act].roads.end(); i++){
            if (!c[ *i ].visited){
                c[ *i ].visited = true;
                c[ *i ].depth = c[ act ].depth + 1;
                city_queue.push( *i );
            }
        }
    }

    if ( c[ n ].visited ) return c[ n ].depth;
    else return -1;
}

void MatrixMultiplication(Matrix*& a, Matrix*& b){

    Matrix *res = PopMat();

    res->h = min( a->h, b->h );
    res->w = min( a->w, b->w );

    int minlength = min( res->h, res->w );
    int x,y,k;

    for (x=1;x<=res->w;x++){
        for (y=1;y<=res->h;y++){
            res->F[ x ][ y ] = 0;
            for (k=1; k<=minlength; k++){
                res->F[ x ][ y ] = res->F[ x ][ y ] || ( a->F[ k ][ y ] && b->F[ x ][ k ] );
            }
        }
    }

    AddMat(a);
    a = res;
}

Matrix* initMatrix( int w, int h, bool diognal ){
    Matrix *res = PopMat();
    res->w = w;
    res->h = h;
    int x,y;
    for ( x=1; x<=res->w; x++ ){
        for ( y=1; y<=res->h; y++ ){
            res->F[ x ][ y ] = 0;
        }
    }
    if ( diognal && res->w == res->h ){
        for ( x=1; x <= res->w; x++)
            res->F[ x ][ x ] = 1;
    }

    return res;
}

Matrix* CopyMatrix( Matrix* matrix ){
    Matrix* res = PopMat();
    int id = res->id;
    *res = *matrix;
    res->id = id;
    return res;
}

void printMatrix( Matrix &matrix ){
    int x,y;
    for ( y=1;y<=matrix.h;y++ ){
        printf("\n");
        for ( x=1;x<=matrix.w;x++){
            printf("%d ",matrix.F[x][y]);
        }
    }
    printf("\n");
}

int main(){
    cntmat = 0;
    for (int i=0;i<10;i++){
        mat[i].id = i;
        AddMat( &mat[i] );
    }

    scanf("%d %d",&n,&m);

    if ( n == 1 ){// Jau atrodas galapunkta
        printf("0");
        return 0;
    }

    for (int i=0;i<m;i++){
        scanf("%d %d %d", &r[i].from, &r[i].to, &r[i].d);
    }

    sort( r, r+m );

    r[m].to = r[m].from = n;  //Pievienojam celu, kas atlaus parbaudit vai
    r[m].d = r[ m-1 ].d + 159;      //pec pedejas cela pievienosanas nevar aizbraukt
                              //uz n pilsetu

    int depth, ldepth, act, delta, answer;

    Matrix *actualmap, *tmpmap, *tmpres;

    act = 0;
    ldepth = depth = 0;

    Matrix *road_map = initMatrix( n, n, false);
    actualmap = initMatrix( n, n, true);

    while ( act < m ){

        // Pievienojam jaunus celus
        while ( act < m && r[ act ].d <= depth ){
            road_map->F[ r[ act ].to ][ r[ act ].from ] = 1;
            c[ r[ act ].from ].roads.push_back( r[ act ].to );
            act++;
        }

        ldepth = depth;            // Palielinam braucienu skaitu,
        depth = r[ act ].d;

        // Nobraucam dotos braucienus - sastadot karti kur nonaksim

        delta = depth - ldepth;

        answer = BFS( *actualmap );
        if (answer!= -1 && answer<=(depth-ldepth) ){
            printf("%d", answer+ldepth);
            return 0;
        }

        tmpres = initMatrix( n, n, true );
        tmpmap = CopyMatrix( road_map );

        while ( delta > 0 ){
            if ( delta % 2 == 1 ) MatrixMultiplication( tmpres, tmpmap );
            MatrixMultiplication( tmpmap, tmpmap );
            delta /= 2;
        }

        AddMat( tmpmap );

        if ( ldepth == 0 ) {AddMat(actualmap); actualmap = tmpres;}
        else {MatrixMultiplication( actualmap, tmpres ); AddMat(tmpres); }

    }

    printf("Impossible");
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <cassert>
#include <numeric>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef unsigned long long ull;
typedef long long int int64;

struct Edge
{
	int from, to, cost;
	Edge() : from(), to(), cost() {}
	Edge(int _from, int _to, int _cost) : from(_from), to(_to), cost(_cost) {}

	void read()
	{
		scanf("%d%d%d", &from, &to, &cost);
		from--;
		to--;
	}
	bool operator < (const Edge &A) const
	{
		return cost < A.cost;
	}
};

const int maxn = 155;
Edge edge[maxn];
int N;

int bit(ull x, int y)
{
	return ( (x >> y) & 1ULL);
}

struct Matr
{
	ull row[maxn][3], col[maxn][3];

	Matr() : row(), col() {}

	Matr(int a[] ) : row(), col()
	{
		for (int i = 0; i < N; i++)
		{
			if (a[i] )
			{
				row[0][i >> 6] |= (1ULL << (i & 63) );
				col[i][0] |= 1;
			}
		}
	}

	void set(int i, int j)
	{
		row[i][j >> 6] |= (1ULL << (j & 63) );
		col[j][i >> 6] |= (1ULL << (i & 63) );
	}

	Matr operator * (const Matr &A) const
	{
		Matr ans = Matr();
		for (int i = 0; i < N; i++)
			for (int j = 0; j < N; j++)
			{
				 if ( (row[i][0] & A.col[j][0] ) | (row[i][1] & A.col[j][1] ) | (row[i][2] & A.col[j][2] ) )
				 {
					 ans.row[i][j >> 6] |= (1ULL << (j & 63) );
					 ans.col[j][i >> 6] |= (1ULL << (i & 63) );
				 }
			}
		return ans;
	}

	int get(int x, int y)
	{
		return bit(row[x][y >> 6], y & 63);
	}

	void eprint()
	{
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < N; j++)
				eprintf("%d ", get(i, j) );
			eprintf("\n");
		}
		eprintf("\n");
	}
};

Matr ONE()
{
	Matr ans = Matr();
	for (int i = 0; i < N; i++)
	{
		ans.row[i][i >> 6] |= (1ULL << (i & 63) );
		ans.col[i][i >> 6] |= (1ULL << (i & 63) );
	}
	return ans;
}

Matr fpow(Matr X, int n)
{
	Matr ans = ONE();
	Matr A = X;

	while (n)
	{
		if (n & 1)
			ans = ans * A;
		A = A * A;
		n >>= 1;
	}

//	eprintf("end fpow:\n");
//	ans.eprint();
	return ans;
}

int starr[maxn];

void solve()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++)
	{
		edge[i].read();
	}
	N = n;
	sort(edge, edge + m);

	starr[0] = 1;
	Matr st = Matr(starr);//起点
	Matr turn = Matr();
	Matr turnStay = ONE();

	if (edge[0].cost != 0)
	{
		printf("Impossible\n");
		return;
	}

	int curT = 0;
	for (int i = 0; i < m; i++)
	{
		int nT;
		if (i == m - 1)
			nT = curT + 200;
		else
			nT = edge[i + 1].cost;

		turn.set(edge[i].from, edge[i].to);
		turnStay.set(edge[i].from, edge[i].to);

		Matr nx = st * fpow(turnStay, nT - curT);

		if (nx.get(0, n - 1) )
		{
			int l = curT;
			int r = nT;

			while (r - l > 1)
			{
				int mid = (r + l) / 2;
				Matr M = st * fpow(turnStay, mid - curT);

				if (M.get(0, n - 1) )
					r = mid;
				else
					l = mid;
			}

			printf("%d\n", r);
			return;
		}

		st = st * fpow(turn, nT - curT);
		curT = nT;
	}

	printf("Impossible\n");
}

int main(int , char **)
{
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	solve();

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
#include <bitset>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

#define base bitset<150>
typedef base arr[151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)a[i]=b[i];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(a[i][j])c[i]|=b[j];
    copy(a,c);
}
void mul1(base &c,arr b){
    base a;
    for(int i=0;i<n;i++)if(c[i])a|=b[i];
    c=a;
}
bool check(base &c,arr &b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c.test(i)){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u].test(i)&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c.set(n-1);
        return 1;
    }
    return 0;
}
struct edge{
    int u,v,w;
    bool operator <(const edge&a)const{
        return w<a.w;
    }
}e[200];
vector<pii>g[200];
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    ans=0;
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        e[i]=(edge){u,v,k};
        g[u].pb(mp(v,k));
    }
    if(n==1){
        printf("1\n1\n");return 0;
    }
    sort(e,e+m);
    if(e[0].w){puts("Impossible");return 0;}
    int d[151];
    for(i=0;i<n;i++)d[i]=-1;d[0]=0;
    priority_queue<pii>q;q.push(mp(0,0));
    while(!q.empty()){
        int u=q.top().y,v=-q.top().x;q.pop();
        if(d[u]!=v)continue;
        for(i=0;i<g[u].size();i++){
            j=g[u][i].x;k=g[u][i].y;
            if(d[j]==-1||d[j]>max(d[u],k)){
                d[j]=max(d[u],k);
                q.push(mp(-d[j],j));
            }
        }
    }
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }

    int D=d[n-1];
    //DBG(D)
    arr b;base c;c.set(0);
    for(i=0;i<m;i=j){
        j=i;
        while(j<m&&e[j].w==e[i].w){
            b[e[j].u].set(e[j].v);
            j++;
        }
        if(e[i].w==D)break;
        if(j<m){
            int len=e[j].w-e[i].w;
            //DBG(len)
            arr bb;
            copy(bb,b);
            while(len){
                if(len&1)mul1(c,bb);
                mul(bb,bb);len>>=1;
            }
            ans=e[j].w;
        }
    }
    check(c,b);
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151],vis[151];
    queue<int>q;q.push(0);
    for(i=0;i<n;i++)d[i]=-1,vis[i]=0;d[0]=0;
    while(!q.empty()){
        int u=q.front();q.pop();vis[i]=0;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                if(!vis[i])vis[i]=1,q.push(i);
            }
        }
    }
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,szieof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151],vis[151];
    queue<int>q;q.push(0);
    for(i=0;i<n;i++)d[i]=-1,vis[i]=0;d[0]=0;
    while(!q.empty()){
        int u=q.front();q.pop();vis[i]=0;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                if(!vis[i])vis[i]=1,q.push(i);
            }
        }
    }
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,sz=0,ans,w[155];
vector<pii> g[151];
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int d[151];
    for(int i=0;i<n;i++)d[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        d[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&d[i]==-1){
            d[i]=d[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(d[n-1]!=-1){
        ans+=d[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            w[sz++]=a[i][j];
        }
    sort(w,w+sz);
    sz=unique(w,w+sz)-w;
    if(w[0]){puts("Impossible");return 0;}
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            k=lower_bound(w,w+sz,a[i][j])-w;
            g[k].pb(mp(i,j));
        }
    //memset(c,0,sizeof(c));
    memset(b,0,sizeof(b));
    //for(i=0;i<n;i++)c[i][i]=1;
    bool flag=false;
    //DBG(sz)
    for(i=0;i<sz;i++){
        int x=w[i];
        for(j=0;j<g[i].size();j++){
            int u=g[i][j].x,v=g[i][j].y;
            if(v==n-1)flag=true;
        }
        if(flag)break;
        for(j=0;j<g[i].size();j++){
            int u=g[i][j].x,v=g[i][j].y;
            b[u][v]=1;
        }
    }
    if(!flag){puts("Impossible");return 0;}
    int c[151]={0};
    c[0]=1;
    pow(b,w[i],c);
    ans=w[i];
    //DBG(i)
    for(;i<sz;i++){
        int x=w[i];
        FOREACH(it,g[i]){
            int u=it->x,v=it->y;
            b[u][v]=1;
        }
        if(check(c,b))break;
        if(i<sz-1){
            pow(b,w[i+1]-x,c);
            ans=w[i+1];
        }
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int d[151];
    for(int i=0;i<n;i++)d[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        d[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&d[i]==-1){
            d[i]=d[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(d[n-1]!=-1){
        ans+=d[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151],vis[151];
    queue<int>q;q.push(0);
    for(i=0;i<n;i++)d[i]=-1,vis[i]=0;d[0]=0;
    while(!q.empty()){
        int u=q.front();q.pop();vis[i]=0;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                if(!vis[i])vis[i]=1,q.push(i);
            }
        }
    }
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151];
    priority_queue<pii>q;q.push(mp(0,0));
    for(i=0;i<n;i++)d[i]=-1;d[0]=0;
    while(!q.empty()){
        int u=q.top().y,v=-q.top().x;q.pop();
        if(d[u]!=v)continue;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                q.push(mp(-d[i],i));
            }
        }
    }
    //DBG(d[n-1])
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,sz=0,ans,w[155];
vector<pii> g[151];
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int d[151];
    for(int i=0;i<n;i++)d[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        d[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&d[i]==-1){
            d[i]=d[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(d[n-1]!=-1){
        ans+=d[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            w[sz++]=a[i][j];
        }
    sort(w,w+sz);
    sz=unique(w,w+sz)-w;
    if(w[0]){puts("Impossible");return 0;}
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            k=lower_bound(w,w+sz,a[i][j])-w;
            g[k].pb(mp(i,j));
        }
    //memset(c,0,sizeof(c));
    memset(b,0,sizeof(b));
    //for(i=0;i<n;i++)c[i][i]=1;
    bool flag=false;
    //DBG(sz)
    for(i=0;i<sz;i++){
        int x=w[i];
        FOREACH(it,g[i]){
            int u=it->x,v=it->y;
            b[u][v]=1;
            if(v==n-1)flag=true;
        }
        if(flag)break;
    }
    if(!flag){puts("Impossible");return 0;}
    int c[151]={0};
    c[0]=1;
    pow(b,w[i],c);
    if(c[n-1]){
        printf("%d\n",w[i]);return 0;
    }
    //DBG(i)
    for(i++;i<sz;i++){
        int x=w[i];
        FOREACH(it,g[i]){
            int u=it->x,v=it->y;
            b[u][v]=1;
        }
        if(check(c,b))break;
        if(i<sz-1){
            pow(b,w[i+1]-x,c);
            ans=w[i+1];
        }
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151];
    priority_queue<pii>q;q.push(mp(0,0));
    for(i=0;i<n;i++)d[i]=-1;d[0]=0;
    while(!q.empty()){
        int u=q.top().y,v=-q.top().x;q.pop();
        if(d[u]!=v)continue;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                q.push(mp(-d[i],i));
            }
        }
    }
    //DBG(d[n-1])
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(c[n-1]){assert(0);}
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,sz=0,ans,w[155];
vector<pii> g[151];
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
            }
    copy(a,c);
}
void pow(arr a,int m,arr &b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)b[i][j]=0;
    for(int i=0;i<n;i++)b[i][i]=1;
    arr c;
    copy(c,a);
    while(m){
        if(m&1)mul(b,c);
        mul(c,c);m>>=1;
    }
}
bool check(arr c,arr b){
    static int d[151];
    for(int i=0;i<n;i++)d[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[0][i]){
        d[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&d[i]==-1){
            d[i]=d[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(d[n-1]!=-1){
        ans+=d[n-1];
        c[0][n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a;ans=0;
    memset(a,-1,sizeof(a));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            w[sz++]=a[i][j];
        }
    sort(w,w+sz);
    sz=unique(w,w+sz)-w;
    if(w[0]){puts("Impossible");return 0;}
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            k=lower_bound(w,w+sz,a[i][j])-w;
            g[k].pb(mp(i,j));
        }
    arr b,c;
    memset(c,0,sizeof(c));
    memset(b,0,sizeof(b));
    for(i=0;i<n;i++)c[i][i]=1;
    bool flag=false;
    //DBG(sz)
    for(i=0;i<sz;i++){
        int x=w[i];
        FOREACH(it,g[i]){
            int u=it->x,v=it->y;
            b[u][v]=1;
            if(v==n-1)flag=true;
        }
        if(flag){
            if(check(c,b))break;
        }
        if(i<sz-1){
            arr e;
            pow(b,w[i+1]-x,e);
            //DBG("........")
            mul(c,e);
            ans=w[i+1];
        }
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!flag||!c[0][n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151],vis[151];
    queue<int>q;q.push(0);
    for(i=0;i<n;i++)d[i]=-1,vis[i]=0;d[0]=0;
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                if(!vis[i])vis[i]=1,q.push(i);
            }
        }
    }
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(!c[n-1]){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[150][150];
int n,sz=0,ans,w[155];
vector<pii> g[151];
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    memset(c,0,sizeof(c));
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
            }
    copy(a,c);
}
void pow(arr a,int n,arr &b){
    memset(b,0,sizeof(b));
    for(int i=0;i<n;i++)b[i][i]=1;
    arr c;
    copy(c,a);
    while(n){
        if(n&1)mul(b,c);
        mul(c,c);n>>=1;
    }
}
bool check(arr c,arr b){
    static int d[151];
    for(int i=0;i<n;i++)d[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[0][i]){
        d[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&d[i]==-1){
            d[i]=d[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(d[n-1]!=-1){
        ans+=d[n-1];
        c[0][n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a;ans=0;
    memset(a,-1,sizeof(a));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            w[sz++]=a[i][j];
        }
    sort(w,w+sz);
    sz=unique(w,w+sz)-w;
    if(w[0]){puts("Impossible");return 0;}
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1){
            k=lower_bound(w,w+sz,a[i][j])-w;
            g[k].pb(mp(i,j));
        }
    arr b,c;
    memset(c,0,sizeof(c));
    memset(b,0,sizeof(b));
    for(i=0;i<n;i++)c[i][i]=1;
    bool flag=false;
    for(i=0;i<sz;i++){
        int x=w[i];
        FOREACH(it,g[i]){
            int u=it->x,v=it->y;
            b[u][v]=1;
            if(v==n-1)flag=true;
        }
        if(flag){
            if(check(c,b))break;
        }
        if(i<sz-1){
            arr e;
            pow(b,w[i+1]-x,e);
            mul(c,e);
            ans=w[i+1];
        }
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!flag||!c[0][n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <ctime>
#include <assert.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
#define N 100005
#define DBG(x) cerr<<(#x)<<"="<<x<<endl;
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)

template <class T> inline void Max(T &a,T b){if(a<b)a=b;}
template <class T> inline void Min(T &a,T b){if(a>b)a=b;}

typedef int arr[151][151];
int n,ans;
void copy(arr &a,arr b){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)a[i][j]=b[i][j];
}
void mul(arr &a,arr b){
    arr c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)c[i][j]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++){
                c[i][j]|=(a[i][k]&b[k][j]);
                if(c[i][j])break;
            }
    copy(a,c);
}
void mul1(int *c,arr a){
    static int h[151];
    for(int i=0;i<n;i++){
        h[i]=0;
        for(int j=0;j<n;j++){
            h[i]|=(c[j]&a[j][i]);
            if(h[i])break;
        }
    }
    for(int i=0;i<n;i++)c[i]=h[i];
}
void pow(arr &a,int m,int *c){
    arr b;
    copy(b,a);
    while(m){
        if(m&1)mul1(c,b);
        mul(b,b);m>>=1;
    }
}
bool check(int *c,arr b){
    static int dp[151];
    for(int i=0;i<n;i++)dp[i]=-1;
    queue<int>q;
    for(int i=0;i<n;i++)if(c[i]){
        dp[i]=0;q.push(i);
        //DBG(i)
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<n;i++)if(b[u][i]&&dp[i]==-1){
            dp[i]=dp[u]+1;
            q.push(i);
        }
    }
    //DBG(d[n-1])
    if(dp[n-1]!=-1){
        ans+=dp[n-1];
        c[n-1]=1;
        return 1;
    }
    return 0;
}
int main(){
    int T,i,j,k,m;
    scanf("%d%d",&n,&m);
    arr a,b;ans=0;
    memset(a,-1,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<m;i++){
        int u,v;
        scanf("%d%d%d",&u,&v,&k);u--,v--;
        if(a[u][v]!=-1)a[u][v]=min(a[u][v],k);
        else a[u][v]=k;
    }
    int d[151];
    priority_queue<pii>q;q.push(mp(0,0));
    for(i=0;i<n;i++)d[i]=-1;d[0]=0;
    while(!q.empty()){
        int u=q.top().y,v=-q.top().x;q.pop();
        if(d[u]!=v)continue;
        for(i=0;i<n;i++)if(a[u][i]!=-1){
            if(d[i]==-1||d[i]>max(d[u],a[u][i])){
                d[i]=max(d[u],a[u][i]);
                q.push(mp(-d[i],i));
            }
        }
    }
    //DBG(d[n-1])
    if(d[n-1]==-1){
        puts("Impossible");return 0;
    }
    //for(i=0;i<n;i++)c[i][i]=1;
    int c[151]={0};
    c[0]=1;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]<d[n-1])b[i][j]=1;
    //DBG(d[n-1])
    pow(b,d[n-1],c);
    ans=d[n-1];
    //DBG(ans)
    //DBG(c[n-1])
    if(1){
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)if(a[i][j]!=-1&&a[i][j]==d[n-1])b[i][j]=1;
        check(c,b);
    }
    //DBG(flag)
    //DBG(c[0][n-1])
    if(!c[n-1]){
        puts("Impossible");
    }
    else{
        printf("%d\n",ans);
    }
    return 0;
}


#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
using namespace std;
const int N=160,inf=0x3f3f3f3f;
struct cyc{int x,y,d;}e[N];
int n,m,mp[N][N];
bitset<N>a[N],ans[N],c[N],z[N];
bool cmp(cyc a,cyc b){return a.d<b.d;}
void mul(bitset<N>a[N],bitset<N>b[N]){
	for(int i=1;i<=n;i++)c[i].reset();
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	if(a[i][k])c[i]|=b[k];
	for(int i=1;i<=n;i++)a[i]=c[i];
}
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].d);
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++)ans[i].reset();
	for(int i=1;i<=n;i++)ans[i][i]=1;
	int ANS=inf;
	for(int b=1;b<=m;b++){
		for(int i=1;i<=n;i++)a[i].reset();
		for(int i=1;i<b;i++)a[e[i].x][e[i].y]=1;
		int k=e[b].d-e[b-1].d;
		while(k){
			if(k&1)mul(ans,a);
			mul(a,a);
			k>>=1;
		}
		memset(mp,0x3f,sizeof(mp));
		for(int i=1;i<=n;i++)mp[i][i]=0;
		for(int j=1;j<=b;j++)mp[e[j].x][e[j].y]=1;
		for(int k=1;k<=n;k++)
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
					mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
		for(int i=1;i<=n;i++)if(ans[1][i])ANS=min(ANS,e[b].d+mp[i][n]);
	}
	if(ANS==inf)printf("Impossible");else printf("%d",ANS);
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

typedef vector<vector<int> > mat;

const int limite=151;
int n;
const int infinito=2000000000;

mat codifica(mat m)
{
  mat r(n,vector<int> (5,0));
  for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
      r[i][j>>5]|=m[i][j]<<(j&31);
  return r;
}

void transponer(mat &m)
{
  for (int i=0;i<n;i++)
    for (int j=0;j<i;j++)
      swap(m[i][j],m[j][i]);
}

mat operator*(mat m1,mat m2)
{
  /*
  mat m(n,vector<int> (n,0));
  for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
      for (int k=0;k<n;k++)
	m[i][j]=m[i][j] or (m1[i][k] and m2[k][j]);
  return m;
  */
  mat c1=codifica(m1);
  transponer(m2);
  mat c2=codifica(m2);
  mat m(n,vector<int> (n,0));
  for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
      for (int k=0;k<5;k++)
	m[i][j]=m[i][j] or (c1[i][k]&c2[j][k])!=0;
  return m;
}

vector<int> operator*(mat m,vector<int> v)
{
  vector<int> r(n,0);
  for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
      r[i]=r[i] or (m[i][j] and v[j]);
  return r;
}

mat eleva(mat m,int b)
{
  if (b==0) {
    mat r(n,vector<int> (n,0));
    for (int i=0;i<n;i++)
      r[i][i]=1;
    return r;
  }
  if (b%2==0) return eleva(m*m,b/2);
  return m*eleva(m*m,b/2);
}

struct arista {
  int u,v,d;
};

bool operator<(arista a1,arista a2)
{
  return a1.d<a2.d;
}

vector<int> g[limite];

int sol=infinito;

int nc,na;
int dist[limite];

void calculasol(vector<int> e,int dbase)
{
  //cout<<"dbase "<<dbase<<endl;
  //cout<<"e "<<e[1]<<" "<<e[2]<<" "<<e[3]<<endl;
  queue<int> q;
  for (int i=0;i<n;i++) {
    if (e[i]) {
      dist[i]=0;
      q.push(i);
    } else {
      dist[i]=infinito;
    }
  }
  while (dist[nc]==infinito and not q.empty()) {
    int u=q.front();
    q.pop();
    vector<int> &ar=g[u];
    for (int i=0;i<int(ar.size());i++) {
      int v=ar[i];
      if (dist[v]==infinito) {
	dist[v]=dist[u]+1;
	q.push(v);
      }
    }
  }
  if (dist[nc]!=infinito)
    sol=min(sol,dist[nc]+dbase);
}

int main()
{
  cin>>nc>>na;
  n=nc+1;
  vector<arista> va(na);
  for (int i=0;i<na;i++)
    cin>>va[i].u>>va[i].v>>va[i].d;
  sort(va.begin(),va.end());
  vector<int> e(n,0);
  e[1]=1;
  mat m(n,vector<int> (n,0));
  int d=0;
  int iva=0;
  while (iva<na) {
    int nextd=va[iva].d;
    e=eleva(m,nextd-d)*e;
    d=nextd;
    //cout<<"d "<<d<<endl;
    //cout<<"e "<<e[1]<<" "<<e[2]<<" "<<e[3]<<endl;
    for (;iva<na and va[iva].d==d;iva++) {
      arista &a=va[iva];
      int u=a.u;
      int v=a.v;
      m[v][u]=1;
      g[u].push_back(v);
    }
    calculasol(e,d);
  }
  if (sol<infinito)
    cout<<sol<<endl;
  else
    cout<<"Impossible"<<endl;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <stack>
#include <cstdio>
using namespace std;
const int SUPER_KONSTANTA_FOR_REAL_PACAN_1337 = 228;
const int leet = 1337;
const int MAXN = 155;
const long long modulo = 1000000007;
const int inf = 2000001337;
const int L = 30;

struct Matrix
{
    int N;
    unsigned int rows[MAXN][5], columns[MAXN][5];

    void FillZeros()
    {
        for (int i = 0; i < MAXN; i++)
        {
            for (int j = 0; j < 5; j++)
                rows[i][j] = columns[i][j] = 0;
        }
    }

    void put( int i , int j )
    {
        int colJ = j / L;
        int colBitPos = j % L;

        rows[i][colJ] ^= (1 << colBitPos);

        int rowI = i / L;
        int rowBitPos = i % L;

        columns[j][rowI] ^= (1 << rowBitPos);
    }

    void print()
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                int x = rows[ i ][ j / L ] & ( 1 <<  (j % L) );
                if ( x != 0 ) x = 1;
                cout << x << " ";
            }
            cout << endl;
        }
    }
};

struct Vector
{
    unsigned int v[5];
};

Matrix operator *( Matrix A , Matrix B )
{
    Matrix C;
    C.FillZeros();
    C.N = A.N;
    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            for (int k = 0; k < 5; k++)
            {
                unsigned int x = A.rows[i][k] & B.columns[j][k];
                if ( x != 0 )
                {
                    C.put( i , j );
                    break;
                }
            }
        }
    }

    return C;
}

Vector operator *( Matrix A , Vector x )
{
    Vector y;
    for (int i = 0; i < 5; i++)
        y.v[i] =0;

    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        unsigned int q = 0;
        for (int k = 0; k < 5; k++)
        {
            q += A.rows[i][k] & x.v[k];
        }

        if ( q != 0 ) q = 1;
        y.v[ i / L ] ^= (q << ( i % L ));
    }

    return y;
}

int a[MAXN], b[MAXN], d[MAXN], dd[MAXN];
vector<int> critical;
Matrix I;

void GetBits( Matrix& A , int X , int M )
{
    for (int i = 1; i <= M; i++)
    {
        if ( d[i] <= X )
        {
            A.put( b[i] , a[i] );
        }
    }
}

Matrix pow( Matrix A, int b )
{
    if ( b == 0 ) return I;
    Matrix B = pow( A , b / 2 );
    B = B * B;
    if ( b % 2 == 1 ) B = B * A;
    return B;
}

int CheckAns(  Matrix A , Vector x , int T , int S )
{
    T--;
    for ( int i = 1; i <= S; i++)
    {
        x = A * x;
        if ( (x.v[ T / L ] & ( 1 << (T % L) )) != 0 ) return i;
    }

    return inf;
}

int main()
{
    //freopen("input.in" , "r" , stdin);
    int N , M;
    cin >> N >> M;

    for (int i = 1; i <= M; i++)
    {
        cin >> a[i] >> b[i] >> d[i];
        a[i]--;
        b[i]--;
        dd[i] = d[i];
    }

    sort( dd + 1 , dd + M + 1);
    critical.push_back( dd[1] );
    for (int i = 2; i <= M; i++)
    {
        if ( dd[i] != dd[i-1] )
            critical.push_back( dd[i] );
    }

    if ( dd[1] != 0 )
    {
        cout << "Impossible" << endl;
        return 0;
    }

    Vector x;
    x.v[0] = x.v[1] = x.v[2] = x.v[3] = x.v[4] = 0;
    x.v[0] = 1;
    critical.push_back( inf );

    I.N = N;
    I.FillZeros();
    for ( int i = 0; i < N; i++ )
        I.put( i , i );

    for (int i = 0; i < critical.size() - 1; i++)
    {
        Matrix A;
        A.N = N;
        A.FillZeros();
        GetBits( A , critical[i] , M );

        int ans = CheckAns( A , x , N , min( critical[i + 1] - critical[i] , N ) );
        if ( ans != inf )
        {
            cout << critical[i] + ans << endl;
            return 0;
        }

        if ( i == critical.size() - 2 ) break;

        A = pow( A , critical[i + 1] - critical[i] );
        x = A * x;
    }

    cout << "Impossible" << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <stack>
#include <cstdio>
using namespace std;
const int SUPER_KONSTANTA_FOR_REAL_PACAN_1337 = 228;
const int leet = 1337;
const int MAXN = 155;
const long long modulo = 1000000007;
const int inf = 2000001337;
const int L = 30;

struct Matrix
{
    int N;
    unsigned int rows[MAXN][5], columns[MAXN][5];

    void FillZeros()
    {
        for (int i = 0; i < MAXN; i++)
        {
            for (int j = 0; j < 5; j++)
                rows[i][j] = columns[i][j] = 0;
        }
    }

    void put( int i , int j )
    {
        int colJ = j / L;
        int colBitPos = j % L;

        rows[i][colJ] ^= (1 << colBitPos);

        int rowI = i / L;
        int rowBitPos = i % L;

        columns[j][rowI] ^= (1 << rowBitPos);
    }

    void print()
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                int x = rows[ i ][ j / L ] & ( 1 <<  (j % L) );
                if ( x != 0 ) x = 1;
                cout << x << " ";
            }
            cout << endl;
        }
    }
};

struct Vector
{
    unsigned int v[5];
};

Matrix operator *( Matrix A , Matrix B )
{
    Matrix C;
    C.FillZeros();
    C.N = A.N;
    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            for (int k = 0; k < 5; k++)
            {
                unsigned int x = A.rows[i][k] & B.columns[j][k];
                if ( x != 0 )
                {
                    C.put( i , j );
                    break;
                }
            }
        }
    }

    return C;
}

Vector operator *( Matrix A , Vector x )
{
    Vector y;
    for (int i = 0; i <= 5; i++)
        y.v[i] =0;

    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        unsigned int q = 0;
        for (int k = 0; k < 5; k++)
        {
            q += A.rows[i][k] & x.v[k];
        }

        if ( q != 0 ) q = 1;
        y.v[ i / L ] ^= (q << ( i % L ));
    }

    return y;
}

int a[MAXN], b[MAXN], d[MAXN], dd[MAXN];
vector<int> critical;
Matrix I;

void GetBits( Matrix& A , int X , int M )
{
    for (int i = 1; i <= M; i++)
    {
        if ( d[i] <= X )
        {
            A.put( b[i] , a[i] );
        }
    }
}

Matrix pow( Matrix A, int b )
{
    if ( b == 0 ) return I;
    Matrix B = pow( A , b / 2 );
    B = B * B;
    if ( b % 2 == 1 ) B = B * A;
    return B;
}

int CheckAns(  Matrix A , Vector x , int T , int S )
{
    //cout << "I am checking ans" << endl;
    //cout << "Matrix: " << endl; A.print();

    //cout << x.v[0] << endl;
    T--;
    for ( int i = 1; i <= S; i++)
    {
        x = A * x;
        //cout << x.v[0] << endl;
        if ( (x.v[ T / L ] & ( 1 << (T % L) )) != 0 ) return i;
    }

    //cout << "End of checking" << endl;
    return inf;
}

int main()
{
    //freopen("input.in" , "r" , stdin);
    int N , M;
    cin >> N >> M;

    for (int i = 1; i <= M; i++)
    {
        cin >> a[i] >> b[i] >> d[i];
        a[i]--;
        b[i]--;
        dd[i] = d[i];
    }

    sort( dd + 1 , dd + M + 1);
    critical.push_back( dd[1] );
    for (int i = 2; i <= M; i++)
    {
        if ( dd[i] != dd[i-1] )
            critical.push_back( dd[i] );
    }

    if ( dd[1] != 0 )
    {
        cout << "Impossible" << endl;
        return 0;
    }

    Vector x;
    x.v[0] = x.v[1] = x.v[2] = x.v[3] = x.v[4] = 0;
    x.v[0] = 1;
    critical.push_back( inf );

    I.N = N;
    I.FillZeros();
    for ( int i = 0; i < N; i++ )
        I.put( i , i );

    for (int i = 0; i < critical.size(); i++)
    {
        Matrix A;
        A.N = N;
        A.FillZeros();
        GetBits( A , critical[i] , M );

        int ans = CheckAns( A , x , N , min( critical[i + 1] - critical[i] , N ) );
        if ( ans != inf )
        {
            cout << critical[i] + ans << endl;
            return 0;
        }

        if ( i == critical.size() - 1 ) break;

        A = pow( A , critical[i + 1] - critical[i] );
        x = A * x;
    }

    cout << "Impossible" << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <stack>
#include <cstdio>
using namespace std;
const int SUPER_KONSTANTA_FOR_REAL_PACAN_1337 = 228;
const int leet = 1337;
const int MAXN = 155;
const long long modulo = 1000000007;
const int inf = 2000001337;
const int L = 30;

struct Matrix
{
    int N;
    unsigned int rows[MAXN][5], columns[MAXN][5];

    void FillZeros()
    {
        for (int i = 0; i < MAXN; i++)
        {
            for (int j = 0; j < 5; j++)
                rows[i][j] = columns[i][j] = 0;
        }
    }

    void put( int i , int j )
    {
        int colJ = j / L;
        int colBitPos = j % L;

        rows[i][colJ] |= (1 << colBitPos);

        int rowI = i / L;
        int rowBitPos = i % L;

        columns[j][rowI] |= (1 << rowBitPos);
    }

    void print()
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                int x = rows[ i ][ j / L ] & ( 1 <<  (j % L) );
                if ( x != 0 ) x = 1;
                cout << x << " ";
            }
            cout << endl;
        }
    }
};

struct Vector
{
    unsigned int v[5];
};

Matrix operator *( Matrix A , Matrix B )
{
    Matrix C;
    C.FillZeros();
    C.N = A.N;
    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            for (int k = 0; k < 5; k++)
            {
                unsigned int x = A.rows[i][k] & B.columns[j][k];
                if ( x != 0 )
                {
                    C.put( i , j );
                    break;
                }
            }
        }
    }

    return C;
}

Vector operator *( Matrix A , Vector x )
{
    Vector y;
    for (int i = 0; i < 5; i++)
        y.v[i] =0;

    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        unsigned int q;
        for (int k = 0; k < 5; k++)
        {
            q = A.rows[i][k] & x.v[k];
            if ( q != 0 ) break;
        }

        if ( q != 0 ) q = 1;
        y.v[ i / L ] ^= (q << ( i % L ));
    }

    return y;
}

int a[MAXN], b[MAXN], d[MAXN], dd[MAXN];
vector<int> critical;
Matrix I;

void GetBits( Matrix& A , int X , int M )
{
    for (int i = 1; i <= M; i++)
    {
        if ( d[i] <= X )
        {
            A.put( b[i] , a[i] );
        }
    }
}

Matrix pow( Matrix A, int b )
{
    if ( b == 0 ) return I;
    Matrix B = pow( A , b / 2 );
    B = B * B;
    if ( b % 2 == 1 ) B = B * A;
    return B;
}

int CheckAns(  Matrix A , Vector x , int T , int S )
{
    T--;
    for ( int i = 1; i <= S; i++)
    {
        x = A * x;
        if ( (x.v[ T / L ] & ( 1 << (T % L) )) != 0 ) return i;
    }

    return inf;
}

int main()
{
    //freopen("input.in" , "r" , stdin);
    int N , M;
    cin >> N >> M;

    for (int i = 1; i <= M; i++)
    {
        cin >> a[i] >> b[i] >> d[i];
        a[i]--;
        b[i]--;
        dd[i] = d[i];
    }

    sort( dd + 1 , dd + M + 1);
    critical.push_back( dd[1] );
    for (int i = 2; i <= M; i++)
    {
        if ( dd[i] != dd[i-1] )
            critical.push_back( dd[i] );
    }

    if ( dd[1] != 0 )
    {
        cout << "Impossible" << endl;
        return 0;
    }

    Vector x;
    x.v[0] = x.v[1] = x.v[2] = x.v[3] = x.v[4] = 0;
    x.v[0] = 1;
    critical.push_back( inf );

    I.N = N;
    I.FillZeros();
    for ( int i = 0; i < N; i++ )
        I.put( i , i );

    for (int i = 0; i < critical.size() - 1; i++)
    {
        Matrix A;
        A.N = N;
        A.FillZeros();
        GetBits( A , critical[i] , M );

        int ans = CheckAns( A , x , N , min( critical[i + 1] - critical[i] , N ) );
        if ( ans != inf )
        {
            cout << critical[i] + ans << endl;
            return 0;
        }

        if ( i == critical.size() - 2 ) break;

        A = pow( A , critical[i + 1] - critical[i] );
        x = A * x;
    }

    cout << "Impossible" << endl;

    return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <stack>
#include <cstdio>
using namespace std;
const int SUPER_KONSTANTA_FOR_REAL_PACAN_1337 = 228;
const int leet = 1337;
const int MAXN = 155;
const long long modulo = 1000000007;
const int inf = 1000001337;

bool curr[MAXN] = {false}, next[MAXN] = {false};
int d[MAXN];
vector< pair<int , int > > p[MAXN];

bool HasNotModified( int N )
{
    for (int i = 1; i <= N; i++)
        if ( curr[i] != next[i] ) return false;

    return true;
}

int main()
{
    //freopen("input.in" , "r" , stdin);
    int N , M;
    cin >> N >> M;

    for (int i = 1; i <= M; i++)
    {
        int a, b, d[i];
        cin >> a >> b >> d[i];
        p[a].push_back( { b , d[i] } );
    }

    sort( d + 1 , d + M + 1 );

    int step = 0;
    curr[1] = true;

    while ( true )
    {
        for (int i = 1; i <= N; i++)
        {
            next[i] = false;
        }

        for (int v = 1; v <= N; v++)
        {
            if ( !curr[v] ) continue;

            for (int i = 0; i < p[v].size(); i++)
            {
                if ( p[v][i].second <= step )
                    next[ p[v][i].first ] = true;
            }
        }

        if ( next[ N ] )
        {
            cout << step + 1 << endl;
            return 0;
        }

        if ( HasNotModified( N ) )
        {
            if ( step >= d[M] )
            {
                cout << "Impossible" << endl;
                return 0;
            }

            int i = 1;
            while ( d[i] <= step ) i++;
            step = d[i];
        }
        else
        {
            step++;
            for (int i = 1; i <= N; i++)
                curr[i] = next[i];
        }

    }

    return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <stack>
#include <cstdio>
using namespace std;
const int SUPER_KONSTANTA_FOR_REAL_PACAN_1337 = 228;
const int leet = 1337;
const int MAXN = 155;
const long long modulo = 1000000007;
const int inf = 2000001337;
const int L = 30;

struct Matrix
{
    int N;
    unsigned int rows[MAXN][5], columns[MAXN][5];

    void FillZeros()
    {
        for (int i = 0; i < MAXN; i++)
        {
            for (int j = 0; j < 5; j++)
                rows[i][j] = columns[i][j] = 0;
        }
    }

    void put( int i , int j )
    {
        int colJ = j / L;
        int colBitPos = j % L;

        rows[i][colJ] ^= (1 << colBitPos);

        int rowI = i / L;
        int rowBitPos = i % L;

        columns[j][rowI] ^= (1 << rowBitPos);
    }

    void print()
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                int x = rows[ i ][ j / L ] & ( 1 <<  (j % L) );
                if ( x != 0 ) x = 1;
                cout << x << " ";
            }
            cout << endl;
        }
    }
};

struct Vector
{
    unsigned int v[5];
};

Matrix operator *( Matrix A , Matrix B )
{
    Matrix C;
    C.FillZeros();
    C.N = A.N;
    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            for (int k = 0; k < 5; k++)
            {
                unsigned int x = A.rows[i][k] & B.columns[j][k];
                if ( x != 0 )
                {
                    C.put( i , j );
                    break;
                }
            }
        }
    }

    return C;
}

Vector operator *( Matrix A , Vector x )
{
    Vector y;
    for (int i = 0; i < 5; i++)
        y.v[i] =0;

    int N = A.N;

    for (int i = 0; i < N; i++)
    {
        unsigned int q = 0;
        for (int k = 0; k < 5; k++)
        {
            q = A.rows[i][k] & x.v[k];
            if ( q != 0 ) break;
        }

        if ( q != 0 ) q = 1;
        y.v[ i / L ] ^= (q << ( i % L ));
    }

    return y;
}

int a[MAXN], b[MAXN], d[MAXN], dd[MAXN];
vector<int> critical;
Matrix I;

void GetBits( Matrix& A , int X , int M )
{
    for (int i = 1; i <= M; i++)
    {
        if ( d[i] <= X )
        {
            A.put( b[i] , a[i] );
        }
    }
}

Matrix pow( Matrix A, int b )
{
    if ( b == 0 ) return I;
    Matrix B = pow( A , b / 2 );
    B = B * B;
    if ( b % 2 == 1 ) B = B * A;
    return B;
}

int CheckAns(  Matrix A , Vector x , int T , int S )
{
    T--;
    for ( int i = 1; i <= S; i++)
    {
        x = A * x;
        if ( (x.v[ T / L ] & ( 1 << (T % L) )) != 0 ) return i;
    }

    return inf;
}

int main()
{
    //freopen("input.in" , "r" , stdin);
    int N , M;
    cin >> N >> M;

    for (int i = 1; i <= M; i++)
    {
        cin >> a[i] >> b[i] >> d[i];
        a[i]--;
        b[i]--;
        dd[i] = d[i];
    }

    sort( dd + 1 , dd + M + 1);
    critical.push_back( dd[1] );
    for (int i = 2; i <= M; i++)
    {
        if ( dd[i] != dd[i-1] )
            critical.push_back( dd[i] );
    }

    if ( dd[1] != 0 )
    {
        cout << "Impossible" << endl;
        return 0;
    }

    Vector x;
    x.v[0] = x.v[1] = x.v[2] = x.v[3] = x.v[4] = 0;
    x.v[0] = 1;
    critical.push_back( inf );

    I.N = N;
    I.FillZeros();
    for ( int i = 0; i < N; i++ )
        I.put( i , i );

    for (int i = 0; i < critical.size() - 1; i++)
    {
        Matrix A;
        A.N = N;
        A.FillZeros();
        GetBits( A , critical[i] , M );

        int ans = CheckAns( A , x , N , min( critical[i + 1] - critical[i] , N ) );
        if ( ans != inf )
        {
            cout << critical[i] + ans << endl;
            return 0;
        }

        if ( i == critical.size() - 2 ) break;

        A = pow( A , critical[i + 1] - critical[i] );
        x = A * x;
    }

    cout << "Impossible" << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN = 155;
const int INF  = 2e9;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
struct vec {bitset <MAXN> a; };
struct mat {bitset <MAXN> r[MAXN], c[MAXN]; };
int n, m;
vec Veccipher() {
	vec ans; ans.a.reset();
	return ans;
}
mat Matcipher() {
	mat ans;
	for (int i = 1; i <= n; i++) {
		ans.r[i].reset();
		ans.c[i].reset();
	}
	ans.r[n].set(n);
	ans.c[n].set(n);
	return ans;
}
mat unit() {
	mat ans;
	for (int i = 1; i <= n; i++) {
		ans.r[i].reset();
		ans.c[i].reset();
		ans.r[i].set(i);
		ans.c[i].set(i);
	}
	return ans;
}
vec operator * (vec a, mat b) {
	vec ans;
	for (int i = 1; i <= n; i++)
		if ((a.a & b.c[i]).count() != 0) ans.a[i] = true;
		else ans.a[i] = false;
	return ans;
}
mat operator * (mat a, mat b) {
	mat ans;
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++) {
		if ((a.r[i] & b.c[j]).count() != 0) ans.r[i][j] = ans.c[j][i] = true;
		else ans.r[i][j] = ans.c[j][i] = false;
	}
	return ans;
}
mat power(mat x, int y) {
	if (y == 0) return unit();
	mat tmp = power(x, y / 2);
	if (y % 2 == 0) return tmp * tmp;
	else return tmp * tmp * x;
}
pair <pair <int, int>, int> e[MAXN];
bool cmp(pair <pair <int, int>, int> x, pair <pair <int, int>, int> y) {
	return x.second < y.second;
}
int main() {
	read(n), read(m);
	for (int i = 1; i <= m; i++) {
		read(e[i].first.first);
		read(e[i].first.second);
		read(e[i].second);
	}
	sort(e + 1, e + m + 1, cmp);
	e[m + 1] = make_pair(make_pair(1, 1), INF);
	vec now = Veccipher(); now.a[1] = true;
	mat tmp = Matcipher();
	for (int i = 1; i <= m + 1; i++) {
		int cnt = e[i].second - e[i - 1].second;
		vec tnp = now * power(tmp, cnt);
		if (tnp.a[n]) {
			int ans = e[i - 1].second;
			while (now.a[n] == 0) {
				ans++;
				now = now * tmp;
			}
			cout << ans << endl;
			return 0;
		}
		int x = e[i].first.first, y = e[i].first.second;
		tmp.r[x][y] = tmp.c[y][x] = true; now = tnp;
	}
	puts("Impossible");
	return 0;
}


#include <bits/stdc++.h>

#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
typedef vector < int > VI;
typedef double D;

const int MN = 155, inf = 1000000005, mod = 1000000007;
const LL INF = 1000000000000000005LL;

struct matrix
{
	bitset < MN > wie[MN], kol[MN];
};

matrix operator*(matrix a, matrix b)
{
	matrix res;
	for(int i = 1; i < MN; ++i)
		for(int j = 1; j < MN; ++j)
			res.wie[i][j] = res.kol[j][i] = ((a.wie[i] & b.kol[j]).count() > 0 ? 1 : 0);
	return res;
}

matrix zero()
{
	matrix res;
	for(int i = 1; i < MN; ++i)
		res.wie[i][i] = res.kol[i][i] = 1;
	return res;
}

matrix pot(matrix a, int wyk)
{
	matrix res = zero();
	while(wyk)
	{
		if(wyk & 1)
			res = res * a;
		a = a * a;
		wyk >>= 1;
	}
	return res;
}

pair < int , PII > kraw[MN];

VI G[MN];
int used[MN];

queue < int > Q;

int n;

int bfs(int v)
{
	Q.push(v);
	for(int i = 1; i <= n; ++i)
		used[i] = 0;
	used[v] = 1;
	while(!Q.empty())
	{
		int cur = Q.front();
		Q.pop();
		for(auto x : G[cur])
			if(!used[x])
			{
				used[x] = used[cur] + 1;
				Q.push(x);
			}
	}
	return (used[n] == 0 ? inf : used[n] - 1);
}

int main()
{
	int m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++i)
	{
		int a, b, d;
		scanf("%d%d%d", &a, &b, &d);
		kraw[i] = {d, {a, b}};
	}
	sort(kraw + 1, kraw + 1 + m);
	matrix drogi, mozna;
	mozna.kol[1][1] = mozna.wie[1][1] = 1;
	mozna.kol[n][n] = mozna.wie[n][n] = drogi.kol[n][n] = drogi.wie[n][n] = 1;
	int res = inf;
	for(int i = 1; i <= m; ++i)
	{
		int dif = kraw[i].fi - kraw[i - 1].fi;
		mozna = mozna * pot(drogi, dif);
		int a = kraw[i].se.fi, b = kraw[i].se.se;
		G[a].pb(b);
		drogi.wie[a][b] = drogi.kol[b][a] = 1;
		for(int j = 1; j <= n; ++j)
			if(mozna.wie[1][j])
				res = min(res, kraw[i].fi + bfs(j));
	}
	if(res == inf)
		printf("Impossible");
	else
		printf("%d\n", res);
}


#include <bits/stdc++.h>

#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
typedef vector < int > VI;
typedef double D;

const int MN = 155, inf = 1100000005, mod = 1000000007;
const LL INF = 1000000000000000005LL;

struct matrix
{
	bitset < MN > wie[MN], kol[MN];
};

matrix operator*(matrix a, matrix b)
{
	matrix res;
	for(int i = 1; i < MN; ++i)
		for(int j = 1; j < MN; ++j)
			res.wie[i][j] = res.kol[j][i] = ((a.wie[i] & b.kol[j]).count() > 0 ? 1 : 0);
	return res;
}

matrix zero()
{
	matrix res;
	for(int i = 1; i < MN; ++i)
		res.wie[i][i] = res.kol[i][i] = 1;
	return res;
}

matrix pot(matrix a, int wyk)
{
	matrix res = zero();
	while(wyk)
	{
		if(wyk & 1)
			res = res * a;
		a = a * a;
		wyk >>= 1;
	}
	return res;
}

pair < int , PII > kraw[MN];

VI G[MN];
int used[MN];

queue < int > Q;

int n;

int bfs(int v)
{
	Q.push(v);
	for(int i = 1; i <= n; ++i)
		used[i] = 0;
	used[v] = 1;
	while(!Q.empty())
	{
		int cur = Q.front();
		Q.pop();
		for(auto x : G[cur])
			if(!used[x])
			{
				used[x] = used[cur] + 1;
				Q.push(x);
			}
	}
	return (used[n] == 0 ? inf : used[n] - 1);
}

int main()
{
	int m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; ++i)
	{
		int a, b, d;
		scanf("%d%d%d", &a, &b, &d);
		kraw[i] = {d, {a, b}};
	}
	sort(kraw + 1, kraw + 1 + m);
	matrix drogi, mozna;
	mozna.kol[1][1] = mozna.wie[1][1] = 1;
	mozna.kol[n][n] = mozna.wie[n][n] = drogi.kol[n][n] = drogi.wie[n][n] = 1;
	int res = inf;
	for(int i = 1; i <= m; ++i)
	{
		int dif = kraw[i].fi - kraw[i - 1].fi;
		mozna = mozna * pot(drogi, dif);
		int a = kraw[i].se.fi, b = kraw[i].se.se;
		G[a].pb(b);
		drogi.wie[a][b] = drogi.kol[b][a] = 1;
		for(int j = 1; j <= n; ++j)
			if(mozna.wie[1][j])
				res = min(res, kraw[i].fi + bfs(j));
	}
	if(res == inf)
		printf("Impossible");
	else
		printf("%d\n", res);
}