#include<bits/stdc++.h>
using namespace std;
#define EPS 1e-10
#define inf 1e100
// compile '-std=c++14'

//typedef complex<double> comp;//複素数を利用することでangleを出しやすくする
typedef struct point{ // ベクトル(原点）　や　xy座標
	double x,y;
	point(){};
	point(double x,double y) :x(x),y(y){};
	//ベクトル的計算
	point operator + (point &p){ return point(x+p.x,y+p.y) ;}
	point operator - (point &p){ return point(x-p.x,y-p.y) ;}
	point operator * (point &p){ return point(x*p.x-y*p.y ,x*p.y+y*p.x ) ;}
	point operator * (double k){ return point(x*k,y*k) ;}
	point operator / (double k){ return point(x/k,y/k) ;}
	//大小関係　x座標　優先
	bool operator <  (const point &p) { return x!=p.x ? x<p.x : y < p.y;}
	bool operator >  (const point &p) { return x!=p.x ? x>p.x : y > p.y;}
	bool operator == (const point &p) { return fabs(x-p.x) <= EPS && fabs(y-p.y) <=  EPS ;}
	bool operator != (const point &p) { return x!=p.x || y !=p.y;}
	//関数
	double norm(){ return x*x+y*y;}
	double abs(){ return sqrt(norm() );}
	double arg(){//原点からの角度
		//comp c(x.y);
		//return c.arg();
		return atan2(y,x);
	}	
	void print(){ cout<<x<<' '<<y<<endl; }
	void make(){ cin>>x>>y;}
}point;

typedef struct segment{// 線分 s -> e
	point s,e;
	segment(){};
	segment(point &s,point &e) : s(s),e(e){};
	//大小関係
	bool operator < (const segment &d){return s!=d.s ? s<d.s : e < d.e;}
	bool operator > (const segment &d){return s!=d.s ? s>d.s : e > d.e;}
	bool operator == (const segment &d){return (s==d.s)&&(e==d.e);}
	//関数
	point vec() { return e-s;}
	double abs(){ return (e-s).abs();}
	void print(){ cout<<"("<<s.x<<","<<s.y<<") ("<<e.x<<","<<e.y<<")"<<endl;}
	void make(){ s.make(),e.make(); }
	void swap() { point tmp = s; s = e;e = tmp;}
	void lr(){if( !(s<e) ) swap(); } //left to right
}segment;
//内積
double dot(point &a,point &b){return a.x*b.x + a.y*b.y; }
//外積
double cross(point &a,point &b){return a.x*b.y-a.y*b.x; }

// (p3-p1)*(p2-p1)
double direction(point &p1,point &p2,point &p3){ point a = p3-p1, b = p2-p1; return cross( a ,b  ); }
// p1~p2 上に　p3があるか判定
bool on_segment(point &p1,point &p2,point &p3){
	if( abs(  direction(p1,p2,p3)  ) < EPS ) //segments_intersectでは必要なし
		if( ( min(p1.x,p2.x) <= p3.x && p3.x <= max(p1.x,p2.x) ) && ( min(p1.y,p2.y)<= p3.y && p3.y <= max(p1.y,p2.y) ) ) return true;
	return false;  
}
//交点検出
bool segments_intersect(point &p1,point &p2,point &p3,point &p4){
	double d1 = direction(p3,p4,p1);
	double d2 = direction(p3,p4,p2);
	double d3 = direction(p1,p2,p3);
	double d4 = direction(p1,p2,p4);
	if(  ( (d1 > 0 and d2 < 0 ) or (d1 < 0 and d2 > 0) ) and ( ( d3 > 0 and d4 < 0) or ( d3 < 0 and d4 > 0) )  ) return true;   
	if( ( abs(d1) <= EPS )  and on_segment(p3,p4,p1) ) return true;
	if( ( abs(d2) <= EPS )  and on_segment(p3,p4,p2) ) return true;
	if( ( abs(d3) <= EPS )  and on_segment(p1,p2,p3) ) return true;
	if( ( abs(d4) <= EPS )  and on_segment(p1,p2,p4) ) return true;
	return false;
}
bool segments_intersect(segment &s1,segment &s2){ return segments_intersect(s1.s,s1.e,s2.s,s2.e) ; }
typedef struct event{
	double x;
	segment s;
	bool f;//true -> segment s.sのx座標 false -> segment s.eのx座標
	event(){};
	event(double x,segment &s,bool f) :x(x),s(s),f(f){};
	bool operator < (const event &e){
	if(x==e.x){//x座標が同じなら 挿入できる方が先
		if(f&&!e.f) return true;//
		if(!f&&e.f) return false;
	}
	return x!=e.x ? x<e.x : s<e.s;	}
	bool operator == (const event &e){return (x==e.x) && (s==e.s);}
}event;
typedef pair<double,double> mp;

bool any_segments_intersect(vector<segment> &S){//P1025
	//1
	//set<segment> T;//
	map<mp,segment> T1,T2; 	//mp (y,x) 挿入する際にすでにkeyが使われている場合はtrue
				// T1はそのまま　T2はキーを　mp(-y,-x)
	vector<event> events;
	int n = S.size();
	//2
	for(int i=0;i<n;i++){
		S[i].lr();
		events.push_back(event(S[i].s.x ,S[i],true) );
		events.push_back(event(S[i].e.x ,S[i],false) );	
	}
	sort(events.begin(),events.end());
	//3
	for(int i=0;i<events.size();i++){
		if(events[i].f){//left endpoint
			event ev = events[i];
			segment s = ev.s;
			mp tmp1 = mp(s.s.y,s.s.x),tmp2 = mp(-s.s.y,-s.s.x);
			if(T1.find(tmp1) != T1.end() ) return true; //既に同じ点が使われている
			auto it1 = T1.upper_bound(tmp1);
			auto it2 = T2.upper_bound(tmp2);
			if(it1 != T1.end() ){
				segment s1 = it1->second;
				if(segments_intersect(s,s1) ) return true;
			}
			if(it2 != T2.end()){
				segment s2 = it2->second;
				if(segments_intersect(s,s2) ) return true;
			}	
			//insert
			T1.insert(make_pair(tmp1,s) );
			T2.insert(make_pair(tmp2,s) );			
		}else{//right endpoint
			event ev = events[i];
			segment s = ev.s;
			mp tmp1 = mp(s.s.y,s.s.x),tmp2 = mp(-s.s.y,-s.s.x);
			auto it1 = T1.upper_bound(tmp1);
			auto it2 = T2.upper_bound(tmp2);
			
			if(it1 != T1.end()&&it2 != T2.end() ){
				segment s1 = it1->second;
				segment s2 = it2->second;
				if(segments_intersect(s1,s2) ) return true;
			}
			//delete
			T1.erase(tmp1);
			T2.erase(tmp2);
		}
	}	
	return false;//12
}

	
bool lessangle(point &p1,point &p2){
	mp tmp1  =  mp( p1.arg(),p1.abs() );//angle,r
	mp tmp2  =  mp( p2.arg(),p2.abs() );
	return tmp1 < tmp2; //tmp1の方が偏角が小さい
}
bool lessy_x(const point &p1,const point &p2){ //一番下から始めたい場合
	return p1.y != p2.y ? p1.y < p2.y : p1.x < p2.x;
}
//直線上の線分は除外するためにはいくつかの行をコメントアウトする必要があり
vector<point> convex_hull_graham_scan(vector<point> &Q){
	sort(Q.begin(),Q.end(),lessy_x);
	int n = Q.size();
	//if(n<=3) return Q;
	stack<point> S;
	point p0  = Q[0];
	vector<point> P;//Q[i]-Q[0]の形式で保存
	for(int i=1;i<n;i++) P.push_back(Q[i]-Q[0]);
	sort(P.begin(),P.end(),lessangle);
	//angle が　最後の部分だけ入れ替える (直線上の点を入れるため)
	int s = P.size()-1;//この行から
	double ang = P[P.size()-1].arg();
		for(int i=0;i<P.size();i++)if(P[i].arg() == ang) {
			s = i;
			break;		
		}
	reverse(P.begin()+s,P.end());//この行までコメントアウト
	P.push_back(point(0,0) );//
	S.push(point(0,0) );
	S.push(P[0]);
	for(int i=1;i<P.size();i++){
		point p = P[i];
		while(S.size()>=2 ){
			point top =  S.top();
			S.pop();
			point next_top = S.top();
				//(p-next_top)*(top-next_top)
			if(direction(next_top,top,p) <= 0){ //直線上の点を除外するにはこの行の等号を除く
				S.push(top);
				break;
			}		
		}
		S.push(p);
	}
	S.pop();
	vector<point> res;
	while(!S.empty()){
		point p = S.top();
		S.pop();
		res.push_back(p+p0);
	}
	reverse(res.begin(),res.end());
	return res;
}

bool compare_y(const point &p1,const point &p2){ //一番下から始めたい場合
	return p1.y < p2.y;
}
// [s,t)
double closest_pair_dac(vector<point> &P,int s,int t,double &res){//divide and conquer
	if(t-s<=1) return inf;
	if(t-s==2) {
		 sort(P.begin()+s,P.begin()+t,lessy_x);
		return (P[s]-P[s+1]).abs();
	}
	int mid = (s+t)/2;
	double x = P[mid].x;
	res = min( res,min( closest_pair_dac(P,s,mid,res ),closest_pair_dac(P,mid,t,res) ) );
	auto it = P.begin();
	auto its = it+s,itm = it+mid,itt = it + t;
	inplace_merge(its,itm,itt,lessy_x);
	vector<point> l,m,r;
	for(int i=s;i<t;i++){
		if(abs(P[i].x-x) >= res ) continue;
		if(P[i].x== x ){
			if(m.size()!=0) res = min(res,(P[i]-m[m.size()-1]).abs() );
			for(int j=l.size()-1;j>=0;j--) {
				point d = P[i]-l[j];
				if(d.y >= res ) break;
				res = min(res,d.abs());
			}
			for(int j=r.size()-1;j>=0;j--) {
				point d = P[i]-r[j];
				if(d.y >= res ) break;
				res = min(res,d.abs());
			}
			m.push_back(P[i]);
		}
		else if(P[i].x > x && P[i].x <= x+res ) {
			if(m.size()!=0) res = min(res,(P[i]-m[m.size()-1]).abs() );
			for(int j=l.size()-1;j>=0;j--) {
				point d = P[i]-l[j];
				if(d.y >= res ) break;
				res = min(res,d.abs());
			}
			r.push_back(P[i]);
		}
		else if(P[i].x < x && P[i].x >= x-res ){
			if(m.size()!=0) res = min(res,(P[i]-m[m.size()-1]).abs() );
			for(int j=r.size()-1;j>=0;j--) {
				point d = P[i]-r[j];
				if(d.y >= res ) break;
				res = min(res,d.abs());
			}
			l.push_back(P[i] ); 
		}
	}
	
	return res;
}
double closest_pair(vector<point> &P){
	double res = inf;
	sort(P.begin(),P.end());
	int n = P.size();
	return closest_pair_dac(P,0,n,res);
}

int main(){
	int n;
	cin>>n;
	vector<point> P(n);
	for(int i=0;i<n;i++)P[i].make();
	double res = closest_pair(P);
	printf("%d\n",(int)(res*res+0.01) );
	return 0;
}


Measured memory_bytes: 22452