#include using namespace std; #define REP(i,a,n) for(int i=(a); i<(int)(n); i++) #define rep(i,n) REP(i,0,n) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it) #define ALLOF(c) (c).begin(), (c).end() typedef long long ll; typedef unsigned long long ull; class SCC { int V; std::vector> G, rG; std::vector vs; std::vector used; std::vector cmp; void dfs(int v){ used[v] = true; for(int i=0; i get_edge(int from){ return G[from]; } void add_edge(int from, int to){ G[from].push_back(to); rG[to].push_back(from); } // 強連結成分(2点が相互に行き来できるグループ)数 int scc(){ for(int i=0; i=0; i--) if(!used[vs[i]]) rdfs(vs[i], k++); return k; } // サイクルがあるか bool iscyclic(){ return scc() != V; } // 強連結成分番号 std::vector get_cmp(){ return cmp; } // 同じ辺を2度通らない、その頂点までの最長経路 std::vector depth(){ scc(); std::vector> order; std::vector dp(V, 1); for(int i=0; i> G[100005]; vector rG[100005]; bool cango1[100005]; bool cango2[100005]; ll dp1[100005]; ll dp2[100005]; int main(){ int N, M; cin >> N >> M; SCC scc(N+1); rep(i,M){ ll a, b, c, d; cin >> a >> b >> c >> d; scc.add_edge(a,b); G[a].push_back({b, c % MOD, d % MOD}); rG[b].push_back(a); } queue que; que.push(N); while(!que.empty()){ int pos = que.front(); que.pop(); if(cango1[pos]) continue; cango1[pos] = true; rep(i,rG[pos].size()){ que.push(rG[pos][i]); } } que.push(0); while(!que.empty()){ int pos = que.front(); que.pop(); if(cango2[pos]) continue; cango2[pos] = true; rep(i,G[pos].size()){ que.push(G[pos][i][0]); } } scc.scc(); vector cmp = scc.get_cmp(); vector> order; for(int i=0; i visited(N+1,false); visited[0] = true; dp2[0] = 1; rep(ii,order.size()){ int pos = order[ii].second; if(!cango1[pos] || !cango2[pos]) continue; visited[pos] = true; if(pos == N) break; rep(i,G[pos].size()){ ll to = G[pos][i][0]; ll l = G[pos][i][1]; ll a = G[pos][i][2]; if(visited[to]){ cout << "INF" << endl; return 0; } dp1[to] += ((dp1[pos] * a)%MOD + (((a * dp2[pos]) % MOD) * l) % MOD) % MOD; dp1[to] %= MOD; dp2[to] += (dp2[pos] * a) % MOD; dp2[to] %= MOD; } } cout << dp1[N] << endl; return 0; }