Problem: Today is the open campus of Z University. Every year during the lunch break on this day, many high school students line up for the school cafeteria. Therefore, the secretariat of Z University decided to predict the maximum distance of the procession. As a result of the preliminary survey, we know the following.

* The matrix is ​​lined with N people, each numbered from 1 to N.
* For each pair of C high school students (ai, bi), there are two types of restrictions:
* The first constraint is on the order and is one of the following:
ai must be ahead of bi or in the same position
ai must line up after or in the same position as bi
ai can be before, in the same position, or after bi

* The second constraint is on distance and is one of the following:
ai and bi must be at least di meters apart
ai and bi must line up within di meters




We also know that multiple people can be lined up at the same distance from the beginning, and that the number 1 person is always at the beginning of the procession.

Create a program to find the distance when the matrix that satisfies all the given C constraints is arranged so that the distance from the beginning to the end is the maximum. However, output inf if it can be separated indefinitely, and -1 if it is not possible to arrange in a way that satisfies the constraint.



input

The input is given in the following format.


N C
constraint1
constraint2
::
constraintC


The number of high school students in the queue on the first line N (2 ≤ N ≤ 100) and the number of constraints C (0 ≤ C ≤ 200) are given. Each constraint constrainti is given in the following C line in the following format.


aioibisidi


The constraint does not include spaces. The meanings of ai, oi, bi, si and di are shown below.

* ai and bi (1 ≤ ai, bi ≤ N and ai ≠ bi) are high school student numbers, and di is an integer representing the distance (0 ≤ d ≤ 10000).
* oi is a string of <=,> =, * that specifies the order constraint, and if <=, "ai must precede bi or be in the same position",> = In the case of, "ai must be after bi or in the same position", and in the case of *, it means that "ai can be before, in the same position, or after bi". However, no more than 7 constraints with oi as * can be given.
* si is the + or-character that specifies the distance constraint, for + "ai and bi must be at least di meters apart", for-"ai and bi must be within di meters" It means that.



However, it is assumed that multiple constraints are not given to a pair.

output

The distance from the beginning to the end is output on one line.

Example

Input

3 2
1


Output

3

Solution (in CPP):

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

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
//template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<58;
const double eps=1e-9;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
	os << "[";
	for (const auto &v : vec) {
		os << v << ",";
	}
	os << "]";
	return os;
}

string split(const string &str, const string &delim){
    string res;
    size_t current = 0, found, delimlen = delim.size();
    while((found = str.find(delim, current)) != string::npos){
        res+=string(str, current, found - current) + " " + delim + " ";
        current = found + delimlen;
    }
    res+=string(str, current, str.size() - current);
    return res;
}

int n,c;
typedef tuple<int,int,int> edge;
vector<edge> es;
vector<int> dist;

void bellmanford(){
    fill_n(dist.begin(),n,inf);
    dist[0]=0;

    for(int i=0; i<2*n; ++i){
        for(edge& e:es){
            int a=get<0>(e),b=get<1>(e),w=get<2>(e);
            if(dist[a]+w<dist[b]) dist[b]=dist[a]+w;
        }
    }
}

void add_edge(string& constraint){
    constraint=split(constraint,">=");
    constraint=split(constraint,"<=");
    constraint=split(constraint,"+");
    constraint=split(constraint,"-");

    int a,b,d;
    string tmp1,tmp2;
    stringstream ss(constraint);
    ss >> a >> tmp1 >> b >> tmp2 >> d;
    --a; --b;

    if(tmp1=="<=") es.push_back(make_tuple(b,a,0));
    else if(tmp1==">=") es.push_back(make_tuple(a,b,0));

    int w=-d;
    if(tmp2=="-"){
        w*=-1;
        swap(a,b);
    }
    if(tmp1=="<=") es.push_back(make_tuple(b,a,w));
    else if(tmp1==">=") es.push_back(make_tuple(a,b,w));
}

void solve(){
    cin >> n >> c;

    dist.resize(n);
    vector<string> unfixed;

    rep(i,0,c){
        string constraint;
        cin >> constraint;
        if(constraint.find("*")==string::npos) add_edge(constraint);
        else unfixed.push_back(constraint);
    }
    rep(v,1,n) es.push_back(make_tuple(v,0,0));

    vector<edge> es_=es;
    int ans=-1;
    rep(b,0,1<<unfixed.size()){
        es=es_;
        rep(i,0,unfixed.size()){
            string constraint=unfixed[i];
            if(1&(b>>i)) constraint.replace(constraint.find("*"),1,"<=");
            else constraint.replace(constraint.find("*"),1,">=");
            add_edge(constraint);
        }

        bellmanford();
        if(dist[0]<0) continue;
        rep(i,0,n) ans=max(ans,dist[i]);
    }
    if(ans==inf) cout << "inf" << endl;
    else cout << ans << endl;
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	solve();
	return 0;
}