← Home
 ```go
package main

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

type State struct {
	next [2]int
	link int
	len  int
}

func countDistinct(s string) int {
	n := len(s)
	size := 2 * n
	st := make([]State, size)
	for i := range st {
		st[i].next = [2]int{-1, -1}
		st[i].link = -1
	}
	last := 0
	sz := 1

	for i := 0; i < n; i++ {
		c := 0
		if s[i] == 'O' {
			c = 1
		}
		cur := sz
		sz++
		st[cur].len = st[last].len + 1
		p := last
		for p != -1 && st[p].next[c] == -1 {
			st[p].next[c] = cur
			p = st[p].link
		}
		if p == -1 {
			st[cur].link = 0
		} else {
			q := st[p].next[c]
			if st[p].len+1 == st[q].len {
				st[cur].link = q
			} else {
				clone := sz
				sz++
				st[clone].len = st[p].len + 1
				st[clone].next = st[q].next
				st[clone].link = st[q].link
				for p != -1 && st[p].next[c] == q {
					st[p].next[c] = clone
					p = st[p].link
				}
				st[q].link = clone
				st[cur].link = clone
			}
		}
		last = cur
	}

	res := 0
	for i := 1; i < sz; i++ {
		res += st[i].len - st[st[i].link].len
	}
	return res
}

func getWord(idx int) string {
	if idx == 0 {
		return "XXO"
	}
	s := ""
	x := idx
	for x > 0 {
		if x&1 == 1 {
			s = "O" + s
		} else {
			s = "X" + s
		}
		x >>= 1
	}
	return "X" + s + "O"
}

func main() {
	scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())

	words := make([]string, n)
	for i := 0; i < n; i++ {
		words[i] = getWord(i)
		fmt.Println(words[i])
	}

	powerMap := make(map[int][2]int)
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			spell := words[i] + words[j]
			power := countDistinct(spell)
			powerMap[power] = [2]int{i + 1, j + 1}
		}
	}

	scanner.Scan()
	q, _ := strconv.Atoi(scanner.Text())

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	for i := 0; i < q; i++ {
		scanner.Scan()
		p, _ := strconv.Atoi(scanner.Text())
		ans := powerMap[p]
		fmt.Fprintln(out, ans[0], ans[1])
	}
}
```