← Home
```go
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

const MOD int64 = 1000000007

func insertBasis(b *[5]uint8, x uint8) bool {
	for i := 4; i >= 0; i-- {
		if x&(uint8(1)<<uint(i)) == 0 {
			continue
		}
		if b[i] == 0 {
			b[i] = x
			return true
		}
		x ^= b[i]
	}
	return false
}

func spanAddBitset(u uint32, x int) uint32 {
	if x == 0 || (u&(uint32(1)<<uint(x))) != 0 {
		return u
	}
	w := u
	for v := 0; v < 32; v++ {
		if (u & (uint32(1) << uint(v))) != 0 {
			w |= uint32(1) << uint(v^x)
		}
	}
	return w
}

func basisToBitset(b [5]uint8) uint32 {
	u := uint32(1)
	for i := 0; i < 5; i++ {
		if b[i] != 0 {
			u = spanAddBitset(u, int(b[i]))
		}
	}
	return u
}

func generateStates() ([]uint32, map[uint32]int) {
	states := []uint32{1}
	id := map[uint32]int{1: 0}
	for i := 0; i < len(states); i++ {
		u := states[i]
		for x := 1; x < 32; x++ {
			if (u & (uint32(1) << uint(x))) != 0 {
				continue
			}
			w := spanAddBitset(u, x)
			if _, ok := id[w]; !ok {
				id[w] = len(states)
				states = append(states, w)
			}
		}
	}
	return states, id
}

func addOption(ids *[3]int, ways *[3]int64, cnt *int, id int, w int64) {
	if w == 0 {
		return
	}
	for i := 0; i < *cnt; i++ {
		if ids[i] == id {
			ways[i] += w
			return
		}
	}
	ids[*cnt] = id
	ways[*cnt] = w
	*cnt++
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	pos := 0
	readInt := func() int {
		for pos < len(data) && (data[pos] < '0' || data[pos] > '9') {
			pos++
		}
		v := 0
		for pos < len(data) && data[pos] >= '0' && data[pos] <= '9' {
			v = v*10 + int(data[pos]-'0')
			pos++
		}
		return v
	}

	n := readInt()
	m := readInt()

	head := make([]int, n+1)
	for i := range head {
		head[i] = -1
	}

	to := make([]int, 0, 2*m)
	nxt := make([]int, 0, 2*m)
	wt := make([]uint8, 0, 2*m)

	addEdge := func(u, v int, w uint8) {
		to = append(to, v)
		wt = append(wt, w)
		nxt = append(nxt, head[u])
		head[u] = len(to) - 1
	}

	has1 := make([]bool, n+1)
	w1 := make([]uint8, n+1)

	eu := make([]int, 0, m)
	ev := make([]int, 0, m)
	ew := make([]uint8, 0, m)

	for i := 0; i < m; i++ {
		a := readInt()
		b := readInt()
		w := uint8(readInt())
		if a == 1 || b == 1 {
			x := a
			if x == 1 {
				x = b
			}
			has1[x] = true
			w1[x] = w
		} else {
			eu = append(eu, a)
			ev = append(ev, b)
			ew = append(ew, w)
			addEdge(a, b, w)
			addEdge(b, a, w)
		}
	}

	comp := make([]int, n+1)
	dist := make([]uint8, n+1)
	verts := []int{0}
	stack := make([]int, 0, n)

	for s := 2; s <= n; s++ {
		if comp[s] != 0 {
			continue
		}
		cid := len(verts)
		verts = append(verts, 0)
		comp[s] = cid
		dist[s] = 0
		stack = append(stack, s)
		for len(stack) > 0 {
			v := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			verts[cid]++
			for e := head[v]; e != -1; e = nxt[e] {
				u := to[e]
				if comp[u] == 0 {
					comp[u] = cid
					dist[u] = dist[v] ^ wt[e]
					stack = append(stack, u)
				}
			}
		}
	}

	k := len(verts) - 1
	edgesCnt := make([]int, k+1)
	rank := make([]int, k+1)
	bases := make([][5]uint8, k+1)

	for i := 0; i < len(eu); i++ {
		cid := comp[eu[i]]
		edgesCnt[cid]++
		val := dist[eu[i]] ^ dist[ev[i]] ^ ew[i]
		if val != 0 {
			if insertBasis(&bases[cid], val) {
				rank[cid]++
			}
		}
	}

	neighCnt := make([]int, k+1)
	na := make([]int, k+1)
	nb := make([]int, k+1)

	for v := 2; v <= n; v++ {
		if has1[v] {
			cid := comp[v]
			if neighCnt[cid] == 0 {
				na[cid] = v
			} else {
				nb[cid] = v
			}
			neighCnt[cid]++
		}
	}

	states, idMap := generateStates()
	numStates := len(states)

	stateBasis := make([][5]uint8, numStates)
	for i, u := range states {
		var b [5]uint8
		for x := 1; x < 32; x++ {
			if (u & (uint32(1) << uint(x))) != 0 {
				insertBasis(&b, uint8(x))
			}
		}
		stateBasis[i] = b
	}

	addVec := make([][32]int16, numStates)
	for i, u := range states {
		for x := 0; x < 32; x++ {
			w := spanAddBitset(u, x)
			addVec[i][x] = int16(idMap[w])
		}
	}

	comb := make([]int16, numStates*numStates)
	for i := range comb {
		comb[i] = -1
	}
	for i := 0; i < numStates; i++ {
		row := i * numStates
		for j := 0; j < numStates; j++ {
			if (states[i] & states[j]) != 1 {
				continue
			}
			cur := i
			b := stateBasis[j]
			for t := 0; t < 5; t++ {
				if b[t] != 0 {
					cur = int(addVec[cur][b[t]])
				}
			}
			comb[row+j] = int16(cur)
		}
	}

	dp := make([]int64, numStates)
	ndp := make([]int64, numStates)
	dp[0] = 1

	for cid := 1; cid <= k; cid++ {
		for i := 0; i < numStates; i++ {
			ndp[i] = 0
		}

		var optIds [3]int
		var optWays [3]int64
		optCnt := 0

		addOption(&optIds, &optWays, &optCnt, 0, 1)

		d := edgesCnt[cid] - verts[cid] + 1
		if d == rank[cid] {
			sbit := basisToBitset(bases[cid])
			sid := idMap[sbit]
			if neighCnt[cid] == 1 {
				addOption(&optIds, &optWays, &optCnt, sid, 1)
			} else if neighCnt[cid] == 2 {
				addOption(&optIds, &optWays, &optCnt, sid, 2)
				x := int(dist[na[cid]] ^ dist[nb[cid]] ^ w1[na[cid]] ^ w1[nb[cid]])
				if (sbit & (uint32(1) << uint(x))) == 0 {
					tid := int(addVec[sid][x])
					addOption(&optIds, &optWays, &optCnt, tid, 1)
				}
			}
		}

		for s, val := range dp {
			if val == 0 {
				continue
			}
			base := s * numStates
			for i := 0; i < optCnt; i++ {
				r := comb[base+optIds[i]]
				if r < 0 {
					continue
				}
				idx := int(r)
				nv := ndp[idx] + val*optWays[i]
				for nv >= MOD {
					nv -= MOD
				}
				ndp[idx] = nv
			}
		}

		dp, ndp = ndp, dp
	}

	ans := int64(0)
	for _, v := range dp {
		ans += v
		if ans >= MOD {
			ans -= MOD
		}
	}

	out := bufio.NewWriter(os.Stdout)
	out.WriteString(strconv.FormatInt(ans, 10))
	out.Flush()
}
```