#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> group[100005];
vector<int> G[100005];
int x[100005], y[100005], w[100005];
int id[100005];
bool visited[100005];
int c[100005];
vector<int> g[100005];
vector<int> vd;
int dp[100005];
bool dfs(int pos, int prev, int root) {
  id[pos] = root;
  visited[pos] = true;
  group[root].push_back(pos);
  for (int to : G[pos]) {
    if (to == prev) continue;
    if (visited[to]) return true;
    if (dfs(to, pos, root)) return true;
  }
  return false;
}
bool check() {
  map<pair<int, int>, bool> mp;
  for (int i = 0; i < m; i++) {
    if (w[i] == 1) continue;
    if (x[i] > y[i]) swap(x[i], y[i]);
    if (mp[pair<int, int>(x[i], y[i])]) return true;
    mp[pair<int, int>(x[i], y[i])] = true;
  }
  memset(visited, false, sizeof(visited));
  for (int i = 0; i < n; i++) {
    if (visited[i]) continue;
    if (dfs(i, -1, i)) return true;
  }
  for (int i = 0; i < m; i++) {
    if (w[i] == 2) continue;
    int X = id[x[i]];
    int Y = id[y[i]];
    if (X == Y) {
      return true;
    }
    g[X].push_back(Y);
    c[Y]++;
  }
  queue<int> Q;
  for (int i = 0; i < n; i++) {
    if (c[i] == 0 && id[i] == i) {
      Q.push(i);
    }
  }
  while (!Q.empty()) {
    int pos = Q.front();
    Q.pop();
    vd.push_back(pos);
    for (int to : g[pos]) {
      c[to]--;
      if (c[to] == 0) Q.push(to);
    }
  }
  for (int i = 0; i < n; i++)
    if (c[i] > 0) return true;
  return false;
}
int d[100005];
void init(int root) {
  root = id[root];
  for (int pos : group[root]) {
    d[pos] = -1;
  }
}
void bfs(int root) {
  init(root);
  queue<int> Q;
  Q.push(root);
  d[root] = 0;
  while (!Q.empty()) {
    int pos = Q.front();
    Q.pop();
    for (int to : G[pos]) {
      if (d[to] != -1) continue;
      d[to] = d[pos] + 1;
      Q.push(to);
    }
  }
}
void update(int root, int dif) {
  for (int pos : group[root]) {
    for (int to : g[pos]) {
      dp[to] = max(dp[to], d[pos] + dif + 1);
    }
  }
}
int solve(int root) {
  int res = 0;
  bfs(root);
  int maxm = -1, maxmid;
  for (int pos : group[root])
    if (d[pos] + dp[pos] > maxm) maxm = d[pos] + dp[pos], maxmid = pos;
  bfs(maxmid);
  update(root, dp[maxmid]);
  maxm = -1;
  for (int pos : group[root]) {
    if (d[pos] + dp[pos] > maxm) maxm = d[pos] + dp[pos], maxmid = pos;
    res = max(res, d[pos]);
  }
  bfs(maxmid);
  update(root, dp[maxmid]);
  return res;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &x[i], &y[i], &w[i]);
    x[i]--, y[i]--;
    if (w[i] == 2) {
      G[x[i]].push_back(y[i]);
      G[y[i]].push_back(x[i]);
    }
  }
  if (check()) {
    printf("Infinite\n");
    return 0;
  }
  for (int i = 0; i < n; i++) {
    g[i].clear();
  }
  for (int i = 0; i < m; i++) {
    if (w[i] == 1) {
      g[x[i]].push_back(y[i]);
    }
  }
  int ans = 0;
  for (int root : vd) {
    if (root != id[root]) continue;
    ans = max(ans, solve(root));
  }
  for (int i = 0; i < n; i++) {
    ans = max(ans, dp[i]);
  }
  printf("%d\n", ans);
  return 0;
}
