#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
struct IoSetup {
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        //        cout << fixed << setprecision(20);
        //        cerr << fixed << setprecision(20);
    }
} iosetup;

template <class Info>
struct edge {
    int from, to;
    Info info;
    edge(int to, Info info) : to(to), info(info) {}
    edge(int from, int to, Info info) : from(from), to(to), info(info) {}
};

struct normal_edge {
    normal_edge() {}
};

template <class Info>
class graph {
   protected:
    using edge_type = edge<Info>;
    ::std::size_t N;
    ::std::vector<::std::vector<edge_type>> edges;

   public:
    graph(::std::size_t N_) : N(N_), edges(N_) {}
    virtual void add_edge(int x, int y, Info info) = 0;
    const ::std::vector<edge_type> &delta(int v) const {
        assert(v < N);
        return edges[v];
    }
    const ::std::vector<edge_type> &operator[](int v) const {
        return this->delta(v);
    }
    ::std::size_t size() const { return N; }
};

template <class Info>
class undirected_graph : public graph<Info> {
   public:
    undirected_graph(::std::size_t N) : graph<Info>(N) {}
    void add_edge(int x, int y, Info info) {
        this->edges[x].push_back(edge<Info>(x, y, info));
        this->edges[y].push_back(edge<Info>(y, x, info));
    }
};

template <class Info>
class directed_graph : public graph<Info> {
   public:
    directed_graph(::std::size_t N) : graph<Info>(N) {}
    void add_edge(int x, int y, Info info) {
        this->edges[x].push_back(edge<Info>(x, y, info));
    }
};

template <class Info>
class bipartite_graph : public undirected_graph<Info> {
    ::std::size_t A;
    ::std::size_t B;

   public:
    bipartite_graph(::std::size_t A_, ::std::size_t B_)
        : A(A_), B(B_), undirected_graph<Info>(A_ + B_) {}
    void add_edge(int x, int y, Info info) {
        undirected_graph<Info>::add_edge(x, y + A, info);
    }
};

template <typename T>
pair<vector<T>, vector<bool>> bellman_ford(graph<T> &g, int s) {
    const auto INF = numeric_limits<T>::max();
    const int N = g.size();
    vector<T> dist(N, INF);
    vector<bool> negative(N, false);
    dist[s] = 0;
    for(int i = 0; i < N - 1; i++) {
        for(int j = 0; j < N; j++) {
            for(auto &e : g[j]) {
                if(dist[e.from] == INF) continue;
                dist[e.to] = min(dist[e.to], dist[e.from] + e.info);
            }
        }
    }
    for(int i = 0; i < N; i++) {
        for(auto &e : g[i]) {
            if(dist[e.from] == INF) continue;
            if(dist[e.from] + e.info < dist[e.to]) negative[e.to] = true;
        }
    }
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            for(auto &e : g[j]) {
                if(negative[e.from]) negative[e.to] = true;
            }
        }
    }
    return make_pair(dist, negative);
}

int main() {
    int N, M;
    cin >> N >> M;
    directed_graph<int_fast64_t> g(N);
    for(int i = 0; i < M; i++) {
        int a, b;
        int_fast64_t c;
        cin >> a >> b >> c;
        --a, --b;
        g.add_edge(a, b, -c);
    }
    auto ans = bellman_ford(g, 0);
    if(ans.second[N - 1])
        cout << "inf" << endl;
    else
        cout << -ans.first[N - 1] << endl;
    return 0;
}

Measured memory_bytes: 384