#include <bits/stdc++.h>
using namespace std;
template <typename T>
void read_to_vector(size_t N, std::vector<T> &v) {
  for (size_t i = 0; i < N; i++) {
    T tmp;
    std::cin >> tmp;
    v.push_back(tmp);
  }
}
template <typename T>
void print_vector(const std::vector<T> &v) {
  for (auto it = v.begin(); it < v.end(); it++) {
    if (it != v.begin()) std::cout << " ";
    std::cout << (*it);
  }
}
struct Edge {
  int to;
  long long w;
  Edge(int to, long long w) {
    this->to = to;
    this->w = w;
  }
  Edge(int to) : Edge(to, 1){};
  bool operator<(const Edge &e) const {
    return (w < e.w) || ((w == e.w) && (to < e.to));
  }
  bool operator>(const Edge &e) const {
    return (w > e.w) || ((w == e.w) && (to > e.to));
  }
};
struct Vertex {
  std::vector<Edge> el;
};
struct Graph {
  std::vector<Vertex> v;
  Graph(int N) {
    for (int i = 0; i < N; i++) v.push_back(Vertex());
  }
  void addEdge(int a, int b) { v[a].el.push_back(Edge(b)); }
  void addEdge(int a, int b, long long w) { v[a].el.push_back(Edge(b, w)); }
  void bfs(int st, vector<int> &compo, int compo_i) {
    int r = v.size();
    std::queue<int> Q;
    Q.push(st);
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      compo[u] = compo_i;
      for (Edge e : v[u].el) {
        if (compo[e.to] == -1) {
          Q.push(e.to);
        }
      }
    }
  }
  bool bipbfs(int st, vector<int> &part) {
    int r = v.size();
    std::queue<int> Q;
    Q.push(st);
    part[st] = 0;
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      for (Edge e : v[u].el) {
        if (part[e.to] == -1) {
          part[e.to] = 1 - part[u];
          Q.push(e.to);
        } else if (part[e.to] == part[u]) {
          return false;
        }
      }
    }
    return true;
  }
};
void solve() {
  int n, m;
  cin >> n >> m;
  vector<pair<int, int> > love;
  vector<pair<int, int> > hate;
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    if (c == 1)
      love.push_back(pair<int, int>(min(a, b), max(a, b)));
    else
      hate.push_back(pair<int, int>(min(a, b), max(a, b)));
  }
  Graph glove(n);
  for (auto p : love) {
    glove.addEdge(p.first, p.second);
    glove.addEdge(p.second, p.first);
  }
  vector<int> compo(n, -1);
  int n_compo = 0;
  for (int i = 0; i < n; i++) {
    if (compo[i] == -1) {
      glove.bfs(i, compo, n_compo);
      n_compo++;
    }
  }
  Graph ghate(n_compo);
  for (auto p : hate) {
    if (compo[p.first] == compo[p.second]) {
      cout << "0\n";
      return;
    }
    ghate.addEdge(compo[p.first], compo[p.second]);
    ghate.addEdge(compo[p.second], compo[p.first]);
  }
  long long choices = -1;
  vector<int> part(n_compo, -1);
  for (int i = 0; i < n_compo; i++) {
    if (part[i] == -1) {
      if (!ghate.bipbfs(i, part)) {
        cout << "0\n";
        return;
      }
      choices += 1;
    }
  }
  long long res = 1;
  for (long long i = 0; i < choices; i++) {
    res *= 2;
    res %= 1000000007;
  }
  cout << res << "\n";
}
void pre_compute() {}
int main() {
  std::cout << std::setprecision(15);
  std::ios::sync_with_stdio(false);
  pre_compute();
  solve();
  return 0;
}
