#include <iostream>
#include <queue>
#include <memory.h>
#define MAX 101
using namespace std;
int n, m;
int edge[MAX][MAX]; //紀錄活動耗費時間
int dp[MAX]; //紀錄最早完成任務i的時間
int rd[MAX]; //紀錄i的入度
int vis[MAX]; //判斷是否已經加入隊列
void jiSuanRD();
void topSort();
void init();
int main(){
int v1, v2, weight;
init();
//建圖
scanf("%d %d", &n, &m);
for(int i = 0; i< m; i++){
scanf("%d %d %d", &v1, &v2, &weight);
edge[v1][v2] = weight; //有向圖
}
topSort();
return 0;
}
void init(){
memset(rd, 0, sizeof(rd));
memset(vis, 0, sizeof(vis));
memset(edge, 0, sizeof(edge));
memset(dp, 0, sizeof(dp));
}
void topSort(){
jiSuanRD(); //計算各頂點的入度
dp[0] = 0; //初始值
queue<int> q;
int flag = 1; //判斷是否有任务点加入
int cnt = 0; //已完成的任務數目
while(flag){
flag = 0;
for(int i = 0; i < n; i++){
if(vis[i] == 0 && rd[i] == 0){
q.push(i);
vis[i] = 1; //需要遍歷完所有結點,不加vis的話最出現死循環,因為rd[i]最后都都等於0
flag = 1; //循環結束的判定條件
cnt ++; //決定能否完成所有任務
}
}
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i = 0; i < n; i ++){
if(edge[tmp][i]){ //tmp->i,求出任務i最早完成時間
if(dp[i] < edge[tmp][i] + dp[tmp]){
dp[i] = edge[tmp][i] + dp[tmp];
}
rd[i] --; //結點i的入度減1
}
}
}
}
if(cnt == n){
int max = 0;
for(int i = 0; i< n; i++){ //n-1不一定就是終點
if(dp[i] > max){
max = dp[i];
}
}
printf("%d\n", max);
}
else { //證明有環路存在
printf("Impossible\n");
}
}
void jiSuanRD(){
for(int i =0; i< n; i++){
for(int j = 0; j < n; j ++){
if(edge[i][j]){
rd[j] ++;
}
}
}
}