// Arup Guha
// 5/15/2023
// Solution to SER D1 Problem: Eroding Pillars

import java.util.*;

public class erodingpillars {

	public static int n;
	public static long[] x;
	public static long[] y;
	public static long[][] dSq;
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt(); n++;
		x = new long[n];
		y = new long[n];

		// Read points.
		for (int i=1; i<n; i++) {
			x[i] = stdin.nextLong();
			y[i] = stdin.nextLong();
		}
		
		// Store all unique distances squared.
		TreeSet<Long> lens = new TreeSet<Long>();
		dSq = new long[n][n];
		for (int i=0; i<n; i++) { 
			for (int j=i+1; j<n; j++) {
				dSq[i][j] = (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
				dSq[j][i] = dSq[i][j];
				lens.add(dSq[i][j]);
			}
		}
		
		// Put them in a list.
		ArrayList<Long> ansSq = new ArrayList<Long>();
		while (lens.size() > 0) ansSq.add(lens.pollFirst());
		
		int low = 0, high = ansSq.size()-1;
		
		// Binary search the square of the answer. low and high are indexes into ansSq.
		while (low < high) {
		
			int mid = (low+high)/2;
			
			if (canDo(ansSq.get(mid)))
				high = mid;
			else
				low = mid+1;
		}
		
		// Ta da!
		System.out.println(Math.sqrt(ansSq.get(low)));
	}
	
	// Returns true iff we can jump sqrt(limit) and make it happen.
	public static boolean canDo(long limit) {
	
		// Add all jumpable edges in.
		MagicComponents mine = new MagicComponents(n);
		for (int i=0; i<n; i++)
			for (int j=i+1; j<n; j++)
				if ( dSq[i][j] <= limit)
					mine.addEdge(i,j);
					
		// Run the magic components.
		mine.run();
		
		// Go through all BCCs.
		for (int i=0; i< mine.bccs.size(); i++) {
			ArrayList<Edge> tmp = mine.bccs.get(i);
			
			// If 0 isn't in a bcc, then we can't return back to 0 from that bcc...
			boolean seen = false;
			for (Edge e: tmp) {
				if (e.u == 0 || e.v == 0) {seen = true; break;}
			}
			
			if (!seen) return false;
			
		}
		
		// If we make it here, we're good.
		return true;
	}
}

/*** Old UCF Magic Components Code ***/

class Edge {
  int u, v, id;
  public Edge(int U, int V, int i) {
    u = U; v = V; id = i;
  }
}

class MagicComponents { // Stack Trick!
  int num, n, edges;
  int[] dfsNum, low, vis;
  ArrayList<Integer> cuts;
  ArrayList<Edge> bridges, adj[];
  ArrayList<ArrayList<Edge>> bccs; 
  ArrayDeque<Edge> eStack;
  
  MagicComponents(int N) {
    adj = new ArrayList[n = N];
    for (int i = 0; i < n; i++)
      adj[i] = new ArrayList<>();
    edges = 0;
  }
  
  void addEdge(int u, int v) {
    adj[u].add(new Edge(u, v, edges));
    adj[v].add(new Edge(v, u, edges++));
  }
  
  void run() {
    vis = new int[n];
    dfsNum = new int[n];
    low = new int[n];
    bridges = new ArrayList<>();
    cuts = new ArrayList<>();
    bccs = new ArrayList<>();
    eStack = new ArrayDeque<>();
    num = 0;
    
    for (int i = 0; i < n; i++) {
      if (vis[i] != 0) continue;
      dfs(i, -1);
    }
  }
  
  void dfs(int node, int par) {
    dfsNum[node] = low[node] = num++;
    vis[node] = 1;
    int nChild = 0;
    for(Edge e : adj[node]) {
      if(e.v == par) continue;
      if(vis[e.v] == 0) {
        ++nChild; eStack.push(e); dfs(e.v, node);
        low[node] = Math.min(low[node], low[e.v]);
        if(low[e.v] >= dfsNum[node]) {
          if(dfsNum[node] > 0 || nChild > 1)
            cuts.add(node);
          if(low[e.v] > dfsNum[node]) {
            bridges.add(e); pop(node);
          } else pop(node);
        }
      } else if(vis[e.v] == 1) {
        low[node] = Math.min(low[node], dfsNum[e.v]);
        eStack.push(e);
      } 
    }
    vis[node] = 2;
  }

  void pop(int u) {
    ArrayList<Edge> list = new ArrayList<>();
    for (;;) {
      Edge e = eStack.pop(); list.add(e);
      if(e.u == u) break;
    }
    bccs.add(list);
  }
}