#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1000000000")
using namespace std;
const int maxn = (int)1e5 + 10;
int p[maxn];
int xorrrr[maxn];
int d[maxn];
vector<int> ed[maxn];
int get_parent(int v) {
  if (v == p[v]) {
    return v;
  }
  int par = get_parent(p[v]);
  d[v] += d[p[v]];
  d[v] %= 2;
  xorrrr[v] ^= xorrrr[p[v]];
  p[v] = par;
  return par;
}
bool used[maxn];
const int q = (int)1e9 + 7;
void dfs(int v) {
  used[v] = true;
  for (int i = 0; i < (int)ed[v].size(); i++) {
    int u = ed[v][i];
    if (!used[u]) {
      dfs(u);
    }
  }
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    p[i] = i;
    xorrrr[i] = 0;
    d[i] = 0;
  }
  for (int i = 0; i < m; i++) {
    int x, y, tp;
    scanf("%d %d %d", &x, &y, &tp);
    ed[x].push_back(y);
    ed[y].push_back(x);
    int p_x = get_parent(x);
    int p_y = get_parent(y);
    if (p_x == p_y) {
      if ((d[x] + d[y]) % 2 == 0) {
        if ((xorrrr[x] ^ xorrrr[y] ^ tp) == 0) {
          printf("0");
          return 0;
        }
      } else {
        if ((xorrrr[x] ^ xorrrr[y] ^ tp) == 1) {
          printf("0");
          return 0;
        }
      }
    } else {
      p[p_x] = p_y;
      d[p_x] = (d[x] + d[y] + 1) % 2;
      xorrrr[p_x] = xorrrr[x] ^ xorrrr[y] ^ tp;
    }
  }
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (!used[i]) {
      cnt++;
      dfs(i);
    }
  }
  int ans = 1;
  for (int i = 1; i < cnt; i++) {
    ans *= 2;
    ans %= q;
  }
  cout << ans << endl;
  return 0;
}
