← Home
```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()
}
```