Buggy python submission (verdict: Time Limit Exceeded):
import math

class FastFourierTransform:

	def dft(self, F, inverse ):
		N = len(F)
		if N==1:
			return

		f0 = [ F[2*n] for n in range(N // 2) ]
		f1 = [ F[2*n+1] for n in range(N // 2) ]

		self.dft(f0, inverse)
		self.dft(f1, inverse)

		# 最初のzetaは1
		now = 1 + 0j
		# polar(1.0, inverse * 2.0 * acos(-1) / sz)
		# 絶対値,偏角[rad]
		#zeta = crect(1.0, inverse * 2.0 * acos(-1) / N )
		zeta = complex(math.cos( inverse * 2.0 * math.pi / N ), math.sin( inverse * 2.0 * math.pi / N ) )

		for n in range(N):
			F[n] = f0[ n % (N//2) ] + now * f1[ n % (N//2) ]
			now *= zeta

	def multiply(self, F,G):
		""" multiply by FFT
		"""
		N=1
		# 1.N > deg(g) + deg(h)となる2の冪乗を選ぶ
		while N < len(F) + len(G):
			N *= 2
		# 2. 離散フーリエ変換の計算
		nf = F + [0] * (N-len(F))
		ng = G + [0] * (N-len(G))

		# print("start dft")
		self.dft( nf, 1 )
		self.dft( ng, 1 )
		# print("end dft")
		for n in range(N):
			nf[n] *= ng[n]

		# 3. 離散フーリエ逆変換
		self.dft( nf, -1 )

		ans = []
		for n in range(N):
			# 係数を1/N倍
			ans.append( round(nf[n].real / N) )

		return ans

if __name__ == "__main__":
	N=int(input())
	A=list(map(int,input().split()))

	P=200_003
	rootP=2

	# order of 1 to P-1 after fft
	order=[1]
	x=rootP
	while x!=1:
		order.append(x)
		x *= rootP
		x %= P

	ORDER_SIZE=len(order)	# 200_002

	# create order index
	where=[0 for _ in range(P)]
	for i in range(ORDER_SIZE):
		where[ order[i] ] = i

	# count non zero items
	prevCnt1 = [ 0 for _ in range(P)]
	prevCnt2 = [ 0 for _ in range(P)]
	resCnt = [ 0 for _ in range(P)]
	for n in range(N):
		if A[n] != 0:
			prevCnt1[ where[A[n]] ] += 1
			prevCnt2[ where[A[n]] ] += 1
			# remove Ax * Ax pattern count
			resCnt[ (A[n] * A[n]) % P ] -= 1

	# fft to cnt (calc nC2 and all Ax * Ay)
	clsFFT = FastFourierTransform()
	fftRes = clsFFT.multiply(prevCnt1,prevCnt2)

	for r in range(len(fftRes)):
		if fftRes[r] != 0:
			# get result(Ax*Ay==resCnt.index) Cnt by summary fftRes
			resCnt[ order[ r % ORDER_SIZE ] ] += fftRes[r]

	ans = 0
	for p in range(P):
		if resCnt[p] != 0:
			# print(p,resCnt[p])
			# remove j <= i pattern count 
			# and
			# calc summary value((Ax * Ay cnt) * (Ax * Ay)))
			ans += (resCnt[p] // 2) * p

	print(ans)








Fixed submission:
import numpy as np


class FastFourierTransform:
	"""FFT
	"""

	def multiplySameArr(self,A):
		""" multiply by FFT(A*A)
		"""
		N=1
		# 1. N > deg(g) + deg(h)となる2の冪乗を選ぶ
		while N < 2*len(A): N *= 2

		# 2. 離散フーリエ変換の計算
		nf = np.zeros(N,int)
		nf[:len(A)]=A
		nf=np.fft.fft(nf)
		nf = nf * nf

		# 3. 離散フーリエ逆変換
		nf=np.fft.ifft(nf)

		# コピー
		ans = np.zeros(N,int)
		for n in range(N):
			# 係数を1/N倍 => np.fftの場合、すでに実行済
			#ans.append( round(nf[n].real / N) )
			if nf[n].real != 0:
				ans[n] = int(nf[n].real + 0.5)

		return ans

if __name__ == "__main__":
	N=int(input())
	A=list(map(int,input().split()))

	P=200_003
	rootP=2

	# order of 1 to P-1 after fft
	order=[1]
	x=rootP
	while x!=1:
		order.append(x)
		x *= rootP
		x %= P

	ORDER_SIZE=len(order)	# 200_002

	# create order index
	where=np.zeros(P,int)
	for i in range(ORDER_SIZE):
		where[ order[i] ] = i

	# count non zero items
	prevCnt = np.zeros(P,int)
	resCnt = np.zeros(P,int)
	for n in range(N):
		if A[n] != 0:
			prevCnt[ where[A[n]] ] += 1
			# remove Ax * Ax pattern count
			resCnt[ (A[n] * A[n]) % P ] -= 1

	# fft to cnt (calc nC2 and all Ax * Ay)
	clsFFT = FastFourierTransform()
	fftRes = clsFFT.multiplySameArr(prevCnt)

	for r in range(len(fftRes)):
		if fftRes[r] != 0:
			# get result(Ax*Ay==resCnt.index) Cnt by summary fftRes
			resCnt[ order[ r % ORDER_SIZE ] ] += fftRes[r]

	ans = 0
	for p in range(P):
		if resCnt[p] != 0:
			# remove j <= i pattern count 
			# and
			# calc summary value((Ax * Ay cnt) * (Ax * Ay)))
			ans += (resCnt[p] // 2) * p

	print(ans)