using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("4 5 5");
WillReturn.Add("1 4");
WillReturn.Add("2 3");
WillReturn.Add("3 2");
WillReturn.Add("3 4");
WillReturn.Add("4 2");
//No
}
else if (InputPattern == "Input2") {
WillReturn.Add("2 7 3");
WillReturn.Add("1 2");
WillReturn.Add("2 4");
WillReturn.Add("1 6");
//Yes
}
else if (InputPattern == "Input3") {
WillReturn.Add("1 1 0");
//Yes
}
else if (InputPattern == "Input4") {
WillReturn.Add("10 12 20");
WillReturn.Add("8 3");
WillReturn.Add("1 11");
WillReturn.Add("6 4");
WillReturn.Add("3 7");
WillReturn.Add("10 4");
WillReturn.Add("5 7");
WillReturn.Add("4 7");
WillReturn.Add("5 5");
WillReturn.Add("4 3");
WillReturn.Add("6 1");
WillReturn.Add("1 6");
WillReturn.Add("2 7");
WillReturn.Add("6 7");
WillReturn.Add("1 3");
WillReturn.Add("6 3");
WillReturn.Add("2 12");
WillReturn.Add("9 6");
WillReturn.Add("7 3");
WillReturn.Add("3 11");
WillReturn.Add("9 7");
//Yes
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct XYInfoDef
{
internal long X;
internal long Y;
}
static List<XYInfoDef> mXYInfoList = new List<XYInfoDef>();
static long UB_X;
static long UB_Y;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
SplitAct(InputList[0]);
UB_X = wkArr[1] - 1;
UB_Y = wkArr[0] - 1;
var XYSet = new HashSet<long>();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
long X = wkArr[1] - 1;
long Y = wkArr[0] - 1;
XYInfoDef WillAdd;
WillAdd.X = X;
WillAdd.Y = Y;
mXYInfoList.Add(WillAdd);
long Hash = GetHash(X, Y);
XYSet.Add(Hash);
}
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
foreach (XYInfoDef EachXYInfo in mXYInfoList) {
if (EachXYInfo.X == UB_X || EachXYInfo.Y == 0) {
WillPush.CurrX = EachXYInfo.X;
WillPush.CurrY = EachXYInfo.Y;
Stk.Push(WillPush);
}
}
var VisitedSet = new HashSet<long>();
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
// クリア判定
if (Popped.CurrX == 0 || Popped.CurrY == UB_Y) {
Console.WriteLine("No");
return;
}
List<PointDef> KinbouList = Get8KinbouList(Popped.CurrX, Popped.CurrY);
foreach (PointDef EachPoint in KinbouList) {
long Hash = GetHash(EachPoint.X, EachPoint.Y);
if (XYSet.Contains(Hash) == false) {
continue;
}
if (VisitedSet.Add(Hash)) {
WillPush.CurrX = EachPoint.X;
WillPush.CurrY = EachPoint.Y;
Stk.Push(WillPush);
}
}
}
Console.WriteLine("Yes");
}
// 座標のハッシュ値
static long GetHash(long pX, long pY)
{
long Hash = 0;
Hash += pX * 100000000;
Hash += pY;
return Hash;
}
struct JyoutaiDef
{
internal long CurrX;
internal long CurrY;
}
struct PointDef
{
internal long X;
internal long Y;
}
// 8近傍の座標を返す
static List<PointDef> Get8KinbouList(long pX, long pY)
{
var WillReturn = new List<PointDef>();
WillReturn.AddRange(GetPoint(pX - 1, pY - 1));
WillReturn.AddRange(GetPoint(pX + 0, pY - 1));
WillReturn.AddRange(GetPoint(pX + 1, pY - 1));
WillReturn.AddRange(GetPoint(pX - 1, pY + 0));
WillReturn.AddRange(GetPoint(pX + 1, pY + 0));
WillReturn.AddRange(GetPoint(pX - 1, pY + 1));
WillReturn.AddRange(GetPoint(pX + 0, pY + 1));
WillReturn.AddRange(GetPoint(pX + 1, pY + 1));
return WillReturn;
}
static List<PointDef> GetPoint(long pTargetX, long pTargetY)
{
var WillReturn = new List<PointDef>();
if (pTargetX < 0 || UB_X < pTargetX) return WillReturn;
if (pTargetY < 0 || UB_Y < pTargetY) return WillReturn;
PointDef WillAdd;
WillAdd.X = pTargetX;
WillAdd.Y = pTargetY;
WillReturn.Add(WillAdd);
return WillReturn;
}
}