#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7, MAXN = 1e5 + 7;
bool poss = true;
int n, m, pai[MAXN], mrk[MAXN], comp = 0, pot[MAXN];
vector<pair<int, int> > arestas;
vector<int> G[MAXN];
int raiz(int u) { return (u == pai[u]) ? u : pai[u] = raiz(pai[u]); }
void unite(int u, int v) { pai[u] = v; }
void dfs(int u) {
  for (int i = 0; i < (int)G[u].size(); i++) {
    int viz = G[u][i];
    if (mrk[viz] == 0) {
      mrk[viz] = (mrk[u] == 1) ? 2 : 1;
      dfs(viz);
    } else {
      if (mrk[viz] == mrk[u]) poss = false;
    }
  }
}
int main() {
  pot[0] = 1;
  for (int i = 1; i < MAXN; i++) pot[i] = (2 * pot[i - 1]) % MOD;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) pai[i] = i;
  for (int i = 0; i < m; i++) {
    int ui, vi, wi;
    cin >> ui >> vi >> wi;
    if (wi == 0) {
      arestas.push_back({ui, vi});
    } else {
      ui = raiz(ui);
      vi = raiz(vi);
      if (ui != vi) unite(ui, vi);
    }
  }
  for (int i = 0; i < (int)arestas.size(); i++) {
    int ui = arestas[i].first;
    int vi = arestas[i].second;
    ui = raiz(ui);
    vi = raiz(vi);
    if (ui == vi) {
      cout << "0" << endl;
      return 0;
    }
    G[ui].push_back(vi);
    G[vi].push_back(ui);
  }
  for (int i = 1; i <= n; i++) {
    if (raiz(i) != i || mrk[i] != 0) continue;
    mrk[i] = 1;
    dfs(i);
    if (!poss) {
      cout << "0" << endl;
      return 0;
    }
    comp++;
  }
  cout << pot[comp - 1] << endl;
}
