#include <stdio.h>
#include <stdlib.h>

#define InX 1
#define InY 2
#define true 1
#define false 0
#define MaxPoints 5000
int NumPoints,HalfPoints,BigX;
int Net[MaxPoints][MaxPoints];
int CoordX[MaxPoints],CoordY[MaxPoints];
double PX[MaxPoints],PY[MaxPoints];
int MinX,MinY;
double MinLength;
  int i,j,x,y;
  int Umax,Umin,Pmax,Pmin;

void ReadInput(void)
{
  int i;
  FILE *f;
  f=fopen("g.in","r");
  if (f==NULL) 
  {
     printf("No input files\n");
     exit(0);
  }
  fscanf(f," %i ",&NumPoints); 
  HalfPoints=(NumPoints/2)+(NumPoints % 2);
  for (i=1;i<=NumPoints;i++)
  {
     fscanf(f," %lf %lf ",&PX[i],&PY[i]);
     CoordX[i]=CoordY[i]=i;
  }
  fclose(f);
}

int CompareX(const void *p1,const void *p2)
{
  int *first,*sec;
  first=(int *)p1;
  sec=(int *)p2;
  if (PX[*first]<PX[*sec]) return -1;
  if (PX[*first]==PX[*sec]) return 0;
  return 1;
}

int CompareY(const void *p1,const void *p2)
{
  int *first,*sec;
  first=(int *)p1;
  sec=(int *)p2;
  if (PY[*first]<PY[*sec]) return -1;
  if (PY[*first]==PY[*sec]) return 0;
  return 1;
}

int FindY(double f)
{
  int min=1,max=NumPoints;
  int str;

  if (PY[CoordY[NumPoints]]<f) return -1;
  if (PY[CoordY[1]]>f) return 1;
  
  while (PY[CoordY[min]]<f && f<PY[CoordY[max]]) 
  {
    str=(max-min)/2 + min;
    if (PY[CoordY[str]]==f) { return str; }
    if (PY[CoordY[str]]>f) 
    {
      max=str; 
    } 
    else // if (PY[str]<f)
    {
      min=str; 
      if (min==max)   { return -1; }  
      if (min+1==max) return max;
      if (min+2==max)
      {
        if (PY[CoordY[min+1]]>=f) return min+1;
	min=min+1;
      }   
    }
  }
  if (PY[CoordY[min]]==f) return min;
  return max;
}

int NumberOfPointsX(int x1,int y1,int x2)
{
  double f;
  int y2,Number;
  f=PX[CoordX[x2]]-PX[CoordX[x1]]+PY[CoordY[y1]];
  y2=FindY(f);
  if (y2==-1) y2=NumPoints;
  if (PY[CoordY[y2]]>f) y2--;
  Number=Net[x2][y2]-Net[x1-1][y2]-Net[x2][y1-1]+Net[x1-1][y1-1];
  return Number;
}

int NumberOfPointsY(int x1,int y1,int y2) 
{
  int Number;
  int x2=BigX;
  Number=Net[x2][y2]-Net[x1-1][y2]-Net[x2][y1-1]+Net[x1-1][y1-1];
  return Number;
}

void GotIt(int x,int y,double f)
{
  //printf("%lf %lf\n%lf %lf %lf\n",PX[CoordX[x]],PY[CoordY[y]],PX[CoordX[x]]+f,PY[CoordY[y]]+f,f);
  printf("%lf %lf\n%lf %lf \n",PX[CoordX[x]],PY[CoordY[y]],PX[CoordX[x]]+f,PY[CoordY[y]]+f);
  exit(0);
}

void BinarySearch(int x,int y,int *PPmin,int *PPmax,int *PUmin,int *PUmax,int where)
{
  int Cont;
  int Umax,Umin,Ustr,Pmax,Pmin,Pstr,Pnew;
  Pmin=*PPmin; Pmax=*PPmax; Umin=*PUmin; Umax=*PUmax;
  Cont=true; 
  switch (where)
  {
    case InX: Pmax=NumberOfPointsX(x,y,Umax);        
              Pmin=NumberOfPointsX(x,y,Umin);
	      break; 
    case InY: Pmax=NumberOfPointsY(x,y,Umax);        
              Pmin=NumberOfPointsY(x,y,Umin);
	      break; 
  }
  while (Pmax>=HalfPoints && HalfPoints>Pmin && Cont)
  {
    Cont=false;
    Ustr=(Umax-Umin)/2 + Umin;
    switch (where)
    {
      case InX: Pstr=NumberOfPointsX(x,y,Ustr); break;
      case InY: Pstr=NumberOfPointsY(x,y,Ustr); break;
    }  
    if (Pstr>=HalfPoints) { Cont=true; Pmax=Pstr; Umax=Ustr;}
    if (Pstr<HalfPoints) 
    { 
      if (Ustr==Umin)
      {
        switch (where)
        {
           case InX:  Pnew=NumberOfPointsX(x,y,Umin+1); break;
           case InY:  Pnew=NumberOfPointsY(x,y,Umin+1); break;
		}  
        if (Pnew>HalfPoints) {Pmax=Pnew; Umax=Umin+1; Cont=false;}    
        if (Pnew<=HalfPoints) 
		{
	      switch (where)
          {
		    case InX:
				if (Umin+1==Umax) {Cont=false;}
				else {Pmin=Pnew; Umin=Umin+1; Cont=false;}
				break;
            case InY: 
			  Pmin=Pnew; Umin=Umin+1; Cont=false; break;
          }
		}
      } else { Cont=true; Pmin=Pstr; Umin=Ustr; }
    }
  } //while (Pmax>=HalfPoints && HalfPoints>Pmin && Cont && !OK)        
  *PPmin=Pmin; *PPmax=Pmax; *PUmin=Umin; *PUmax=Umax;
}

main()
{
   
  ReadInput();
  qsort((void *)CoordX,(size_t)NumPoints+1,sizeof(int),CompareX);        
  qsort((void *)CoordY,(size_t)NumPoints+1,sizeof(int),CompareY);        
  for (i=0;i<=NumPoints;i++) Net[i][0]=Net[0][i]=0;
  for (i=1;i<=NumPoints;i++)
  for (j=1;j<=NumPoints;j++)
  {
    Net[i][j]=Net[i-1][j]+Net[i][j-1]-Net[i-1][j-1];
    if (CoordX[i]==CoordY[j]) Net[i][j]++;     

  }
  MinLength=PX[CoordX[NumPoints]];
  if (MinLength<PY[CoordY[NumPoints]]) MinLength=PY[CoordY[NumPoints]];

  for(x=1;x<=NumPoints;x++)
  for(y=1;y<=NumPoints;y++)
  {
    Umax=NumPoints; Umin=x;
    BinarySearch(x,y,&Pmin,&Pmax,&Umin,&Umax,InX);
    if (Pmin>=HalfPoints && MinLength>PX[CoordX[Umin]]-PX[CoordX[x]])
    {
       MinLength=PX[CoordX[Umin]]-PX[CoordX[x]]; MinX=x; MinY=y;
    }
    else //if (Pmin<HalfPoints)
    {
      double f;
      if (Pmax>=HalfPoints) //<>
      {
        BigX=Umin;
        if (Pmax==HalfPoints && MinLength>PX[CoordX[Umax]]-PX[CoordX[x]]) 
        {
           MinLength=PX[CoordX[Umax]]-PX[CoordX[x]]; MinX=x; MinY=y;
        }
        f=PX[CoordX[Umin]]-PX[CoordX[x]]+PY[CoordY[y]]; 
        Umin=FindY(f);
	if (Umin==-1) Umin=NumPoints;
	Umin=Umin-1;
	if (Umin<1) Umin=1;
        f=PX[CoordX[Umax]]-PX[CoordX[x]]+PY[CoordY[y]];
	Umax=FindY(f);
	if (Umax==-1) Umax=NumPoints; 
	BinarySearch(x,y,&Pmin,&Pmax,&Umin,&Umax,InY);    
        if (Pmin==HalfPoints && MinLength>PY[CoordY[Umin]]-PY[CoordY[y]])
        {
           MinLength=PY[CoordY[Umin]]-PY[CoordY[y]]; MinX=x; MinY=y;
        }
      }	
      else
      if (Pmax<HalfPoints) 
      {
        BigX=NumPoints;
        f=PX[CoordX[Umax]]-PX[CoordX[x]]+PY[CoordY[y]]; 
		Umin=FindY(f);
		if (Umin==-1) Umin=NumPoints;
		Umin=Umin-1;
		if (Umin<1) Umin=1;
		Umax=NumPoints;
        BinarySearch(x,y,&Pmin,&Pmax,&Umin,&Umax,InY);    
        if (Pmin>=HalfPoints && MinLength>PY[CoordY[Umin]]-PY[CoordY[y]])
        {
           MinLength=PY[CoordY[Umin]]-PY[CoordY[y]]; MinX=x; MinY=y;
        }
      }	
    }
  }
  GotIt(MinX,MinY,MinLength);
}
