Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7) #再帰関数の上限,10**5以上の場合python
import math
from copy import copy, deepcopy
from copy import deepcopy as dcp
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right#2分探索
#bisect_left(l,x), bisect(l,x)#aはソート済みである必要あり。aの中からx未満の要素数を返す。rightだと以下
from collections import deque, defaultdict
#deque(l), pop(), append(x), popleft(), appendleft(x)
#q.rotate(n)で → にn回ローテート
from collections import Counter#文字列を個数カウント辞書に、
#S=Counter(l),S.most_common(x),S.keys(),S.values(),S.items()
from itertools import accumulate,combinations,permutations,product#累積和
#list(accumulate(l))
from heapq import heapify,heappop,heappush
#heapify(q),heappush(q,a),heappop(q) #q=heapify(q)としないこと、返り値はNone
from functools import reduce,lru_cache#pypyでもうごく
#@lru_cache(maxsize = None)#maxsizeは保存するデータ数の最大値、2**nが最も高効率
from decimal import Decimal

def input(): 
    x=sys.stdin.readline()
    return x[:-1] if x[-1]=="\n" else x
def printe(*x):print("## ",*x,file=sys.stderr)
def printl(li): _=print(*li, sep="\n") if li else None
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)
def matmat(A,B):
    K,N,M=len(B),len(A),len(B[0])
    return [[sum([(A[i][k]*B[k][j]) for k in range(K)]) for j in range(M)] for i in range(N)]
def matvec(M,v):
    N,size=len(v),len(M)
    return [sum([M[i][j]*v[j] for j in range(N)]) for i in range(size)]
def T(M):
    n,m=len(M),len(M[0])
    return [[M[j][i] for j in range(n)] for i in range(m)]
def binr(x): return bin(x)[2:]
def bitcount(x): #xは64bit整数
    x= x - ((x >> 1) & 0x5555555555555555)
    x= (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x= (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f 
    x+= (x >> 8); x+= (x >> 16); x+= (x >> 32) 
    return x & 0x7f

EPS = 0.000000001
def fadd(a,b):#誤差を考慮したaddを使うこと
    if abs(a+b)<EPS*(abs(a)+abs(b)): return 0
    return a+b

class P:#二次元ベクトル
    def __init__(self, x,y):
        self.x=x
        self.y=y
    
    def __add__(self,other):
        nx=fadd(self.x,other.x)
        ny=fadd(self.y,other.y)
        return P(nx,ny)
    
    def __neg__(self):
        return P(-self.x,-self.y)

    def __sub__(self,other):
        return self.__add__(-other)
    
    def __mul__(self,other):
        if isinstance(other, P):
            return P(self.x*other.x,self.y*other.y)
        return P(self.x*other,self.y*other)

    def __rmul__(self,other):
        return self.__mul__(other)

    def __eq__(self,other):
        if abs(self.x-other.x)+abs(self.y-other.y)<1e-10:
            return 1
        else: return 0

    def dot(self, other):
        return fadd(self.x*other.x,self.y*other.y)
    
    def det(self,other):#外積
        return fadd(self.x*other.y,-self.y*other.x)
    
    def on_seg(self, p1, p2, edge=True):#selfが線分p1,p2上にあるか判定, 端も含む場合はedge=True
        if edge:
            return (p1-self).det(p2-self)==0 and (p1-self).dot(p2-self)<=0
        else:
            return (p1-self).det(p2-self)==0 and (p1-self).dot(p2-self)<0

def main():
    mod = 1000000007
    #w.sort(key=itemgetter(1),reverse=True)  #二個目の要素で降順並び替え

    N = int(input())
    #N, K = map(int, input().split())
    #A = tuple(map(int, input().split())) #1行ベクトル
    #L = tuple(int(input()) for i in range(N)) #改行ベクトル
    S = tuple(tuple(map(int, input().split())) for i in range(N)) #改行行列
    
    r=-1
    for i1 in range(N):
        x1=S[i1][0]
        for i2 in range(N):
            y1=S[i2][1]
            for j in range(N):
                x2=S[j][0]
                for j2 in range(N):
                    y2=S[j2][1]
                    ps=(P(x1,y1),P(x2,y1),P(x1,y2),P(x2,y2))

                    for p1,p2,p3 in combinations(ps,3):
                        if (p2-p1).dot(p3-p1)<=0:
                            ri=(p3-p2).dot(p3-p2)**0.5/2
                        elif (p2-p3).dot(p1-p3)<=0:
                            ri=(p1-p2).dot(p1-p2)**0.5/2
                        elif (p3-p2).dot(p1-p2)<=0:
                            ri=(p1-p3).dot(p1-p3)**0.5/2
                        else:
                            l=(p3-p2).dot(p3-p2)**0.5+(p1-p3).dot(p1-p3)**0.5+(p1-p2).dot(p1-p2)**0.5
                            pi=(p3-p2)
                            pj=(p1-p2)
                            ri=abs(pi.x*pj.y-pi.y*pj.x)/l
                        #printe(ri,((x1,y1),(x2,y1),(x1,y2),(x2,y2)))
                        if r<ri:
                            r=ri

                    
    print(r)

if __name__ == "__main__":
    main()

Fixed submission:
import sys
sys.setrecursionlimit(10**7) #再帰関数の上限,10**5以上の場合python
import math
from copy import copy, deepcopy
from copy import deepcopy as dcp
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right#2分探索
#bisect_left(l,x), bisect(l,x)#aはソート済みである必要あり。aの中からx未満の要素数を返す。rightだと以下
from collections import deque, defaultdict
#deque(l), pop(), append(x), popleft(), appendleft(x)
#q.rotate(n)で → にn回ローテート
from collections import Counter#文字列を個数カウント辞書に、
#S=Counter(l),S.most_common(x),S.keys(),S.values(),S.items()
from itertools import accumulate,combinations,permutations,product#累積和
#list(accumulate(l))
from heapq import heapify,heappop,heappush
#heapify(q),heappush(q,a),heappop(q) #q=heapify(q)としないこと、返り値はNone
from functools import reduce,lru_cache#pypyでもうごく
#@lru_cache(maxsize = None)#maxsizeは保存するデータ数の最大値、2**nが最も高効率
from decimal import Decimal
import cmath
def input(): 
    x=sys.stdin.readline()
    return x[:-1] if x[-1]=="\n" else x
def printe(*x):print("## ",*x,file=sys.stderr)
def printl(li): _=print(*li, sep="\n") if li else None
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)
def matmat(A,B):
    K,N,M=len(B),len(A),len(B[0])
    return [[sum([(A[i][k]*B[k][j]) for k in range(K)]) for j in range(M)] for i in range(N)]
def matvec(M,v):
    N,size=len(v),len(M)
    return [sum([M[i][j]*v[j] for j in range(N)]) for i in range(size)]
def T(M):
    n,m=len(M),len(M[0])
    return [[M[j][i] for j in range(n)] for i in range(m)]
def binr(x): return bin(x)[2:]
def bitcount(x): #xは64bit整数
    x= x - ((x >> 1) & 0x5555555555555555)
    x= (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x= (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f 
    x+= (x >> 8); x+= (x >> 16); x+= (x >> 32) 
    return x & 0x7f

EPS = 0.000000001


def cIntersectionPnt(z1,r1,z2,r2):
    d = abs(z1-z2)
 
    if d < EPS:
        if abs(r1-r2) < EPS:
            return float("inf"),-1,-1
        else:
            return 0,-1,-1
    
    
    if abs(d - (r1+r2)) < EPS:
        diff = (z2-z1)/d
        return 1,z1+diff*r1,-1
    
    if abs(d - (r1-r2)) < EPS:
        diff = (z2-z1)/d
        return 1,z1+diff*r1,-1
    
    if abs(d - (r2-r1)) < EPS:
        diff = (z1-z2)/d
        return 1,z2+diff*r2,-1
 
    if d > r1+r2:
        return 0,-1,-1
    if d < abs(r1-r2):
        return 0,-1,-1
 
 
    rc = (r1*r1+d*d-r2*r2)/(2*d)
    rs = cmath.sqrt(r1*r1-rc*rc)
    diff = (z2-z1)/d
    return 2,z1+diff*rc+diff*1j*rs,z1+diff*rc+diff*(-1j)*rs

def main():
    mod = 1000000007
    #w.sort(key=itemgetter(1),reverse=True)  #二個目の要素で降順並び替え

    N = int(input())
    #N, K = map(int, input().split())
    #A = tuple(map(int, input().split())) #1行ベクトル
    #L = tuple(int(input()) for i in range(N)) #改行ベクトル
    S = tuple(tuple(map(int, input().split())) for i in range(N)) #改行行列
    
    def hantei(R):
        ps=[]
        for (x1,y1),(x2,y2) in combinations(S,2):
            n,p1,p2=cIntersectionPnt(x1+y1*1j,R,x2+y2*1j,R)
            if n<2:
                return False
            ps.append(p1)
            ps.append(p2)
        #printe(ps)
        for p in ps:
            x=p.real
            y=p.imag
            tot=0
            for xi,yi in S:
                if (x-xi)**2+(y-yi)**2<=R**2+EPS:
                    tot+=1
            if tot==N:
                return True
        return False


    def bisect_upper(l,r):#大きい側、r側がTrueとなるhanteiをつかう
        #hanteiを満たす最小の整数
        
        while r-l>0.0000005:
            mid=(r*0.5+l*0.5)
            if hantei(mid):
                r=mid
            else:
                l=mid
        return r


                    
    print(bisect_upper(0,2000))

if __name__ == "__main__":
    main()