#! /usr/bin/env python3
# @EXPECTED_RESULTS@: ACCEPTED, TIME_LIMIT_EXCEEDED
# Just barely not optimized enough.

import sys
from collections import defaultdict

GRANULARITY = 211 # how coarse is the grid? I'm thinking 211 > 80 + 80 + 2 * 25.4 should be enough
import time
start_time = time.time()

N = int(input())

models = tuple(tuple(map(int, input().split())) for _ in range(N))

def close(this, that):
    return ((this[0] - that[0]) ** 2 + (this[1] - that[1]) ** 2)*100 <= (2*254 + 5*(this[2] + that[2])) ** 2

models_for_bucket = defaultdict(list)
for i, m in enumerate(models):
    x, y, diam = m
    models_for_bucket[x//GRANULARITY, y//GRANULARITY] += [(x, y, diam)]
print("parsed", time.time() - start_time, file=sys.stderr)
edges = defaultdict(set)
for x_, y_ in models_for_bucket:
    M = set()
    for dx in [-1, 0, 1]:
        for dy in [-1, 0, 1]:
            if (x_ + dx, y_ + dy) in models_for_bucket:
                M.update(models_for_bucket[x_ + dx, y_ + dy])
    for a in models_for_bucket[x_, y_]:
        edges[a].update([b for b in M if a != b and close(a,b)])
print("bucketed", time.time() - start_time, file=sys.stderr)
start = models[0] # arbitrary model
Q = [start]
marked = set([start])
while Q:
    R = []
    for u in Q:
        for v in edges[u]:
            if v in marked:
                continue
            R.append(v)
            marked.add(v)
    Q = R
connected = len(marked) == N
print(connected, file=sys.stderr)
print("done", time.time() - start_time, file=sys.stderr)
if N <= 6:
    print("yes" if connected else "no")
else:
    print("yes" if (connected and min(len(l) for l in edges.values()) >= 2) else "no")
