#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
int n, m, u, v, c;
bool ok = true;
int vis[maxn];
struct Edge {
  int to, nex, col;
} edge[maxn << 1];
int head[maxn], ecnt;
void add_edge(int u, int v, int c) {
  edge[++ecnt] = {v, head[u], c};
  head[u] = ecnt;
}
int fa[maxn];
inline int setfind(int x) { return x == fa[x] ? x : fa[x] = setfind(fa[x]); }
inline void setunion(int x, int y) {
  x = setfind(fa[x]);
  y = setfind(fa[y]);
  fa[x] = y;
}
inline bool setcheck(int x, int y) {
  x = setfind(x);
  y = setfind(y);
  return x == y;
}
void dfs(int now) {
  for (int i = head[now]; i; i = edge[i].nex) {
    int to = edge[i].to, col = edge[i].col;
    if (vis[to] == -1) {
      if (col)
        vis[to] = vis[now];
      else
        vis[to] = vis[now] ^ 1;
      dfs(to);
    }
    if (col && vis[to] != vis[now]) ok = false;
    if (!col && vis[to] == vis[now]) ok = false;
  }
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) fa[i] = i;
  memset(vis, -1, sizeof vis);
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d", &u, &v, &c);
    add_edge(u, v, c);
    add_edge(v, u, c);
  }
  long long ans = (mod + 1) / 2;
  for (int i = 1; i <= n; i++) {
    if (vis[i] != -1) continue;
    vis[i] = 0;
    dfs(i);
    ans = ans * 2 % mod;
  }
  if (!ok) ans = 0;
  printf("%lld\n", ans);
  return 0;
}
