#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1001 * 1001, MOD = 1e9 + 7;
int t2(int x) {
  if (x == 0) return 1;
  long long ans = t2(x / 2);
  ans *= ans;
  ans %= MOD;
  return (ans * (x % 2 == 0 ? 1 : 2)) % MOD;
}
vector<int> adj[MAXN];
vector<pair<int, int> > ed;
int par[MAXN] = {}, sz[MAXN] = {}, t = 0, mark[MAXN] = {};
int root(int u) { return (par[u] == u ? u : par[u] = root(par[u])); }
inline void merge(int x, int y) {
  x = root(x), y = root(y);
  if (x == y) return;
  t--;
  if (sz[x] > sz[y]) swap(x, y);
  par[x] = y;
  sz[y] += x;
}
void dfs(int u) {
  for (auto v : adj[u]) {
    if (mark[v]) {
      if (mark[v] == mark[u]) {
        cout << 0;
        exit(0);
      }
      continue;
    }
    mark[v] = 3 - mark[u];
    dfs(v);
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  t = n;
  for (int i = 1; i <= n; i++) par[i] = i, sz[i] = 1;
  int x, y, z;
  for (int i = 0; i < m; i++) {
    cin >> x >> y >> z;
    if (z)
      merge(x, y);
    else
      ed.push_back({x, y});
  }
  if (ed.size() == 0) return cout << t2(t - 1), 0;
  for (auto u : ed) {
    x = root(u.first), y = root(u.second);
    if (x == y) return cout << 0, 0;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  x = 0;
  for (int i = 1; i <= n; i++) {
    if (!mark[i] && par[i] == i) {
      mark[i] = 1;
      dfs(i);
      x++;
    }
  }
  cout << t2(x - 1);
}
