#!/usr/bin/env PyPy3 from collections import Counter, defaultdict, deque import itertools import re import math from functools import reduce import operator import bisect from heapq import * import functools import typing mod=998244353 import sys input = sys.stdin.readline import typing class SCC: def __init__(self, N): self.N = N self.edges = [] def csr(self): start = [0]*(self.N+1) elist = [0]*len(self.edges) for v, w in self.edges: start[v+1] += 1 for i in range(1, self.N+1): start[i] += start[i-1] counter = start.copy() for v, w in self.edges: elist[counter[v]] = w counter[v] += 1 self.start = start self.elist = elist def add_edge(self, v, w): self.edges.append((v, w)) def scc_ids(self): self.csr() N = self.N now_ord = group_num = 0 visited = [] low = [0]*N order = [-1]*N ids = [0]*N parent = [-1]*N stack = [] for i in range(N): if order[i] == -1: stack.append(~i) stack.append(i) while stack: v = stack.pop() if v >= 0: if order[v] == -1: low[v] = order[v] = now_ord now_ord += 1 visited.append(v) for i in range(self.start[v], self.start[v+1]): to = self.elist[i] if order[to] == -1: stack.append(~to) stack.append(to) parent[to] = v else: low[v] = min(low[v], order[to]) else: v = ~v if low[v] == order[v]: while True: u = visited.pop() order[u] = N ids[u] = group_num if u == v: break group_num += 1 if parent[v] != -1: low[parent[v]] = min(low[parent[v]], low[v]) for i, x in enumerate(ids): ids[i] = group_num - 1 - x return group_num, ids def scc(self): group_num, ids = self.scc_ids() groups = [[] for _ in range(group_num)] for i, x in enumerate(ids): groups[x].append(i) return groups class TwoSAT: def __init__(self, N): self.N = N self._answer = [0] * N self.scc = SCC(2 * N) def add_clause(self, i, f, j, g): #f,g = 0/1 (True/False) # assert 0 <= i < self.N # assert 0 <= j < self.N self.scc.add_edge(2 * i + (0 if f else 1), 2 * j + (1 if g else 0)) self.scc.add_edge(2 * j + (0 if g else 1), 2 * i + (1 if f else 0)) def satisfiable(self): ids = self.scc.scc_ids()[1] for i in range(self.N): if ids[2 * i] == ids[2 * i + 1]: #self.answer.clear() return False self._answer[i] = ids[2 * i] < ids[2 * i + 1] return True def answer(self) -> typing.List[bool]: return self._answer def sieve(limit): if limit < 2: return [] # primep[n]==Trueのとき、(2 * n) + 1 が素数とする primep = [1] * ((limit - 1) // 2 + 1) primep[0] = 0 for num in range(1, int((limit ** 0.5) - 1) // 2 + 1): if primep[num]: p = 2 * num + 1 for i in range(num + p, len(primep), p): primep[i] = 0 return [2] + [2 * p + 1 for p in range(len(primep)) if primep[p]] primes = set(sieve(1000000)) n = int(input()) ab = [list(map(int,input().split())) for _ in range(n)] twosat = TwoSAT(n) def check(a,b): return a * 10 ** (len(str(b))) + b in primes for i in range(n): a,b = ab[i] for j in range(n): c,d = ab[j] if check(a,d) or check(c,b): twosat.add_clause(i,1,j,1) if check(a,c) or check(d,b): twosat.add_clause(i,1,j,0) if check(b,d) or check(c,a): twosat.add_clause(i,0,j,1) if check(b,c) or check(d,a): twosat.add_clause(i,0,j,0) if twosat.satisfiable(): print('Yes') else: print('No')