#include <bits/stdc++.h>
#ifdef __DEBUG__
    #define DBG(X) cout << #X << " = " << (X) << endl;
    #define SAY(X) cout << (X) << endl;
#else
    #define DBG(X)
    #define SAY(X)
#endif

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

int dx[]={1, 0, -1, 0, 1,-1, 1,-1};
int dy[]={0, 1, 0, -1, 1, 1,-1,-1};
const int INT_INF = (int)(2e9);
const ll  LL_INF = (ll)(2e18);

inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const map<T, S> p) { for (auto el : p) cout << "[" << el.first << ";" << el.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for (auto el : v) cout << el << " "; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const deque<T>& v) { for (auto el : v) cout << el << " "; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const set<T>& v) { for (auto el : v) cout << el << " "; return os; }
template<typename T> inline vector<T> fetch_vec(int sz) { vector<T> ret(sz); for (auto& elem : ret) cin >> elem; return ret; }

template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template< typename T >
using Edges = vector< edge< T > >;

template< typename T >
vector< T > bellman_ford(Edges< T > &edges, int V, int s) {
  const auto INF = numeric_limits< T >::max();
  vector< T > dist(V, INF);
  dist[s] = 0;
  for(int i = 0; i < V - 1; i++) {
    for(auto &e : edges) {
      if(dist[e.src] == INF) continue;
      dist[e.to] = min(dist[e.to], dist[e.src] + e.cost);
    }
  }
  // s~V-1上のpathで負閉路がないか検出する。
  vector<bool> reach_s(V,false),reach_t(V,false);
  reach_s[s] = true;
  reach_t[V-1] = true;
  for(int i = 0; i < V - 1; i++) {
    for(auto &e : edges) {
      if(!reach_s[e.src]) continue;
      reach_s[e.to] = reach_s[e.src];
    }
  }

  for(int i = 0; i < V - 1; i++) {
    for(auto &e : edges) {
      if(!reach_t[e.to]) continue;
      reach_t[e.src] = reach_t[e.to];
    }
  }

  for(auto &e : edges) {
    if(dist[e.src] == INF) continue;
    if(!reach_s[e.src]) continue;
    if(!reach_t[e.src]) continue;
    if(dist[e.src] + e.cost < dist[e.to]) return vector< T >();
  }
  return dist;
}


int N,M;
Edges< ll > es;
void input(){
    fast_io();
    cin >> N >> M;
    for (int i = 0; i < M; i++)
    {
        ll a,b,c; cin >> a >> b >> c;
        a--,b--;
        es.emplace_back(a, b, -c);
    }
    
}

int solve(){
    auto dists = bellman_ford(es, N, 0);
    if(dists.empty()) {cout << "inf" << endl; return 0;}
    if(dists[N-1] == numeric_limits< ll >::max()) {cout << "inf" << endl;}
    else cout << (-dists[N-1]) << endl;
    return 0;
}

int main()
{
    input();
    solve();
    return 0;
}

Measured memory_bytes: 3724