#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 105
#define INFINITY -10005
#define MAX_VERTEX_NUM 100
#define ERROR 0
#define OK 1
int TopOrder[MAX_VERTEX_NUM];
int time[MAX_VERTEX_NUM];
typedef int Status;
struct AdjVNode
{
int adjvex;
int weight;
AdjVNode *next;
};
typedef struct VNode
{
AdjVNode *FirstEdge;
} AdjList[MAX_VERTEX_NUM];
typedef struct GNode
{
int Nv;
int Ne;
AdjList vertices;
}*LGraph;
typedef struct ENode
{
int v1,v2;
int weight;
}*Edge;
typedef struct QNode
{
int data;
struct QNode *next;
} QNode,*QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
} LinkQueue;
Status InitQueue(LinkQueue &Q)
{
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front)
exit(0);
Q.front->next = NULL;
return OK;
}
Status QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return 1;
return 0;
}
Status EnQueue(LinkQueue &Q, int e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p)
return ERROR;
p->next = NULL;
p->data = e;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status DeQueue(LinkQueue &Q, int &e)
{
if (Q.front == Q.rear)
return ERROR;
QueuePtr p;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
free(p);
return OK;
}
LGraph CreateLGraph(int n,int m)
{
AdjVNode *NewNode;
int v;
LGraph G=(LGraph)malloc(sizeof(struct GNode));
Edge E=(Edge)malloc(sizeof(struct ENode));
G->Nv=n;
for(v=0; v<n; v++)
{
G->vertices[v].FirstEdge=NULL;
}
for(v=0; v<m; v++)
{
scanf("%d%d%d",&E->v1,&E->v2,&E->weight);
NewNode=(AdjVNode*)malloc(sizeof(AdjVNode));
NewNode->adjvex=E->v2;
NewNode->weight=E->weight;
NewNode->next=G->vertices[E->v1].FirstEdge;
G->vertices[E->v1].FirstEdge=NewNode;
}
return G;
}
int TopSort(LGraph Graph)
{
int Indegree[MAX_VERTEX_NUM], cnt;
int V;
AdjVNode *W;
LinkQueue Q;
InitQueue(Q);
for( V = 0; V<Graph->Nv; V++)
Indegree[V]=0;
for( V = 0; V<Graph->Nv; V++)
for(W = Graph->vertices[V].FirstEdge; W; W = W->next)
Indegree[W->adjvex]++;
for(V = 0; V < Graph->Nv; V++)
if(Indegree[V]==0)
EnQueue(Q, V);
cnt = 0;
while(!QueueEmpty(Q))
{
DeQueue(Q,V);
for(W=Graph->vertices[V].FirstEdge; W!=NULL; W = W->next)
{
if(time[W->adjvex]<time[V]+W->weight)
time[W->adjvex]=time[V]+W->weight;
}
TopOrder[cnt++] = V;
for(W=Graph->vertices[V].FirstEdge; W!=NULL; W = W->next)
{
if(--Indegree[W->adjvex]==0)
EnQueue(Q, W->adjvex);
}
}
if(cnt != Graph->Nv)
return -1;
else
return 1;
}
int main()
{
int n,m;
LGraph G;
scanf("%d%d",&n,&m);
G=CreateLGraph(n,m);
int flag=TopSort(G);
if(flag==1)
{
int Max=time[0];
for(int i=1; i<G->Nv; i++)
{
if(time[i]>Max)
Max=time[i];
}
printf("%d",Max);
}
else
printf("Impossible");
return 0;
}