package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
var scanner *bufio.Scanner
func init() {
scanner = bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
scanner.Buffer(make([]byte, 1024*1024), 1024*1024*10)
}
func nextInt() int {
scanner.Scan()
ans, _ := strconv.Atoi(scanner.Text())
return ans
}
func nextInt64() int64 {
scanner.Scan()
ans, _ := strconv.ParseInt(scanner.Text(), 10, 64)
return ans
}
type Edge struct {
to int
w int64
}
func main() {
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
m := nextInt()
adj := make([][]Edge, n+1)
for i := 0; i < m; i++ {
u := nextInt()
v := nextInt()
w := nextInt64()
adj[u] = append(adj[u], Edge{v, w})
adj[v] = append(adj[v], Edge{u, w})
}
visited := make([]bool, n+1)
d := make([]int64, n+1)
ans := int64(0)
mod := int64(1000000007)
pow2 := make([]int64, 130)
pow2[0] = 1
for i := 1; i < 130; i++ {
pow2[i] = (pow2[i-1] * 2) % mod
}
for i := 1; i <= n; i++ {
if !visited[i] {
basis := make([]int64, 61)
k := 0
var comp []int
queue := []int{i}
visited[i] = true
for head := 0; head < len(queue); head++ {
u := queue[head]
comp = append(comp, u)
for _, e := range adj[u] {
v, w := e.to, e.w
if !visited[v] {
visited[v] = true
d[v] = d[u] ^ w
queue = append(queue, v)
} else {
cycle := d[u] ^ d[v] ^ w
for bit := 60; bit >= 0; bit-- {
if (cycle>>bit)&1 == 1 {
if basis[bit] == 0 {
basis[bit] = cycle
k++
break
}
cycle ^= basis[bit]
}
}
}
}
}
basisOR := int64(0)
for bit := 0; bit <= 60; bit++ {
basisOR |= basis[bit]
}
vc := int64(len(comp))
pairsTotal := (vc * (vc - 1) / 2) % mod
for bit := 0; bit <= 60; bit++ {
if (basisOR>>bit)&1 == 1 {
term := (pairsTotal * pow2[k-1]) % mod
term = (term * pow2[bit]) % mod
ans = (ans + term) % mod
} else {
c1 := int64(0)
for _, u := range comp {
if (d[u]>>bit)&1 == 1 {
c1++
}
}
c0 := vc - c1
pairs := (c0 * c1) % mod
term := (pairs * pow2[k]) % mod
term = (term * pow2[bit]) % mod
ans = (ans + term) % mod
}
}
}
}
fmt.Println(ans)
}