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("5 5 2");
WillReturn.Add("1 3 0");
WillReturn.Add("2 3 1");
WillReturn.Add("5 4 1");
WillReturn.Add("2 1 1");
WillReturn.Add("1 4 0");
WillReturn.Add("3 4");
//5
}
else if (InputPattern == "Input2") {
WillReturn.Add("4 4 2");
WillReturn.Add("4 3 0");
WillReturn.Add("1 2 1");
WillReturn.Add("1 2 0");
WillReturn.Add("2 1 1");
WillReturn.Add("2 4");
//-1
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int mGoalNode;
static int mEdgeCnt;
static int mSwitchCnt;
// 隣接リスト
static Dictionary<int, List<int>> mToNodeListDict0 = new Dictionary<int, List<int>>();
static Dictionary<int, List<int>> mToNodeListDict1 = new Dictionary<int, List<int>>();
static HashSet<int> mSSet = new HashSet<int>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
SplitAct(InputList[0]);
mGoalNode = wkArr[0];
mEdgeCnt = wkArr[1];
mSwitchCnt = wkArr[2];
foreach (string EachStr in InputList.Skip(1).Take(mEdgeCnt)) {
SplitAct(EachStr);
int FromNode = wkArr[0];
int ToNode = wkArr[1];
Dictionary<int, List<int>> WorkPointer;
if (wkArr[2] == 0) {
WorkPointer = mToNodeListDict0;
}
else {
WorkPointer = mToNodeListDict1;
}
if (WorkPointer.ContainsKey(FromNode) == false) {
WorkPointer[FromNode] = new List<int>();
}
if (WorkPointer.ContainsKey(ToNode) == false) {
WorkPointer[ToNode] = new List<int>();
}
WorkPointer[FromNode].Add(ToNode);
WorkPointer[ToNode].Add(FromNode);
}
if (mSwitchCnt >= 1) {
int[] SArr = InputList.Last().Split(' ').Select(pX => int.Parse(pX)).ToArray();
mSSet.UnionWith(SArr);
}
Exec01BFS();
}
struct JyoutaiDef
{
internal int CurrNode;
internal int Level;
internal bool UseEdge1;
}
static void Exec01BFS()
{
var InsLinkedList = new LinkedList<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.CurrNode = 1;
WillEnqueue.Level = 0;
WillEnqueue.UseEdge1 = true;
InsLinkedList.AddFirst(WillEnqueue);
int Answer = int.MaxValue;
bool FoundAnswer = false;
var VisitedSet = new HashSet<int>();
while (InsLinkedList.Count > 0) {
JyoutaiDef Dequeued = InsLinkedList.First();
InsLinkedList.RemoveFirst();
if (Dequeued.CurrNode == mGoalNode) {
FoundAnswer = true;
Answer = Math.Min(Answer, Dequeued.Level);
break;
}
Action<int, int, bool, bool> EnqueueAct = (pCurrNode, pLevel, pUseEdge1, pAddFirst) =>
{
WillEnqueue.CurrNode = pCurrNode;
WillEnqueue.Level = pLevel;
WillEnqueue.UseEdge1 = pUseEdge1;
int Hash = GetHash(WillEnqueue);
if (VisitedSet.Add(Hash) == false) {
return;
}
if (pAddFirst) {
InsLinkedList.AddFirst(WillEnqueue);
}
else {
InsLinkedList.AddLast(WillEnqueue);
}
};
// スイッチを押す
if (mSSet.Contains(Dequeued.CurrNode)) {
EnqueueAct(Dequeued.CurrNode, Dequeued.Level, Dequeued.UseEdge1 == false, true);
}
// 移動する
Dictionary<int, List<int>> WorkPointer;
if (Dequeued.UseEdge1 == false) {
WorkPointer = mToNodeListDict0;
}
else {
WorkPointer = mToNodeListDict1;
}
if (WorkPointer.ContainsKey(Dequeued.CurrNode)) {
foreach (int EachToNode in WorkPointer[Dequeued.CurrNode]) {
EnqueueAct(EachToNode, Dequeued.Level + 1, Dequeued.UseEdge1, false);
}
}
}
if (FoundAnswer) {
Console.WriteLine(Answer);
}
else {
Console.WriteLine(-1);
}
}
static int GetHash(JyoutaiDef pJyoutai)
{
return pJyoutai.CurrNode * 10 + (pJyoutai.UseEdge1 ? 1 : 0);
}
}