#include <bits/stdc++.h>
using namespace std;

//C++14 (GCC 5.4.1)

#define LLINF (1LL<<60)
typedef long long ll;
typedef pair<ll,ll> RR;
#define mod 1000000007

#define repd(i,a,b) for (int i=(a);i<(b);i++)
#define rep(i,n) repd(i,0,n)
#define rrepd(i,a,b) for(int i=(a);i>=(b);i--)

template<typename T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<typename T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template < typename T > inline string toString( const T &a ) { ostringstream oss; oss << a; return oss.str(); }

#define dbg_v1(i,V) do{cout<<"-v1----\n";rep(i,V.size())cout<<" "<<i<<"\t:"<<V[i]<<endl;cout<<endl;}while(0)
#define dbg_v2(i,k,V) do{cout<<"-v2----\n";rep(i,V.size()){rep(k,V[0].size())cout<<" "<<V[i][k];cout<<endl;}}while(0)

//グラフ処理クラス

//共通
template<class T>
class edge{
public:
    edge(int to, T cost) : to(to),cost(cost){}
    int to;
    T cost;
};
template<class T>
class graph{
protected:
    vector<vector<edge<T>>> G;
    int node_size;
public:
    graph(const int node_size) :
        node_size(node_size),
        G(node_size)
        {}
    void direct(int from,int to,T cost){
        G[from].push_back(edge<T>(to,cost));
    }
    void join(int a,int b,ll cost){
        G[a].push_back(edge<T>(a,cost));
        G[b].push_back(edge<T>(b,cost));
    }
};
//ベルマンフォード法
template<class T,class Compare = less<T>>
class bellman_ford : public graph<T>{
private:
    int idx_start;
    vector<int> pred;
    vector<T> costs;
    bool is_negative;
    T Ls,Gt;
    vector<bool> is_negative_pass;
public:
    bellman_ford(const int node_size) : 
        graph<T>(node_size),
        idx_start(0),
        pred(node_size),
        costs(node_size+1),
        is_negative(false),
        is_negative_pass(node_size+1,false)
        {
             if(Compare()(0,1)) Ls=std::numeric_limits<T>::lowest(),Gt=std::numeric_limits<T>::max();
             else Ls=std::numeric_limits<T>::max(),Gt=std::numeric_limits<T>::lowest();
        }
    void calc(int start){
        idx_start=start;

        pred.assign(this->node_size+1,INT_MAX);
        costs.assign(this->node_size+1,Gt);

        is_negative_pass.assign(this->node_size+1,false);
        pred[idx_start]=-1;
        costs[idx_start]=0;
        rep(i,this->node_size*2){
            rep(j,this->node_size)for(auto &nn : this->G[j]){
                if(costs[j]==Gt)continue;
                ll nn_c=nn.cost+costs[j];
                if(Compare()(nn_c , costs[nn.to])){
                    costs[nn.to]=nn_c;
                    pred[nn.to]=j;
                    if(i==this->node_size-1 ){
                        //found negative cycle
                        is_negative=true;
                        is_negative_pass[nn.to]=true;
                    }
                }
                if(is_negative_pass[j]) is_negative_pass[nn.to]=true;
            }
        }
    }
    bool has_negative_cycle() const{
        return is_negative;
    }
    bool is_negative_cycle(int idx_end) const{
        return is_negative_pass[idx_end];
    }
    ll get_cost(int idx_end) const{
      return is_negative_pass[idx_end] ? Ls : costs[idx_end];
    }
};
int main() {
    ios::sync_with_stdio(false);//stdoutとcoutの同期解除
    cin.tie(nullptr);//cinとcoutの同期解除
    
    int N,M;
    cin >>N>>M;

    bellman_ford<ll,greater<ll>> X(N);
    int a,b,c;
    rep(i,M){
        cin >> a>>b>>c;
        X.direct(a-1,b-1,c);
    }
    X.calc(0);

    if(X.is_negative_cycle(N-1)){
        cout<<"inf"<<endl;
    }else{
        cout<<X.get_cost(N-1)<<endl;
    }
    return (0);
}

Measured memory_bytes: 384