#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void chkmax(T& x, T y) {
  if (x < y) x = y;
}
template <class T>
inline void chkmin(T& x, T y) {
  if (y < x) x = y;
}
const int MX = 100005;
const int MOD = 1000000007;
struct Edge {
  int u, v, c;
  void in() { scanf("%d%d%d", &u, &v, &c); }
} e[MX];
int chk[MX], CN;
int vis[MX];
vector<int> con[MX], rcon[MX];
void DFS(int u) {
  chk[u] = CN;
  for (int i = (int((con[u]).size())) - 1; i >= 0; i--) {
    int v = con[u][i];
    if (!chk[v]) DFS(v);
  }
}
int q[MX];
int main() {
  int n, m;
  int i, j, u, v, c;
  scanf("%d%d", &n, &m);
  for (i = 0; i < m; i++) {
    e[i].in();
    if (e[i].c == 1) {
      con[e[i].u].push_back(e[i].v);
      con[e[i].v].push_back(e[i].u);
    }
  }
  for (i = 1; i <= n; i++)
    if (!chk[i]) {
      CN++;
      DFS(i);
    }
  for (i = 0; i < m; i++) {
    u = e[i].u, v = e[i].v;
    if (chk[u] == chk[v] && e[i].c == 0) break;
    if (e[i].c == 1) continue;
    rcon[chk[u]].push_back(chk[v]);
    rcon[chk[v]].push_back(chk[u]);
  }
  if (i < m) {
    puts("0");
    return 0;
  }
  for (i = 1; i <= CN; i++) {
    sort(rcon[i].begin(), rcon[i].end());
    rcon[i].erase(unique(rcon[i].begin(), rcon[i].end()), rcon[i].end());
  }
  int cnt = 0;
  for (i = 1; i <= CN; i++)
    if (!vis[i]) {
      cnt++;
      int hd = 0, tl = 0;
      q[tl++] = i;
      vis[i] = 1;
      int flg = 0;
      while (hd < tl) {
        u = q[hd++];
        for (j = (int((rcon[u]).size())) - 1; j >= 0; j--) {
          v = rcon[u][j];
          if (!vis[v])
            vis[v] = 3 - vis[u], q[tl++] = v;
          else if (vis[v] == vis[u])
            break;
        }
        if (j >= 0) {
          flg = 1;
          break;
        }
      }
      if (flg == 1) break;
    }
  if (i <= CN)
    puts("0");
  else {
    long long ans = 1;
    for (i = 1; i < cnt; i++) ans = ans * 2 % MOD;
    cout << ans << endl;
  }
  return 0;
}
