import java.util.*;

import java.lang.*;

import java.io.*;

import java.util.StringTokenizer;

class KDNode

{

int axis;

double[] x;

int id;

boolean checked;

boolean orientation;

KDNode Parent;

KDNode Left;

KDNode Right;

public KDNode(double[] x0, int axis0)

{

x = new double[2];

axis = axis0;

for(int k=0; k<2; k++)

x[k] = x0[k];

Left = Right = Parent = null;

checked = false;

id = 0;

}

public KDNode FindParent(double[] x0)

{

KDNode parent=null;

KDNode next = this;

int split;

while(next!=null)

{

split = next.axis ;

parent = next;

if(x0[split] > next.x[split])

next = next.Right;

else

next = next.Left;

}

return parent;

}

public KDNode Insert(double[] p)

{

x = new double[2];

KDNode parent = FindParent(p);

if(equal(p, parent.x, 2)==true)

return null;

KDNode newNode = new KDNode(p, parent.axis +1 < 2? parent.axis+1:0);

newNode.Parent = parent;

if(p[parent.axis] > parent.x[parent.axis])

{

parent.Right = newNode;

newNode.orientation = true;//

}

else

{

parent.Left = newNode;

newNode.orientation = false;//

}

return newNode;

}

boolean equal(double[] x1, double[] x2, int dim)

{

for(int k=0; k < dim; k++)

{

if(x1[k] != x2[k])

return false;

}

return true;

}

double distance2(double[] x1, double[] x2, int dim)

{

double S = 0;

for(int k=0; k < dim; k++)

S+= (x1[k]-x2[k])*(x1[k]-x2[k]);

return S;

}

};

class KDTree

{

KDNode Root;

int TimeStart, TimeFinish;

int CounterFreq;

double d_min;

KDNode nearest_neighbour;

int KD_id;

int nList;

KDNode CheckedNodes[];

int checked_nodes;

KDNode List[];

double x_min[], x_max[];

boolean max_boundary[], min_boundary[];

int n_boundary;

public KDTree(int i)

{

Root = null;

KD_id = 1;

nList = 0;

List = new KDNode[i];

CheckedNodes = new KDNode[i];

max_boundary = new boolean[2];

min_boundary = new boolean[2];

x_min = new double[2];

x_max = new double[2];

}

public boolean add(double[] x)

{

if(nList >= 2000000-1)

return false; //can’t add more points

if(Root==null)

{

Root = new KDNode(x,0);

Root.id = KD_id++;

List[nList++] = Root;

}

else

{

KDNode pNode;

if((pNode=Root.Insert(x))!=null)

{

pNode.id = KD_id++;

List[nList++] = pNode;

}

}

return true;

}

public KDNode find_nearest(double[] x)

{

if(Root==null)

return null;

checked_nodes = 0;

KDNode parent = Root.FindParent(x);

nearest_neighbour = parent;

d_min = Root.distance2(x, parent.x, 2);

if(parent.equal(x, parent.x, 2)==true)

return nearest_neighbour;

search_parent(parent, x);

uncheck();

return nearest_neighbour;

}

public void check_subtree(KDNode node, double[] x)

{

if((node==null) || node.checked)

return;

CheckedNodes[checked_nodes++] = node;

node.checked = true;

set_bounding_cube(node, x);

int dim = node.axis;

double d= node.x[dim]-x[dim];

if (d*d > d_min) {

if (node.x[dim] > x[dim])

check_subtree(node.Left, x);

else

check_subtree(node.Right, x);

}

else {

check_subtree(node.Left, x);

check_subtree(node.Right, x);

}

}

public void set_bounding_cube(KDNode node, double[] x)

{

if(node==null)

return;

int d=0;

double dx;

for(int k=0; k<2; k++)

{

dx = node.x[k]-x[k];

if(dx > 0)

{

dx *= dx;

if(!max_boundary[k])

{

if(dx > x_max[k])

x_max[k] = dx;

if(x_max[k]>d_min)

{

max_boundary[k] =true;

n_boundary++;

}

}

}

else

{

dx *= dx;

if(!min_boundary[k])

{

if(dx > x_min[k])

x_min[k] = dx;

if(x_min[k]>d_min)

{

min_boundary[k] =true;

n_boundary++;

}

}

}

d+=dx;

if(d>d_min)

return;

}

if(d<d_min)

{

d_min = d;

nearest_neighbour = node;

}

}

public KDNode search_parent(KDNode parent, double[] x)

{

for(int k=0; k<2; k++)

{

x_min[k] = x_max[k] = 0;

max_boundary[k] = min_boundary[k] = false;//

}

n_boundary = 0;

double dx;

KDNode search_root = parent;

while(parent!=null && (n_boundary != 2*2))

{

check_subtree(parent, x);

search_root = parent;

parent = parent.Parent;

}

return search_root;

}

public void uncheck()

{

for(int n=0; n<checked_nodes; n++)

CheckedNodes[n].checked = false;

}

}

public class KDTNearest

{

public static void main(String args[]) throws IOException

{

BufferedReader in = new BufferedReader(new FileReader("input.txt"));

String strLin;

strLin = in.readLine();

StringTokenizer strLi = new StringTokenizer(strLin,"(,)");

int numpoints = Integer.parseInt(strLi.nextToken());

KDTree kdt = new KDTree(numpoints);

while(strLi.hasMoreTokens()) {

double x[] = new double[2];

for (int i = 0; i < numpoints; i++) {

x[0] = Double.parseDouble(strLi.nextToken());

x[1] = Double.parseDouble(strLi.nextToken());

kdt.add(x);

}

}

System.out.println("Enter the co-ordinates of the point:");

InputStreamReader reader = new InputStreamReader(System.in);

BufferedReader br = new BufferedReader(reader);

double sx = Double.parseDouble(br.readLine());

double sy = Double.parseDouble(br.readLine());

double s[] = {sx,sy};

KDNode kdn = kdt.find_nearest(s);

System.out.println("("+ kdn.x[0] +" , "+ kdn.x[1] + ")");

}

}