def calslope(x1, y1, x2, y2):
slope_string = ””
if (x2 - x1 == 0):
slope_string = ’INF’
elif(y2 - y1 == 0):
slope_string = ’0′
else :
frac = Fraction(y2 - y1, x2 - x1)
sign = ’+’
if frac.numerator < 0:
sign = ’-‘
slope_string = sign + ‘ | ’+str(abs(frac.numerator)) + ‘ | ’+str(abs(frac.denominator))
return slope_string
def caldistance(x1, y1, x2, y2):
return str(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1)))
def calintercepts(x1, y1, x2, y2):
s_y = y2 - y1
s_x = x2 - x1
intercept_string = ”
if s_y == 0:
intercept_string = ’+ | ’+str(abs(y1)) + ‘#INF’
if y1 < 0:
intercept_string = ’- | ’+str(abs(y1)) + ‘#INF’
elif s_x == 0:
intercept_string = ’INF# + ’ +str(abs(x1))
if x1 < 0:
intercept_string = ’INF# - ‘ +str(abs(x1))
else :
slope = Fraction(s_y, s_x)
c = Fraction((slope.denominator * y1 - slope.numerator * x1), slope.denominator)
y_intercept = c
x_intercept = Fraction(-1 * c.numerator * slope.denominator, c.denominator * slope.numerator)
y_int_string = ”
sign = ‘+’
if y_intercept.numerator < 0:
sign = ’-‘
y_int_string = sign + ‘ | ’+str(abs(y_intercept.numerator)) + ’ | ’+str(abs(y_intercept.denominator))
x_int_string = ”
sign = ‘+’
if x_intercept.numerator < 0:
sign = ’-‘
x_int_string = sign + ‘ | ’+str(abs(x_intercept.numerator)) + ’ | ’+str(abs(x_intercept.denominator))
intercept_string = y_int_string + ‘#’ +x_int_string
return intercept_string
def parsepoints(n, point_x, point_y):
#for i in range(0, n): #print point_x[i], point_y[i]
MAP = {}
for i in range(0, n - 1):
for j in range(i + 1, n):
a = point_x[i]
b = point_y[i]
c = point_x[j]
d = point_y[j]
mapstring = calslope(a, b, c, d) + ‘#’ +caldistance(a, b, c, d) + ‘#’ +calintercepts(a, b, c, d)
if mapstring in MAP:
MAP[mapstring].append(i)
MAP[mapstring].append(j)
else :
MAP[mapstring] = []
MAP[mapstring].append(i)
MAP[mapstring].append(j)
ans = 2
for ms in MAP:
points = MAP[ms]
points = list(set(points))# print len(points)
arr = list()
for i in range(0, len(points)):
p = list()
p.append(point_x[points[i]])
p.append(point_y[points[i]])
arr.append(p)
arr.sort(key = lambda k: [k[0], k[1]])
d = caldistance(arr[0][0], arr[0][1], arr[1][0], arr[1][1])
count = 2
for i in range(1, len(arr) - 1):
dnew = caldistance(arr[i][0], arr[i][1], arr[i + 1][0], arr[i + 1][1])
if dnew == d:
count = count + 1
ans = max(ans, count)
else :
d = dnew
count = 2
print ans
if ans > 3:
return ans
else :
return 0
return ans
n = raw_input()
point_x = list()
point_y = list()
for i in range(0, int(n)):
s = raw_input()
x = s.split(“#”)[0]
y = s.split(“#”)[1]
point_x.append(int(x))
point_y.append(int(y))
print parsepoints(int(n), point_x, point_y)
ZGVmIGNhbHNsb3BlKHgxLCB5MSwgeDIsIHkyKToKICBzbG9wZV9zdHJpbmcgPSDigJ3igJ0KCiAgaWYgKHgyIC0geDEgPT0gMCk6CiAgICBzbG9wZV9zdHJpbmcgPSDigJlJTkbigJkKZWxpZih5MiAtIHkxID09IDApOgogIHNsb3BlX3N0cmluZyA9IOKAmTDigLIKZWxzZSA6CiAgZnJhYyA9IEZyYWN0aW9uKHkyIC0geTEsIHgyIC0geDEpCgpzaWduID0g4oCZK+KAmQogIGlmIGZyYWMubnVtZXJhdG9yIDwgMDoKICBzaWduID0g4oCZLeKAmAoKICBzbG9wZV9zdHJpbmcgPSBzaWduICsg4oCYIHwg4oCZK3N0cihhYnMoZnJhYy5udW1lcmF0b3IpKSArIOKAmCB8IOKAmStzdHIoYWJzKGZyYWMuZGVub21pbmF0b3IpKQpyZXR1cm4gc2xvcGVfc3RyaW5nCgpkZWYgY2FsZGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpOgoKICByZXR1cm4gc3RyKCgoeTIgLSB5MSkgKiAoeTIgLSB5MSkpICsgKCh4MiAtIHgxKSAqICh4MiAtIHgxKSkpCgpkZWYgY2FsaW50ZXJjZXB0cyh4MSwgeTEsIHgyLCB5Mik6CiAgc195ID0geTIgLSB5MQpzX3ggPSB4MiAtIHgxCmludGVyY2VwdF9zdHJpbmcgPSDigJ0KCiAgaWYgc195ID09IDA6CiAgaW50ZXJjZXB0X3N0cmluZyA9IOKAmSsgfCDigJkrc3RyKGFicyh5MSkpICsg4oCYI0lORuKAmQppZiB5MSA8IDA6CiAgaW50ZXJjZXB0X3N0cmluZyA9IOKAmS0gfCDigJkrc3RyKGFicyh5MSkpICsg4oCYI0lORuKAmQoKZWxpZiBzX3ggPT0gMDoKICBpbnRlcmNlcHRfc3RyaW5nID0g4oCZSU5GIyArIOKAmSArc3RyKGFicyh4MSkpCmlmIHgxIDwgMDoKICBpbnRlcmNlcHRfc3RyaW5nID0g4oCZSU5GIyAtIOKAmCArc3RyKGFicyh4MSkpCgplbHNlIDoKICBzbG9wZSA9IEZyYWN0aW9uKHNfeSwgc194KQpjID0gRnJhY3Rpb24oKHNsb3BlLmRlbm9taW5hdG9yICogeTEgLSBzbG9wZS5udW1lcmF0b3IgKiB4MSksIHNsb3BlLmRlbm9taW5hdG9yKQp5X2ludGVyY2VwdCA9IGMKeF9pbnRlcmNlcHQgPSBGcmFjdGlvbigtMSAqIGMubnVtZXJhdG9yICogc2xvcGUuZGVub21pbmF0b3IsIGMuZGVub21pbmF0b3IgKiBzbG9wZS5udW1lcmF0b3IpCgp5X2ludF9zdHJpbmcgPSDigJ0KICBzaWduID0g4oCYK+KAmQogIGlmIHlfaW50ZXJjZXB0Lm51bWVyYXRvciA8IDA6CiAgc2lnbiA9IOKAmS3igJgKICB5X2ludF9zdHJpbmcgPSBzaWduICsg4oCYIHwg4oCZK3N0cihhYnMoeV9pbnRlcmNlcHQubnVtZXJhdG9yKSkgKyDigJkgfCDigJkrc3RyKGFicyh5X2ludGVyY2VwdC5kZW5vbWluYXRvcikpCgp4X2ludF9zdHJpbmcgPSDigJ0KICBzaWduID0g4oCYK+KAmQogIGlmIHhfaW50ZXJjZXB0Lm51bWVyYXRvciA8IDA6CiAgc2lnbiA9IOKAmS3igJgKICB4X2ludF9zdHJpbmcgPSBzaWduICsg4oCYIHwg4oCZK3N0cihhYnMoeF9pbnRlcmNlcHQubnVtZXJhdG9yKSkgKyDigJkgfCDigJkrc3RyKGFicyh4X2ludGVyY2VwdC5kZW5vbWluYXRvcikpCgppbnRlcmNlcHRfc3RyaW5nID0geV9pbnRfc3RyaW5nICsg4oCYI+KAmSAreF9pbnRfc3RyaW5nCnJldHVybiBpbnRlcmNlcHRfc3RyaW5nCgpkZWYgcGFyc2Vwb2ludHMobiwgcG9pbnRfeCwgcG9pbnRfeSk6CgogICNmb3IgaSBpbiByYW5nZSgwLCBuKTogI3ByaW50IHBvaW50X3hbaV0sIHBvaW50X3lbaV0KCk1BUCA9IHt9CmZvciBpIGluIHJhbmdlKDAsIG4gLSAxKToKICBmb3IgaiBpbiByYW5nZShpICsgMSwgbik6CiAgYSA9IHBvaW50X3hbaV0KYiA9IHBvaW50X3lbaV0KYyA9IHBvaW50X3hbal0KZCA9IHBvaW50X3lbal0KCm1hcHN0cmluZyA9IGNhbHNsb3BlKGEsIGIsIGMsIGQpICsg4oCYI+KAmSArY2FsZGlzdGFuY2UoYSwgYiwgYywgZCkgKyDigJgj4oCZICtjYWxpbnRlcmNlcHRzKGEsIGIsIGMsIGQpCgppZiBtYXBzdHJpbmcgaW4gTUFQOgogIE1BUFttYXBzdHJpbmddLmFwcGVuZChpKQpNQVBbbWFwc3RyaW5nXS5hcHBlbmQoaikKZWxzZSA6CiAgTUFQW21hcHN0cmluZ10gPSBbXQpNQVBbbWFwc3RyaW5nXS5hcHBlbmQoaSkKTUFQW21hcHN0cmluZ10uYXBwZW5kKGopCmFucyA9IDIKZm9yIG1zIGluIE1BUDoKICBwb2ludHMgPSBNQVBbbXNdCnBvaW50cyA9IGxpc3Qoc2V0KHBvaW50cykpIyBwcmludCBsZW4ocG9pbnRzKQphcnIgPSBsaXN0KCkKZm9yIGkgaW4gcmFuZ2UoMCwgbGVuKHBvaW50cykpOgogIHAgPSBsaXN0KCkKcC5hcHBlbmQocG9pbnRfeFtwb2ludHNbaV1dKQpwLmFwcGVuZChwb2ludF95W3BvaW50c1tpXV0pCmFyci5hcHBlbmQocCkKCmFyci5zb3J0KGtleSA9IGxhbWJkYSBrOiBba1swXSwga1sxXV0pCgpkID0gY2FsZGlzdGFuY2UoYXJyWzBdWzBdLCBhcnJbMF1bMV0sIGFyclsxXVswXSwgYXJyWzFdWzFdKQpjb3VudCA9IDIKZm9yIGkgaW4gcmFuZ2UoMSwgbGVuKGFycikgLSAxKToKICBkbmV3ID0gY2FsZGlzdGFuY2UoYXJyW2ldWzBdLCBhcnJbaV1bMV0sIGFycltpICsgMV1bMF0sIGFycltpICsgMV1bMV0pCmlmIGRuZXcgPT0gZDoKICBjb3VudCA9IGNvdW50ICsgMQphbnMgPSBtYXgoYW5zLCBjb3VudCkKZWxzZSA6CiAgZCA9IGRuZXcKY291bnQgPSAyCnByaW50IGFucwppZiBhbnMgPiAzOgogIHJldHVybiBhbnMKZWxzZSA6CiAgcmV0dXJuIDAKcmV0dXJuIGFucwoKbiA9IHJhd19pbnB1dCgpCnBvaW50X3ggPSBsaXN0KCkKcG9pbnRfeSA9IGxpc3QoKQpmb3IgaSBpbiByYW5nZSgwLCBpbnQobikpOgogIHMgPSByYXdfaW5wdXQoKQp4ID0gcy5zcGxpdCjigJwj4oCdKVswXQp5ID0gcy5zcGxpdCjigJwj4oCdKVsxXQpwb2ludF94LmFwcGVuZChpbnQoeCkpCnBvaW50X3kuYXBwZW5kKGludCh5KSkKCnByaW50IHBhcnNlcG9pbnRzKGludChuKSwgcG9pbnRfeCwgcG9pbnRfeSk=