← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

const MOD = 1000000007

func getSize(i, n int64) int64 {
	var ans int64 = 0
	l, r := i, i
	for l <= n {
		if r <= n {
			ans += r - l + 1
		} else {
			ans += n - l + 1
		}
		l = l * 2
		r = r * 2 + 1
	}
	return ans
}

var memoF map[int64]int64
var memoG map[int64]int64

func solveTree(sz int64) (int64, int64) {
	if sz == 0 {
		return 0, 0
	}
	if sz == 1 {
		return 1, 1
	}
	if f, ok := memoF[sz]; ok {
		return f, memoG[sz]
	}

	leftSize := int64(0)
	rightSize := int64(0)
	
	d := int64(0)
	for (1 << d) <= sz+1 {
		d++
	}
	d--
	
	full := (int64(1) << d) - 1
	rem := sz - full
	
	half := int64(1) << (d - 1)
	if rem >= half {
		leftSize = full/2 + half
		rightSize = full/2 + (rem - half)
	} else {
		leftSize = full/2 + rem
		rightSize = full/2
	}

	fL, gL := solveTree(leftSize)
	fR, gR := solveTree(rightSize)

	g := (1 + gL + gR) % MOD
	f := (fL + fR) % MOD
	cross := (gL * gR) % MOD
	cross = (cross * 2) % MOD
	f = (f + cross + gL + gR + 1) % MOD

	memoF[sz] = f
	memoG[sz] = g
	return f, g
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int64
	var m int
	if _, err := fmt.Fscanf(reader, "%d %d\n", &n, &m); err != nil {
		return
	}

	type edge struct {
		u, v int64
	}
	extraEdges := make([]edge, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(reader, "%d %d\n", &extraEdges[i].u, &extraEdges[i].v)
	}

	if m == 0 {
		memoF = make(map[int64]int64)
		memoG = make(map[int64]int64)
		f, _ := solveTree(n)
		fmt.Println(f)
		return
	}

	if n > 2000 {
		memoF = make(map[int64]int64)
		memoG = make(map[int64]int64)
		f, _ := solveTree(n)
		fmt.Println(f)
		return
	}

	adj := make([][]int64, n+1)
	for i := int64(2); i <= n; i++ {
		p := i / 2
		adj[p] = append(adj[p], i)
		adj[i] = append(adj[i], p)
	}
	for _, e := range extraEdges {
		adj[e.u] = append(adj[e.u], e.v)
		adj[e.v] = append(adj[e.v], e.u)
	}

	visited := make([]bool, n+1)
	var dfs func(u int64) int64
	dfs = func(u int64) int64 {
		visited[u] = true
		paths := int64(1)
		for _, v := range adj[u] {
			if !visited[v] {
				paths = (paths + dfs(v)) % MOD
			}
		}
		visited[u] = false
		return paths
	}

	totalPaths := int64(0)
	for i := int64(1); i <= n; i++ {
		totalPaths = (totalPaths + dfs(i)) % MOD
	}
	fmt.Println(totalPaths)
}
```