#include <bits/stdc++.h>
using namespace std;
#define MASK(x) (1LL << (x))
#define BIT(x, i) (((x) >> (i)) & 1)
#define ALL(x) (x).begin(), (x).end()
#define REP(i, n) for (int i = 0, _n = n; i < _n; ++i)
#define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define FORD(i, a, b) for (int i = (a), _b = (b); i >= _b; --i)
#define FORE(it, s) for (__typeof(s.begin()) it = (s).begin(); it != (s).end(); ++it)
#define TIME (1.0 * clock() / CLOCKS_PER_SEC)
#define file(TASK) \
if (fopen(TASK ".inp", "r")) { \
freopen(TASK ".inp", "r", stdin); \
freopen(TASK ".out", "w", stdout); \
}
template <class U, class V> bool maximize(U &A, const V &B) { return (A < B) ? (A = B, true) : false; }
template <class U, class V> bool minimize(U &A, const V &B) { return (A > B) ? (A = B, true) : false; }
const int Mod = 1e9 + 7;
const int MAXN = 1e5 + 5;
struct QUERY {
int l, r, value;
}queries[MAXN];
int N, Q, color[MAXN];
vector <int> same_color[MAXN], diff_color[MAXN];
int ans = 1;
void dfs(int u, int tmpColor) {
if(color[u] != -1 && color[u] != tmpColor) {
cout << 0;
exit(0);
}
if(color[u] != -1) return;
color[u] = tmpColor;
for (auto v : same_color[u]) dfs(v, tmpColor);
for (auto v : diff_color[u]) dfs(v, 1 ^ tmpColor);
}
int calc(int biti) {
fill(same_color, same_color + N + 1, vector <int> ());
fill(diff_color, diff_color + N + 1, vector <int> ());
fill(color, color + N + 1, -1);
FOR(i, 1, Q) {
if(BIT(queries[i].value, biti)) {
diff_color[queries[i].l - 1].push_back(queries[i].r);
diff_color[queries[i].r].push_back(queries[i].l - 1);
} else {
same_color[queries[i].l - 1].push_back(queries[i].r);
same_color[queries[i].r].push_back(queries[i].l - 1);
}
}
int ans = 1;
REP(u, N + 1) if(color[u] == -1) {
dfs(u, 0);
if(u > 0) ans += ans;
if(ans >= Mod) ans -= Mod;
}
return ans;
}
void process(void) {
cin >> N >> Q;
FOR(i, 1, Q) cin >> queries[i].l >> queries[i].r >> queries[i].value;
REP(biti, 30) ans = 1LL * ans * calc(biti) % Mod;
cout << ans;
}
signed main() {
file("TASK");
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int test = 1;
// cin >> test;
while(test--) {
process();
cout << '\n';
}
cerr << "Time elapsed: " << TIME << " s.\n";
return (0 ^ 0);
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBNQVNLKHgpICgxTEwgPDwgKHgpKQojZGVmaW5lIEJJVCh4LCBpKSAoKCh4KSA+PiAoaSkpICYgMSkKI2RlZmluZSBBTEwoeCkgKHgpLmJlZ2luKCksICh4KS5lbmQoKQoKI2RlZmluZSBSRVAoaSwgbikgZm9yIChpbnQgaSA9IDAsIF9uID0gbjsgaSA8IF9uOyArK2kpCiNkZWZpbmUgRk9SKGksIGEsIGIpIGZvciAoaW50IGkgPSAoYSksIF9iID0gKGIpOyBpIDw9IF9iOyArK2kpCiNkZWZpbmUgRk9SRChpLCBhLCBiKSBmb3IgKGludCBpID0gKGEpLCBfYiA9IChiKTsgaSA+PSBfYjsgLS1pKQojZGVmaW5lIEZPUkUoaXQsIHMpIGZvciAoX190eXBlb2Yocy5iZWdpbigpKSBpdCA9IChzKS5iZWdpbigpOyBpdCAhPSAocykuZW5kKCk7ICsraXQpCgojZGVmaW5lIFRJTUUgKDEuMCAqIGNsb2NrKCkgLyBDTE9DS1NfUEVSX1NFQykKI2RlZmluZSBmaWxlKFRBU0spICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGlmIChmb3BlbihUQVNLICIuaW5wIiwgInIiKSkgeyAgICAgICAgIFwKICAgICAgICBmcmVvcGVuKFRBU0sgIi5pbnAiLCAiciIsIHN0ZGluKTsgIFwKICAgICAgICBmcmVvcGVuKFRBU0sgIi5vdXQiLCAidyIsIHN0ZG91dCk7IFwKICAgIH0KCnRlbXBsYXRlIDxjbGFzcyBVLCBjbGFzcyBWPiBib29sIG1heGltaXplKFUgJkEsIGNvbnN0IFYgJkIpIHsgcmV0dXJuIChBIDwgQikgPyAoQSA9IEIsIHRydWUpIDogZmFsc2U7IH0KdGVtcGxhdGUgPGNsYXNzIFUsIGNsYXNzIFY+IGJvb2wgbWluaW1pemUoVSAmQSwgY29uc3QgViAmQikgeyByZXR1cm4gKEEgPiBCKSA/IChBID0gQiwgdHJ1ZSkgOiBmYWxzZTsgfQpjb25zdCBpbnQgTW9kID0gMWU5ICsgNzsKY29uc3QgaW50IE1BWE4gPSAxZTUgKyA1OwpzdHJ1Y3QgUVVFUlkgewogICAgaW50IGwsIHIsIHZhbHVlOwp9cXVlcmllc1tNQVhOXTsKaW50IE4sIFEsIGNvbG9yW01BWE5dOwp2ZWN0b3IgPGludD4gc2FtZV9jb2xvcltNQVhOXSwgZGlmZl9jb2xvcltNQVhOXTsKaW50IGFucyA9IDE7CnZvaWQgZGZzKGludCB1LCBpbnQgdG1wQ29sb3IpIHsKICAgIGlmKGNvbG9yW3VdICE9IC0xICYmIGNvbG9yW3VdICE9IHRtcENvbG9yKSB7CiAgICAgICAgY291dCA8PCAwOwogICAgICAgIGV4aXQoMCk7CiAgICB9CiAgICBpZihjb2xvclt1XSAhPSAtMSkgcmV0dXJuOwogICAgY29sb3JbdV0gPSB0bXBDb2xvcjsKICAgIGZvciAoYXV0byB2IDogc2FtZV9jb2xvclt1XSkgZGZzKHYsIHRtcENvbG9yKTsKICAgIGZvciAoYXV0byB2IDogZGlmZl9jb2xvclt1XSkgZGZzKHYsIDEgXiB0bXBDb2xvcik7Cn0KaW50IGNhbGMoaW50IGJpdGkpIHsKICAgIGZpbGwoc2FtZV9jb2xvciwgc2FtZV9jb2xvciArIE4gKyAxLCB2ZWN0b3IgPGludD4gKCkpOwogICAgZmlsbChkaWZmX2NvbG9yLCBkaWZmX2NvbG9yICsgTiArIDEsIHZlY3RvciA8aW50PiAoKSk7CiAgICBmaWxsKGNvbG9yLCBjb2xvciArIE4gKyAxLCAtMSk7CiAgICBGT1IoaSwgMSwgUSkgewogICAgICAgIGlmKEJJVChxdWVyaWVzW2ldLnZhbHVlLCBiaXRpKSkgewogICAgICAgICAgICBkaWZmX2NvbG9yW3F1ZXJpZXNbaV0ubCAtIDFdLnB1c2hfYmFjayhxdWVyaWVzW2ldLnIpOwogICAgICAgICAgICBkaWZmX2NvbG9yW3F1ZXJpZXNbaV0ucl0ucHVzaF9iYWNrKHF1ZXJpZXNbaV0ubCAtIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNhbWVfY29sb3JbcXVlcmllc1tpXS5sIC0gMV0ucHVzaF9iYWNrKHF1ZXJpZXNbaV0ucik7CiAgICAgICAgICAgIHNhbWVfY29sb3JbcXVlcmllc1tpXS5yXS5wdXNoX2JhY2socXVlcmllc1tpXS5sIC0gMSk7CiAgICAgICAgfQogICAgfQogICAgaW50IGFucyA9IDE7CiAgICBSRVAodSwgTiArIDEpIGlmKGNvbG9yW3VdID09IC0xKSB7CiAgICAgICAgZGZzKHUsIDApOwogICAgICAgIGlmKHUgPiAwKSBhbnMgKz0gYW5zOwogICAgICAgIGlmKGFucyA+PSBNb2QpIGFucyAtPSBNb2Q7CiAgICB9CiAgICByZXR1cm4gYW5zOwp9CnZvaWQgcHJvY2Vzcyh2b2lkKSB7CiAgICBjaW4gPj4gTiA+PiBROwogICAgRk9SKGksIDEsIFEpIGNpbiA+PiBxdWVyaWVzW2ldLmwgPj4gcXVlcmllc1tpXS5yID4+IHF1ZXJpZXNbaV0udmFsdWU7CiAgICBSRVAoYml0aSwgMzApIGFucyA9IDFMTCAqIGFucyAqIGNhbGMoYml0aSkgJSBNb2Q7CiAgICBjb3V0IDw8IGFuczsKfQpzaWduZWQgbWFpbigpIHsKICAgIGZpbGUoIlRBU0siKTsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7IGNpbi50aWUoMCk7IGNvdXQudGllKDApOwogICAgaW50IHRlc3QgPSAxOwogICAgLy8gY2luID4+IHRlc3Q7CiAgICB3aGlsZSh0ZXN0LS0pIHsKICAgICAgICBwcm9jZXNzKCk7CiAgICAgICAgY291dCA8PCAnXG4nOwogICAgfQogICAgY2VyciA8PCAiVGltZSBlbGFwc2VkOiAiIDw8IFRJTUUgPDwgIiBzLlxuIjsKICAgIHJldHVybiAoMCBeIDApOwp9