def scc(N, G): order = [] used = [False]*N group = [None]*N RG = [[] for _ in range(N)] for i in range(N): for j in G[i]: RG[j].append(i) def dfs(pos): stack = [(1, pos), (0, pos)] while stack: t, pos = stack.pop() if t == 0: if used[pos]: stack.pop() continue used[pos] = True for npos in G[pos]: if not used[npos]: stack.append((1, npos)) stack.append((0, npos)) else: order.append(pos) def rdfs(pos, col): stack = [pos] group[pos] = col used[pos] = True while stack: pos = stack.pop() for npos in RG[pos]: if not used[npos]: used[npos] = True group[npos] = col stack.append(npos) for i in range(N): if not used[i]: dfs(i) used = [False]*N label = 0 for s in reversed(order): if not used[s]: rdfs(s, label) label += 1 return label, group class Two_SAT: def __init__(self, n): self.n = n self.G = [[] for _ in range(2 * n)] # a V B # neg_i = False -> a = i # neg_i = True -> a = ¬i def add_edge(self, i, j, neg_i, neg_j): i0 = i i1 = i + self.n if neg_i: i0, i1 = i1, i0 j0 = j j1 = j + self.n if neg_j: j0, j1 = j1, j0 self.G[i1].append(j0) self.G[j1].append(i0) def const(self): _, self.group = scc(2 * self.n, self.G) def check(self): for i in range(self.n): if self.group[i] == self.group[i + self.n]: return False return True def assign(self): ret = [False] * self.n for i in range(self.n): if self.group[i] > self.group[i + self.n]: ret[i] = True return ret N = 1000100 isprime = [True] * N isprime[0] = isprime[1] = False for i in range(2, int(N ** 0.5 + 1)): if not isprime[i]: continue for j in range(i * i, N, i): isprime[j] = False n = int(input()) ab = [input().split() for _ in range(n)] sat = Two_SAT(n) for i in range(n): ai, bi = ab[i] c1 = int(ai + bi) c2 = int(bi + ai) if not isprime[c1] and not isprime[c2]: pass elif not isprime[c1]: sat.add_edge(i, i, False, False) elif not isprime[c2]: sat.add_edge(i, i, True, True) else: print("No") exit() for j in range(i + 1, n): aj, bj = ab[j] f1 = (not isprime[int(ai + bj)]) and (not isprime[int(aj + bi)]) f2 = (not isprime[int(bi + bj)]) and (not isprime[int(aj + ai)]) f3 = (not isprime[int(ai + aj)]) and (not isprime[int(bj + bi)]) f4 = (not isprime[int(bi + aj)]) and (not isprime[int(bj + ai)]) cnt = f1 + f2 + f3 + f4 if cnt == 0: print("No") exit() elif cnt == 4: continue elif cnt == 3: if f1 and f3: t1 = False else: t1 = True if f1 and f2: t2 = False else: t2 = True sat.add_edge(i, j, t1, t2) elif cnt == 2: if f1 and f3: sat.add_edge(i, j, False, True) sat.add_edge(i, j, False, False) elif f2 and f4: sat.add_edge(i, j, True, True) sat.add_edge(i, j, True, False) elif f1 and f2: sat.add_edge(i, j, False, False) sat.add_edge(i, j, True, False) elif f3 and f4: sat.add_edge(i, j, False, True) sat.add_edge(i, j, True, True) elif f1 and f4: sat.add_edge(i, j, False, True) sat.add_edge(i, j, True, False) else: sat.add_edge(i, j, False, False) sat.add_edge(i, j, True, True) else: if f1: t1 = False t2 = False elif f2: t1 = True t2 = False elif f3: t1 = False t2 = True else: t1 = True t2 = True sat.add_edge(i, j, t1, t2) sat.add_edge(i, j, t1 ^ True, t2) sat.add_edge(i, j, t1, t2 ^ True) sat.const() if sat.check(): print("Yes") else: print("No")