#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, w, rev;
};
vector<vector<edge> > G, oG;
void add_edge(int x, int y, int w, int way) {
  if (way == 1) {
    G[x].push_back({y, w, -1});
  } else {
    int X = G[x].size(), Y = G[y].size();
    G[x].push_back({y, w, Y});
    G[y].push_back({x, w, X});
  }
}
map<pair<int, int>, int> memo;
set<pair<int, int> > vis;
int dfs(int v, int eid) {
  if (memo.count(pair<int, int>(v, eid))) return memo[pair<int, int>(v, eid)];
  if (vis.count(pair<int, int>(v, eid))) {
    puts("Infinite");
    exit(1);
  }
  vis.insert(pair<int, int>(v, eid));
  int ret = 0;
  for (int i = 0; i < (int)G[v].size(); i++)
    if (i != eid) {
      edge& e = G[v][i];
      ret = max(ret, dfs(e.to, e.rev) + e.w);
    }
  memo[pair<int, int>(v, eid)] = ret;
  return ret;
}
int rs[100001] = {};
int its[100000] = {};
int main() {
  return 0;
  int N, M;
  cin >> N >> M;
  oG.resize(N);
  for (int i = 0; i < (int)M; i++) {
    int x, y, w;
    scanf("%d %d %d", &x, &y, &w);
    x--, y--;
    if (w == 1) {
      oG[x].push_back(edge{y, 1, -1});
    } else {
      int X = oG[x].size(), Y = oG[y].size();
      oG[x].push_back(edge{y, 1, Y});
      oG[y].push_back(edge{x, 1, X});
    }
  }
  int newN = 0;
  for (int i = 0; i < (int)N; i++) {
    int sz = oG[i].size();
    if (sz == 0) sz = 1;
    rs[i] = newN;
    its[i] = rs[i];
    newN += sz;
  }
  rs[N] = newN;
  G.resize(newN);
  for (int x = 0; x < (int)N; x++) {
    int n = rs[x + 1] - rs[x];
    for (int v = rs[x]; v < rs[x] + n - 1; v++) add_edge(v, v + 1, 0, 2);
    for (edge e : oG[x]) {
      if (e.rev == -1) {
        add_edge(its[x], rs[e.to], 1, 1);
        its[x]++;
      } else {
        if (x < e.to) {
          add_edge(its[x], its[e.to], 1, 2);
          its[x]++;
          its[e.to]++;
        }
      }
    }
  }
  int ans = 0;
  N = newN;
  for (int i = 0; i < (int)N; i++) ans = max(ans, dfs(i, -1));
  cout << ans << endl;
}
