import std.stdio, std.string, std.array, std.conv, std.algorithm, std.typecons, std.range, std.container, std.math, std.algorithm.searching, std.functional,std.mathspecial, std.numeric;

long[] scores;
int[][] abcs;

void main(){
    auto nm=readln.split.map!(to!int).array;
    auto N=nm[0];
    auto M=nm[1];
    foreach(i;0..M){
        auto abc=readln.split.map!(to!int).array;
        abc[0]-=1;
        abc[1]-=1;
        abcs~=abc;
    }

    scores.length=N;
    foreach(ref s;scores[1..$])s=long.min;

    try{
    foreach(i,abc;abcs){
        onEdge(abc, i, (int[]).init);
    }
    writeln(scores[N-1]);
    }catch{
        writeln("inf");
    }
}

void onEdge(int[] abc, int current, int[] used){
    if(scores[abc[0]]==long.min)return;
    update(abc[1], scores[abc[0]]+abc[2], current, used);
}

void update(int target, long score, int current, int[] used){
    if(scores[target]>=score)return;
    if(used.any!(n=>n==current))throw new Exception("po");
    scores[target]=score;
    auto nextUsed=used~current;
    foreach_reverse(i,abc;abcs[0..current]){
        if(abc[0]==target)onEdge(abc, current, nextUsed);
    }
}

