// Arup Guha
// 10/28/2013
// Solution to 2013 NCPC Problem D: Robert Hood

import java.util.*;

public class roberthood {

	public static void main(String[] args){

		Scanner stdin = new Scanner(System.in);
		int n = stdin.nextInt();

		// Read in all the points.
		pt[] all = new pt[n];
		for (int i=0; i<n; i++) {
			int x = stdin.nextInt();
			int y = stdin.nextInt();
			all[i] = new pt(x,y);
		}

		pt[] hull = convexhull.getConvexHull(all);

		// Based on limits of input, the convex hull will never have too many points, so we
		// can just do brute force from here, if we want.
		double best = 0;
		for (int i=0; i<hull.length; i++)
			for (int j=i+1; j<hull.length; j++)
				if (hull[i].dist(hull[j]) > best)
					best = hull[i].dist(hull[j]);

		System.out.println(best);
	}
}

class convexhull {

	public static pt[] getConvexHull(pt[] allPts) {

		// Find the first point in our convex hull.
		pt base = getBase(allPts);
		pt.setRef(base);

		// Sort points for Graham Scan.
		Arrays.sort(allPts);

		// Initialize stack to first element.
		Stack<pt> s = new Stack<pt>();
		s.push(base);
		s.push(allPts[0]);

		// Go through each item.
		for (int i=1; i<allPts.length; i++) {

			pt cur = allPts[i];
			pt prev = s.pop();
			pt first = s.pop();

			// Only allow strictly right turns with positive tolerance.
			while (s.size() > 0 && first.getV(prev).crossMag(first.getV(cur)) < 1e-9) {
				prev = first;
				first = s.pop();
			}
			s.push(first);
			s.push(prev);
			s.push(cur);
		}

		// Pop off all items from stack into the hull and return.
		pt[] ans = new pt[s.size()];
		for (int i=ans.length-1; i>=0; i--)
			ans[i] = s.pop();

		return ans;
	}

	// Finds our reference point from allPts for the Graham Scan.
	public static pt getBase(pt[] allPts) {

		pt ans = allPts[0];

		// Look for minimum y, breaking ties with minimum x.
		for (int i=1; i<allPts.length; i++) {
			if (allPts[i].y < ans.y)
				ans = allPts[i];
			else if (allPts[i].y == ans.y && allPts[i].x < ans.x)
				ans = allPts[i];
		}

		return ans;
	}
}

class pt implements Comparable<pt> {

	public int x;
	public int y;
	public static pt reference;

	public pt(int myx, int myy) {
		x = myx;
		y = myy;
	}

	public static void setRef(pt ref) {
		reference = ref;
	}

	// Returns the magnitude of this vector cross v2.
	public double crossMag(pt v2) {
		return this.x*v2.y - v2.x*this.y;
	}

	// Returns the angle of this point from the reference point.
	public double getAngle() {
		return Math.atan2(this.y-reference.y, this.x-reference.x);
	}

	// Returns the distance from this point to other.
	public double dist(pt other) {
		return Math.sqrt(Math.pow(this.x-other.x,2) + Math.pow(this.y-other.y,2));
	}

	// Gets the distance from this point to the reference point.
	public double getDist() {
		return Math.sqrt(Math.pow(this.x-reference.x,2) + Math.pow(this.y-reference.y,2));
	}

	// Returns true iff this and other are identical.
	public boolean same(pt other) {
		return this.x == other.x && this.y == other.y;
	}

	// Returns a vector from this to point dest.
	public pt getV(pt dest) {
		return new pt(dest.x-x, dest.y-y);
	}

	// Compares this to other, in reference to the reference point.
	public int compareTo(pt other) {

		// Avoid div 0 errors.
		if (same(reference)) return 1;
		if (same(other)) return -1;

		// Get reference angles.
		double angle1 = this.getAngle();
		double angle2 = other.getAngle();

		// First look at angles.
		if (angle1 < angle2)
			return -1;
		else if (angle1 > angle2)
			return 1;

		double dist1 = this.getDist();
		double dist2 = other.getDist();

		// Break ties by distance.
		if (dist1 < dist2)
			return -1;
		else if (dist1 > dist2)
			return 1;
		return 0;
	}

	public String toString() {
		return "("+x+", "+y+")";
	}
}