Problem:
Score : 400 points

Problem Statement

There is a directed graph with N vertices and M edges.
The i-th edge (1≤i≤M) points from vertex a_i to vertex b_i, and has a weight c_i.
We will play the following single-player game using this graph and a piece.

Initially, the piece is placed at vertex 1, and the score of the player is set to 0.
The player can move the piece as follows:

When the piece is placed at vertex a_i, move the piece along the i-th edge to vertex b_i. After this move, the score of the player is increased by c_i.

The player can end the game only when the piece is placed at vertex N.
The given graph guarantees that it is possible to traverse from vertex 1 to vertex N.

When the player acts optimally to maximize the score at the end of the game, what will the score be?
If it is possible to increase the score indefinitely, print inf.

Constraints

2≤N≤1000

1≤M≤min(N(N-1),2000)

1≤a_i,b_i≤N (1≤i≤M)

a_i≠b_i (1≤i≤M)

a_i≠a_j or b_i≠b_j (1≤i<j≤M)

-10^9≤c_i≤10^9 (1≤i≤M)

c_i is an integer.

In the given graph, there exists a path from vertex 1 to vertex N.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1 c_1
a_2 b_2 c_2
:
a_M b_M c_M

Output

Print the maximum possible score at the end of the game, if it is finite. If it is possible to increase the score indefinitely, print inf.

Sample Input 1

3 3
1 2 4
2 3 3
1 3 5

Sample Output 1

7

There are two ways to move the piece to vertex N=3:

vertex 1 → vertex 2 → vertex 3 : score 4+3=7

vertex 1 → vertex 3 : score 5

Thus, the maximum possible score at the end of the game is 7.

Sample Input 2

2 2
1 2 1
2 1 1

Sample Output 2

inf

It is possible to increase the score indefinitely by alternating between vertex 1 and 2.

Sample Input 3

6 5
1 2 -1000000000
2 3 -1000000000
3 4 -1000000000
4 5 -1000000000
5 6 -1000000000

Sample Output 3

-5000000000

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

/*
cat <<EOF >mistaken-paste
*/

#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>

#define BIG 2000000007
#define VERYBIG 200000000000007

#define MOD 1000000007
typedef uint64_t ull;
typedef  int64_t sll;

#define N_MAX 1000
#define M_MAX 40000

typedef struct {
	int32_t a;
	int32_t b;
} hw;

typedef struct {
	sll a;
	sll b;
} hwll;

typedef struct {
	hwll a;
	hwll b;
} linell;


typedef struct {
	ull s;
	ull t;
	int32_t c;
} struct_a;

typedef struct {
	int32_t from;
	int32_t to;
	sll cost;
} struct_b;



const hw vector8[8] = {
	{-1, -1},
	{-1,  0},
	{-1, +1},
	{ 0, -1},
	{ 0, +1},
	{+1, -1},
	{+1,  0},
	{+1, +1}
};

ull n, m;
ull h, w;
ull k;
ull vua, vub, vuc, vud, vue, vuf;
sll vsa, vsb, vsc, vsd, vse, vsf;
long double vra, vrb, vrc;
double vda, vdb, vdc;
size_t slen;
size_t tlen;
// ull a[N_MAX];
ull a[M_MAX];
// sll a[N_MAX];
// ull a[N_MAX][N_MAX];
ull wall[N_MAX][N_MAX];
// ull b[N_MAX];
ull b[M_MAX];
// sll b[N_MAX];
// ull b[N_MAX][N_MAX];
// sll b[N_MAX][N_MAX];
// ull c[N_MAX];
// ull c[M_MAX];
sll c[M_MAX];
// char s[N_MAX + 1];
// char t[N_MAX + 1];
// char s[N_MAX][M_MAX + 1];
ull alphabets[26];

// ull dp[N_MAX];
// sll dp[N_MAX];
// bool dp[N_MAX];
// ull dq[N_MAX];
// ull dp[N_MAX + 1][M_MAX + 1];
// ull dq[M_MAX][N_MAX];
// bool dq[N_MAX];
// hwll dp[N_MAX + 1][N_MAX + 1];
// struct_a dp[N_MAX + 1][N_MAX + 1];

int32_t dp[N_MAX];

// hw arr[N_MAX];
// hwll arr[N_MAX * 2];
// hw brr[M_MAX];
// linell arr[N_MAX][N_MAX];

ull bitdp[1 << 8];

// ull digitdp[1001][   3][    2];
//           pos  less  carry
// ull digitdp[1001][    2];
//           pos  carry


// struct_a arr[N_MAX * 2];
// struct_b brr[N_MAX * 2];

void swap_adj (ull *a, ull *b) {
	if (*a != *b) {
		ull tmp = *b;
		*b = *a;
		*a = tmp;
	}
	return;
}

ull divide (ull a, ull b) {
	ull x = MOD - 2;
	ull ans = 1;
	while (x) {
		if (x & 1) ans = (ans * b) % MOD;
		b = (b * b) % MOD;
		x /= 2;
	}
	return (a * ans) % MOD;
}

int32_t digits (ull x) {
	int32_t i = 1;
	while (x >= 10) {
		x /= 10;
		i++;
	}
	return i;
}

ull umin (ull x, ull y) {
	return (x < y) ? x : y;
}

ull umax (ull x, ull y) {
	return (x > y) ? x : y;
}

sll smin (sll x, sll y) {
	return (x < y) ? x : y;
}

sll smax (sll x, sll y) {
	return (x > y) ? x : y;
}

ull gcd (ull x, ull y) {
	if (x < y) {
		return gcd(y, x);
	} else if (y == 0) {
		return x;
	} else {
		return gcd(y, x % y);
	}
}

ull bitpow (ull a, ull x, ull modulo) {
	ull result = 1;
	while (x) {
		if (x & 1) {
			result *= a;
			result %= modulo;
		}
		x /= 2;
		a = (a * a) % modulo;
	}
	return result;
}

int32_t targetdig (ull x, int32_t index /* 1-indexed */) {
	// static...?
	int32_t posmax = digits(x);
	if (posmax < index) return -1;
	while (posmax > index) {
		posmax--;
		x /= 10;
	}
	return x % 10;
}

int32_t charcomp (const char left, const char right) {
	if (left < right) {
		return -1;
	} else if (left > right) {
		return +1;
	} else {
		return 0;
	}
}

int32_t pcharcomp (const char *left, const char *right) {
	return charcomp(*left, *right);
}

int32_t pcharrevcomp (const char *left, const char *right) {
	return charcomp(*right, *left);
}

int32_t intcomp (const int32_t left, const int32_t right) {
	if (left < right) {
		return -1;
	} else if (left > right) {
		return +1;
	} else {
		return 0;
	}
}

int32_t pintcomp (const int32_t *left, const int32_t *right) {
	return intcomp(*left, *right);
}

int32_t ullcomp (const ull left, const ull right) {
	if (left < right) {
		return -1;
	} else if (left > right) {
		return +1;
	} else {
		return 0;
	}
}

int32_t pullcomp (const ull *left, const ull *right) {
	return ullcomp(*left, *right);
}

int32_t sllcomp (const sll left, const sll right) {
	if (left < right) {
		return -1;
	} else if (left > right) {
		return +1;
	} else {
		return 0;
	}
}

int32_t hwllfraccomp (const hwll left, const hwll right) {
	return ullcomp(left.a * right.b, left.b * right.a);
}

int32_t psllcomp (const sll *left, const sll *right) {
	return sllcomp(*left, *right);
}

int32_t phwAcomp (const hw *left, const hw *right) {
	return intcomp(left->a, right->a);
}

int32_t phwBcomp (const hw *left, const hw *right) {
	return intcomp(left->b, right->b);
}

int32_t phwABcomp (const hw *left, const hw *right) {
	int32_t x = phwAcomp(left, right);
	if (x) return x;
	return phwBcomp(left, right);
}

int32_t phwllAcomp (const hwll *left, const hwll *right) {
	return sllcomp(left->a, right->a);
}

int32_t phwllBcomp (const hwll *left, const hwll *right) {
	return sllcomp(left->b, right->b);
}

int32_t phwllABcomp (const hwll *left, const hwll *right) {
	int32_t x = phwllAcomp(left, right);
	if (x) return x;
	return phwllBcomp(left, right);
}

int32_t pstrAcomp (const struct_a *left, const struct_a *right) {
	int32_t x;
	if (x = ullcomp(left->t, right->t)) return x;
	if (x = ullcomp(left->s, right->s)) return x;
	if (x = intcomp(left->c, right->c)) return x;
	return 0;
}

int32_t bitlet (char c) {
	return (1 << (c - 'a'));
}

ull ullabs (ull a, ull b) {
	if (a >= b) {
		return a - b;
	} else {
		return b - a;
	}
}

sll sllabs (sll a, sll b) {
	if (a >= b) {
		return a - b;
	} else {
		return b - a;
	}
}

sll nibutanlobo (bool (*func)(sll arg), sll ok, sll ng) {
	while (sllabs(ok, ng) > 1) {
		sll med = (ok + ng) / 2;
		if (func(med)) {
			ok = med;
		} else {
			ng = med;
		}

		// printf("debug: [%lld %lld)\n", ok, ng);
	}

	if (!func(ok)) return ok * 2 - ng;
	return ok;
}

bool nextroute (int32_t arr[], int32_t n) {
	int32_t i = n - 1;
	int32_t j, x;

	while (i > 0 && arr[i - 1] > arr[i]) i--;
	if (i == 0) return false;

	x = n;
	for (j = i; j < n; j++) {
		if (arr[j] < arr[i - 1]) continue;
		if (x == n || arr[x] > arr[j]) x = j;
	}
	arr[i - 1] ^= arr[x];
	arr[x] ^= arr[i - 1];
	arr[i - 1] ^= arr[x];

	qsort(&arr[i], n - i, sizeof(int32_t), pintcomp);
	return true;
}

void printUquotient (ull left, ull right) {
	const int32_t digits = 20;

	printf("%llu.", left / right);
	left %= right;
	for (int32_t i = 0; i < digits; i++) {
		left *= 10;
		printf("%1d", left / right);
		left %= right;
	}
	puts("");

	return;
}

void printSquotient (sll left, sll right) {
	if (left * right < 0) putchar('-');
	printUquotient(sllabs(left, 0), sllabs(right, 0));

	return;
}

int bitcount (ull n) {
	int result = 0;
	while (n) {
		if (n & 1) result++;
		n /= 2;
	}
	return result;
}


bool isonedge (hwll x) {
	return (x.a == 0) || (x.a == h) || (x.b == 0) || (x.b == w);
}

ull converttoint (hwll x) {
	if (x.a == 0) {
		return w - x.b; // w ~ 0
	} else if (x.b == 0) {
		return w + x.a; // w ~ h+w
	} else if (x.a == h) {
		return (h + w) + x.b; // h+w ~ h+2w
	} else {
		return (h + w) * 2 - x.a; // (2h+2w) ~ (h+2w)
	}
}

ull solve () {
	sll i, j, ki, l;
	// ull result = 0;
	sll result = 0;
	ull sum = 0;
	// sll sum = 0;
	ull item;
	ull *dpcell;
	// qsortの際には"p"ullcompを使う

	// if (k % 2 == 0) {
	// 	for (i = 0; i < n; i++) {
	// 		printf("%llu%c", ((i == 0) ? (k / 2 - 1) : (k / 2)), ((i == n - 1) ? '\n' : ' '));
	// 	}
	// } else {
	// 	//
	// }

	// ull p2, p3, p5;
	// p2 = p3 = p5 = 0;
	// while (n % 2) {
	// 	n /= 2;
	// 	p2++;
	// }
	// while (n % 3) {
	// 	n /= 3;
	// 	p3++;
	// }
	// while (n % 5) {
	// 	n /= 5;
	// 	p5++;
	// }
	// if (n > 1) goto fail;

	for (i = 0; i < m; i++) {
		c[i] = -c[i];
	}

	sll d[N_MAX];

	for (i = 0; i < n; i++) {
		d[i] = (i ? VERYBIG : 0);
	}

	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (d[a[i]] != BIG && d[b[i]] > d[a[i]] + c[i]) {
				d[b[i]] = d[a[i]] + c[i];
				if (i == n - 1) goto fail;
			}
		}
	}

	result = -d[n - 1];

	printf("%lld\n", result);
	// puts(s);

	return 0;

	success:
	puts("YES");
	// puts("Yes");
	// printf("%llu\n", result);
	return 0;

	fail:
	// puts("NO");
	// puts("No");
	// puts("0");
	// puts("-1");
	puts("inf");
	return 1;
}

int32_t main (void) {
	int32_t i, j;
	int32_t x, y;

	// scanf("%llu%llu", &h, &w);
	scanf("%llu%llu", &n, &m);
	// scanf("%llu", &k, &n);
	// scanf("%llu%llu%llu", &vua, &vub, &vuc, &vud);
	// scanf("%llu%llu%llu", &vsa, &vsb, &vsc);
	// scanf("%s", s);
	// scanf("%s", t);
	// scanf("%lld%lld", &vsa, &vsb);
	// for (i = 0; i < n; i++) {
	// 	scanf("%llu", &a[i]);
	// }

	// for (i = 0; i < k; i++) {
	// 	scanf("%d", &dp[i]);
	// 	dp[i]--;
	// }
	// for (i = 0; i < h; i++) {
	// 	scanf("%llu", &a[i]);
	// }
	// for (i = 0; i < w; i++) {
	// 	scanf("%llu", &b[i]);
	// }
	for (i = 0; i < m; i++) {
		scanf("%llu%llu%lld", &a[i], &b[i], &c[i]);
		a[i]--;
		b[i]--;
	}
	// for (i = 0; i < h; i++) {
	// 	for (j = 0; j < w; j++) {
	// 		scanf("%llu", &a[i][j]);
	// 	}
	// }

	solve();

	// for (i = 0; i < n; i++) {
	// 	// scanf("%llu%llu", &vua, &vub);
	// 	scanf("%f%f%f", &vda, &vdb, &vdc);
	// 	// scanf("%s", s);
	// 	solve();
	// }

	// while (scanf("%llu%llu", &n, &k), n + k) {
	// 	for (i = 0; i < n; i++) {
	// 		scanf("%llu", &a[i]);
	// 	}
	// 	solve();
	// }

	return 0;
}