```go
package main
import (
"bufio"
"io"
"os"
"strconv"
)
type FastScanner struct {
b []byte
i int
n int
}
func NewFastScanner() *FastScanner {
data, _ := io.ReadAll(os.Stdin)
return &FastScanner{b: data, n: len(data)}
}
func (fs *FastScanner) NextInt() int {
for fs.i < fs.n {
c := fs.b[fs.i]
if c >= '0' && c <= '9' {
break
}
fs.i++
}
v := 0
for fs.i < fs.n {
c := fs.b[fs.i]
if c < '0' || c > '9' {
break
}
v = v*10 + int(c-'0')
fs.i++
}
return v
}
type DSU struct {
p []int32
sz []int32
cnt int
}
func NewDSU(n int) *DSU {
p := make([]int32, n)
sz := make([]int32, n)
for i := 0; i < n; i++ {
p[i] = int32(i)
sz[i] = 1
}
return &DSU{p: p, sz: sz, cnt: n}
}
func (d *DSU) Find(x int32) int32 {
r := x
for d.p[r] != r {
r = d.p[r]
}
for d.p[x] != x {
nx := d.p[x]
d.p[x] = r
x = nx
}
return r
}
func (d *DSU) Union(a, b int32) {
ra := d.Find(a)
rb := d.Find(b)
if ra == rb {
return
}
if d.sz[ra] < d.sz[rb] {
ra, rb = rb, ra
}
d.p[rb] = ra
d.sz[ra] += d.sz[rb]
d.cnt--
}
func buildSPF(n int) []uint32 {
spf := make([]uint32, n+1)
primes := make([]int32, 0, 700000)
for i := 2; i <= n; i++ {
if spf[i] == 0 {
spf[i] = uint32(i)
primes = append(primes, int32(i))
}
limit := n / i
si := spf[i]
for j := 0; j < len(primes); j++ {
p := int(primes[j])
if uint32(p) > si || p > limit {
break
}
spf[i*p] = uint32(p)
}
}
return spf
}
func factorPowers(x int, spf []uint32, comps *[8]int64) int {
k := 0
for x > 1 {
p := int(spf[x])
pw := 1
for x%p == 0 {
x /= p
pw *= p
}
comps[k] = int64(pw)
k++
}
return k
}
func main() {
fs := NewFastScanner()
n := fs.NextInt()
vals := make([]int32, n)
maxA := 0
for i := 0; i < n; i++ {
a := fs.NextInt()
vals[i] = int32(a)
if a > maxA {
maxA = a
}
}
idx := make([]int32, maxA+1)
for i, a := range vals {
idx[int(a)] = int32(i) + 1
}
dsu := NewDSU(n)
if maxA >= 2 {
spf := buildSPF(maxA)
var comps [8]int64
var prods [256]int64
limit := int64(maxA)
for i, av := range vals {
a := int(av)
id0 := int32(i)
if a > 1 && (a&1) == 1 {
k := factorPowers(a, spf, &comps)
prods[0] = 1
cnt := 1
for j := 0; j < k; j++ {
c := comps[j]
for t := 0; t < cnt; t++ {
prods[cnt+t] = prods[t] * c
}
cnt <<= 1
}
total := int64(a)
for j := 0; j < cnt; j++ {
u := prods[j]
v := total / u
if u >= v {
continue
}
uu := u * u
vv := v * v
y := (vv - uu) >> 1
if y <= limit {
id := idx[int(y)]
if id != 0 {
dsu.Union(id0, id-1)
}
}
z := (vv + uu) >> 1
if z <= limit {
id := idx[int(z)]
if id != 0 {
dsu.Union(id0, id-1)
}
}
}
}
if (a & 3) == 0 {
tval := a >> 1
k := factorPowers(tval, spf, &comps)
prods[0] = 1
cnt := 1
for j := 0; j < k; j++ {
c := comps[j]
for t := 0; t < cnt; t++ {
prods[cnt+t] = prods[t] * c
}
cnt <<= 1
}
total := int64(tval)
for j := 0; j < cnt; j++ {
n1 := prods[j]
m := total / n1
if n1 >= m {
continue
}
nn := n1 * n1
mm := m * m
x := mm - nn
if x <= limit {
id := idx[int(x)]
if id != 0 {
dsu.Union(id0, id-1)
}
}
z := mm + nn
if z <= limit {
id := idx[int(z)]
if id != 0 {
dsu.Union(id0, id-1)
}
}
}
}
}
}
w := bufio.NewWriterSize(os.Stdout, 1<<20)
w.WriteString(strconv.Itoa(dsu.cnt))
w.Flush()
}
```