#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50;
int n, m, c[maxn], dfn[maxn], Fa[maxn], HasCircle, dfs_clock, low[maxn],
    scc_idx[maxn], scc_tot;
vector<int> G[maxn], RG[maxn], NormalEdge[maxn], Edge[maxn], BaseEdge[maxn];
stack<int> stk;
vector<pair<int, int> > fk;
int Find_Fa(int u) { return Fa[u] != u ? Fa[u] = Find_Fa(Fa[u]) : u; }
void DFS_Circle(int u) {
  low[u] = dfn[u] = ++dfs_clock;
  stk.push(u);
  for (auto v : Edge[u]) {
    if (!dfn[v]) {
      DFS_Circle(v);
      low[u] = min(low[u], low[v]);
    } else if (!scc_idx[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    int x, cnt = 0;
    ++scc_tot;
    while (1) {
      ++cnt;
      x = stk.top();
      stk.pop();
      scc_idx[x] = scc_tot;
      if (x == u) break;
    }
    HasCircle |= (cnt > 1);
  }
}
int f[maxn], g[maxn], dp1[maxn], dp2[maxn], vis[maxn], deep[maxn], ans;
int DFS1(int u) {
  if (~f[u]) return f[u];
  f[u] = 0;
  for (auto v : G[u]) f[u] = max(f[u], DFS1(v) + 1);
  return f[u];
}
int DFS2(int u) {
  if (~g[u]) return g[u];
  g[u] = 0;
  for (auto v : RG[u]) g[u] = max(g[u], DFS2(v) + 1);
  return g[u];
}
void DFS(int u, int fa) {
  vis[u] = 1;
  dp1[u] = f[u] + deep[u], dp2[u] = g[u] + deep[u];
  for (auto v : NormalEdge[u]) {
    if (v == fa) continue;
    deep[v] = deep[u] + 1;
    DFS(v, u);
    ans = max(ans, dp1[u] + dp2[v] - 2 * deep[u]);
    ans = max(ans, dp1[v] + dp2[u] - 2 * deep[u]);
    dp1[u] = max(dp1[u], dp1[v]);
    dp2[u] = max(dp2[u], dp2[v]);
  }
}
map<pair<int, int>, int> memory;
int Gao(int u, int pre) {
  if (memory.count(make_pair(u, pre))) return memory[make_pair(u, pre)];
  int& ans = memory[make_pair(u, pre)] = 0;
  for (auto v : BaseEdge[u]) {
    if (v == pre) continue;
    ans = max(ans, Gao(v, u) + 1);
  }
  return ans;
}
int main(int argc, char* argv[]) {
  memset(f, -1, sizeof(f));
  memset(g, -1, sizeof(g));
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) Fa[i] = i;
  for (int i = 1; i <= m; ++i) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    BaseEdge[u].emplace_back(v);
    if (w == 2) {
      BaseEdge[v].emplace_back(u);
      int p1 = Find_Fa(u), p2 = Find_Fa(v);
      if (p1 == p2) {
        puts("Infinite");
        return 0;
      }
      Fa[p1] = p2;
      NormalEdge[u].emplace_back(v);
      NormalEdge[v].emplace_back(u);
    } else {
      fk.emplace_back(make_pair(u, v));
      G[u].emplace_back(v);
      RG[v].emplace_back(u);
    }
  }
  for (auto it : fk) {
    if (Find_Fa(it.first) == Find_Fa(it.second)) {
      puts("Infinite");
      return 0;
    }
    Edge[Find_Fa(it.first)].emplace_back(Find_Fa(it.second));
  }
  for (int i = 1; i <= n; ++i)
    if (!dfn[i]) DFS_Circle(i);
  if (HasCircle) {
    puts("Infinite");
    return 0;
  }
  for (int i = 1; i <= n; ++i) ans = max(ans, Gao(i, 0));
  printf("%d\n", ans);
  return 0;
}
