```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
const MOD = 1000000007
var (
lenArr []int
linkArr []int
nextArr [][2]int
sz int
last int
)
func initSAM(m int) {
maxNodes := 2*m + 5
lenArr = make([]int, maxNodes)
linkArr = make([]int, maxNodes)
nextArr = make([][2]int, maxNodes)
lenArr[0] = 0
linkArr[0] = -1
for i := range nextArr {
nextArr[i][0] = -1
nextArr[i][1] = -1
}
sz = 1
last = 0
}
func extend(c int) {
cur := sz
sz++
lenArr[cur] = lenArr[last] + 1
p := last
for p != -1 && nextArr[p][c] == -1 {
nextArr[p][c] = cur
p = linkArr[p]
}
if p == -1 {
linkArr[cur] = 0
} else {
q := nextArr[p][c]
if lenArr[p]+1 == lenArr[q] {
linkArr[cur] = q
} else {
clone := sz
sz++
lenArr[clone] = lenArr[p] + 1
nextArr[clone] = nextArr[q]
linkArr[clone] = linkArr[q]
for p != -1 && nextArr[p][c] == q {
nextArr[p][c] = clone
p = linkArr[p]
}
linkArr[q] = clone
linkArr[cur] = clone
}
}
last = cur
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
if !scanner.Scan() {
return
}
m, _ := strconv.Atoi(scanner.Text())
initSAM(m)
S := make([]byte, 0, m)
dp := make([]int, m+5)
var totalAns int64 = 0
for i := 0; i < m; i++ {
if !scanner.Scan() {
break
}
sStr := scanner.Text()
digit := int(sStr[0] - '0')
S = append(S, sStr[0])
extend(digit)
maxLen := lenArr[last]
minLen := lenArr[linkArr[last]] + 1
curLen := i + 1
minStart := curLen - maxLen
maxStart := curLen - minLen
for k := 1; k <= 4; k++ {
if curLen+k < len(dp) {
dp[curLen+k] = 0
}
}
dp[curLen] = 1
var currentSum int64 = 0
for k := curLen - 1; k >= minStart; k-- {
var ways int64 = 0
for L := 1; L <= 4; L++ {
if k+L <= curLen {
valid := true
if L == 4 {
if S[k] == '0' && S[k+1] == '0' && S[k+2] == '1' && S[k+3] == '1' {
valid = false
} else if S[k] == '0' && S[k+1] == '1' && S[k+2] == '0' && S[k+3] == '1' {
valid = false
} else if S[k] == '1' && S[k+1] == '1' && S[k+2] == '1' && S[k+3] == '0' {
valid = false
} else if S[k] == '1' && S[k+1] == '1' && S[k+2] == '1' && S[k+3] == '1' {
valid = false
}
}
if valid {
ways = (ways + int64(dp[k+L])) % MOD
}
}
}
dp[k] = int(ways)
if k <= maxStart {
currentSum = (currentSum + ways) % MOD
}
}
totalAns = (totalAns + currentSum) % MOD
fmt.Fprintln(out, totalAns)
}
}
```