```go
package main
import (
"fmt"
"math/big"
)
var cellsUsed int = 3
var instructions []string
var zeroCell int = 0
var pInt int64
var dInt int64
func allocate() int {
cellsUsed++
return cellsUsed
}
func out(s string) {
instructions = append(instructions, s)
}
func buildValueFrom1(V int64) int {
if V == 0 {
return getZero()
}
if V == 1 {
return 3
}
binStr := fmt.Sprintf("%b", V)
ans := allocate()
for i := 1; i < len(binStr); i++ {
out(fmt.Sprintf("+ %d %d %d", ans, ans, ans))
if binStr[i] == '1' {
out(fmt.Sprintf("+ %d 3 %d", ans, ans))
}
}
return ans
}
func getZero() int {
if zeroCell == 0 {
zeroCell = buildValueFrom1(pInt)
}
return zeroCell
}
func multiplyByConstant(srcCell int, C int64) int {
C = C % pInt
if C == 0 {
return getZero()
}
if C == 1 {
ans := allocate()
out(fmt.Sprintf("+ %d %d %d", srcCell, getZero(), ans))
return ans
}
binStr := fmt.Sprintf("%b", C)
ans := allocate()
out(fmt.Sprintf("+ %d %d %d", srcCell, getZero(), ans))
for i := 1; i < len(binStr); i++ {
out(fmt.Sprintf("+ %d %d %d", ans, ans, ans))
if binStr[i] == '1' {
out(fmt.Sprintf("+ %d %d %d", ans, srcCell, ans))
}
}
return ans
}
func combExact(n, k int64) int64 {
if k < 0 || k > n {
return 0
}
if k == 0 || k == n {
return 1
}
if k > n/2 {
k = n - k
}
var res int64 = 1
for i := int64(1); i <= k; i++ {
res = res * (n - i + 1)
res = res / i
}
return res
}
func computeS(vCell int) int {
sumCell := getZero()
for j := int64(0); j <= dInt-2; j++ {
term := combExact(dInt-2, j)
if (dInt-2-j)%2 != 0 {
term = -term
}
term = term % pInt
if term < 0 {
term += pInt
}
wJ := term
if wJ == 0 {
continue
}
vPlusJ := 0
if j == 0 {
vPlusJ = vCell
} else {
jCell := buildValueFrom1(j)
vPlusJ = allocate()
out(fmt.Sprintf("+ %d %d %d", vCell, jCell, vPlusJ))
}
termD := allocate()
out(fmt.Sprintf("^ %d %d", vPlusJ, termD))
termWeighted := multiplyByConstant(termD, wJ)
if sumCell == getZero() {
sumCell = termWeighted
} else {
newSum := allocate()
out(fmt.Sprintf("+ %d %d %d", sumCell, termWeighted, newSum))
sumCell = newSum
}
}
return sumCell
}
func modInverse(a, m int64) int64 {
bigA := big.NewInt(a)
bigM := big.NewInt(m)
inv := new(big.Int).ModInverse(bigA, bigM)
return inv.Int64()
}
func main() {
var d, p int64
if _, err := fmt.Scan(&d, &p); err != nil {
return
}
dInt = d
pInt = p
xPlusY := allocate()
out(fmt.Sprintf("+ 1 2 %d", xPlusY))
sXPlusY := computeS(xPlusY)
sX := computeS(1)
sY := computeS(2)
s0 := computeS(getZero())
sum1 := allocate()
out(fmt.Sprintf("+ %d %d %d", sXPlusY, s0, sum1))
sXNeg := multiplyByConstant(sX, pInt-1)
sYNeg := multiplyByConstant(sY, pInt-1)
sum2 := allocate()
out(fmt.Sprintf("+ %d %d %d", sum1, sXNeg, sum2))
sum3 := allocate()
out(fmt.Sprintf("+ %d %d %d", sum2, sYNeg, sum3))
var dFact int64 = 1
for i := int64(1); i <= dInt; i++ {
dFact = (dFact * i) % pInt
}
inv := modInverse(dFact, pInt)
finalAns := multiplyByConstant(sum3, inv)
out(fmt.Sprintf("f %d", finalAns))
for _, s := range instructions {
fmt.Println(s)
}
}
```