```go
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"time"
)
// Suffix Automaton Node
type stNode struct {
len, link int
next [2]int // 0 for 'O', 1 for 'X'
}
// Function to count distinct substrings using Suffix Automaton
func countDistinctFast(s string) int {
// Initialize SAM
// Pre-allocate to optimize performance
st := make([]stNode, 1, 2*len(s)+1)
st[0] = stNode{len: 0, link: -1, next: [2]int{-1, -1}}
last := 0
for i := 0; i < len(s); i++ {
c := 0
if s[i] == 'X' {
c = 1
}
cur := len(st)
st = append(st, stNode{len: st[last].len + 1, link: 0, next: [2]int{-1, -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 := len(st)
st = append(st, stNode{
len: st[p].len + 1,
link: st[q].link,
next: st[q].next,
})
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
}
ans := 0
for i := 1; i < len(st); i++ {
ans += st[i].len - st[st[i].link].len
}
return ans
}
func main() {
rand.Seed(time.Now().UnixNano())
scanner := bufio.NewScanner(os.Stdin)
// Set a large buffer to handle potentially long lines if necessary
buf := make([]byte, 64*1024)
scanner.Buffer(buf, 1024*1024)
if !scanner.Scan() {
return
}
var n int
fmt.Sscanf(scanner.Text(), "%d", &n)
words := make([]string, 0, n)
// Map power -> indices [i, j]
powerToIndices := make(map[int][2]int)
// Set to keep track of used powers to ensure uniqueness
usedPowers := make(map[int]bool)
// Greedily generate n words
for i := 0; i < n; i++ {
for {
// Generate random string of length 300-320
l := 300 + rand.Intn(21)
b := make([]byte, l)
for k := 0; k < l; k++ {
if rand.Intn(2) == 0 {
b[k] = 'O'
} else {
b[k] = 'X'
}
}
cand := string(b)
valid := true
// Temporary map to hold powers generated by this candidate combined with existing words
currentBatch := make(map[int][2]int)
// Check cand + cand
pSelf := countDistinctFast(cand + cand)
if usedPowers[pSelf] {
valid = false
} else {
currentBatch[pSelf] = [2]int{i + 1, i + 1}
}
if valid {
for j, w := range words {
// Check cand + words[j]
p1 := countDistinctFast(cand + w)
if usedPowers[p1] {
valid = false; break
}
if _, exists := currentBatch[p1]; exists {
valid = false; break
}
currentBatch[p1] = [2]int{i + 1, j + 1}
// Check words[j] + cand
p2 := countDistinctFast(w + cand)
if usedPowers[p2] {
valid = false; break
}
if _, exists := currentBatch[p2]; exists {
valid = false; break
}
currentBatch[p2] = [2]int{j + 1, i + 1}
}
}
if valid {
words = append(words, cand)
for p, idx := range currentBatch {
usedPowers[p] = true
powerToIndices[p] = idx
}
break
}
}
}
// Output the generated words
for i, w := range words {
if i > 0 {
fmt.Print(" ")
}
fmt.Print(w)
}
fmt.Println()
// Process requests
for scanner.Scan() {
text := scanner.Text()
var p int
_, err := fmt.Sscanf(text, "%d", &p)
if err != nil {
break
}
if idx, ok := powerToIndices[p]; ok {
fmt.Printf("%d %d\n", idx[0], idx[1])
}
}
}
```