#if !defined(__clang__) && defined(__GNUC__)
#include <bits/stdc++.h>
#else
#include <cstdlib>
#include <climits>
#include <iostream>
#include <cstdint>
#include <vector>
#include <string>
#include <complex>
#include <bitset>
#include <queue>
#include <deque>
#include <stack>
#include <utility>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <regex>
#endif //  !defined(__clang__) && defined(__GNUG__)
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/multi_array.hpp>

using namespace std;

#include <boost/optional.hpp>



/// 距離つきグラフ
template<typename T, typename D, D nonval>
class Gr {
public:
    using edge = std::unordered_map<T, D>;
    using vertex_iterator = typename std::unordered_map<T, edge>::iterator;
    using vertex_const_iterator = typename std::unordered_map<T, edge>::const_iterator;

    Gr(T vertex_count, T edge_count) :
        vertex_count_(vertex_count), edge_count_(edge_count)
    {}

    // 値設定
    void set(T from, T to, D distance) {
        mat_[from][to] = distance;
    }

    // 距離
    D distance(T from, T to) const {
        if (mat_.find(from) != mat_.end()) {
            if (mat_[from].find(to) != mat_[from].end()) {
                return mat_[from][to];
            }
        }
        return nonval;
    }

    // 起点頂点をイテレート
    vertex_iterator from_vertex_begin() {
        return mat_.begin();
    }
    vertex_iterator from_vertex_end() {
        return mat_.end();
    }

    vertex_const_iterator from_vertex_cbegin() const {
        return mat_.begin();
    }

    vertex_const_iterator from_vertex_cend() const {
        return mat_.end();
    }

    // とある起点頂点からの辺をイテレート
    typename edge::iterator edge_begin(T from) {
        return mat_[from].begin();
    }
    typename edge::iterator edge_end(T from) {
        return mat_[from].end();
    }

    /**
        最短経路を計算

        ベルマンフォード法 O(V*E)

        @code
        int64_t N, M;
        std::cin >> N >> M;

        Gr<int64_t, int64_t, 0> g(N, M);
        for (size_t i = 0; i < M; ++i) {
            int64_t a, b, c;
            std::cin >> a >> b >> c;
            a--;
            b--;
            g.set(a, b, c);
        }
        @endcode
    */
    boost::optional<std::vector<T>> find_shortest_path(T start, T loop_detect_goal) const {
        constexpr T INF = std::numeric_limits<T>::max() / 2 + 1;
        std::vector<D> d(vertex_count_, INF);
        d[start] = 0;

        for (T i = 0; i < vertex_count_ * 2; ++i) {
            bool update = false;
            // 辺をイテレート
            for (auto&& f = from_vertex_cbegin();
                 f != from_vertex_cend();
                 ++f)
            {
                for (auto&& e = f->second.begin();
                     e != f->second.end();
                     ++e)
                {
                    const auto from = f->first;
                    const auto to = e->first;
                    const auto cost = e->second;
                    if (d[from] != INF && d[to] > d[from] + cost) {
                        d[to] = d[from] + cost;
                        update = true;

                        if (i >= vertex_count_ - 1 && to == loop_detect_goal) {
                            return boost::none;
                        }

                    }
                }
            }
            if (!update) {
                break;
            }
         }
         return d;
    }

private:
    T vertex_count_;
    T edge_count_;
    std::unordered_map<T, edge> mat_;
};

int main()
{
    int64_t N, M;
    std::cin >> N >> M;

    Gr<int64_t, int64_t, 0> g(N, M);
    for (size_t i = 0; i < M; ++i) {
        int64_t a, b, c;
        std::cin >> a >> b >> c;
        a--;
        b--;
        g.set(a, b, c * -1LL);
    }

    auto d = g.find_shortest_path(0, N-1);
    if (!d) {
        std::cout << "inf" << std::endl;
    }
    else {
        int64_t r = (*d)[N-1] * (-1ll);
        std::cout << r << std::endl;
    }

    return 0;
}


Measured memory_bytes: 384