using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication20
{
    class Program
    {
        static void Main(string[] args)
        {
            reader = Console.In;
            writer = Console.Out;
            int n = ReadInt();
            var a = ReadIntArray();

            int c = 0;
            int ans = 0;

            foreach(int x in a)
            {

                if (x == -1)
                {
                    if (c == 0)
                        ans++;
                    else
                        c--;
                }
                else
                {
                    c += x;
                }
            }

            reader.Close();
            Console.WriteLine(ans);
            writer.Close();
        }

        private static Queue<string> currentLineTokens = new Queue<string>();
        protected static TextReader reader;
        protected static TextWriter writer;
        private static string[] ReadAndSplitLine()
        {
            return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            if (currentLineTokens.Count == 0)
                currentLineTokens = new Queue<string>(ReadAndSplitLine());
            return currentLineTokens.Dequeue();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication20
{
    class Program
    {
        static void Main(string[] args)
        {
            int amount = int.Parse(Console.ReadLine());
            var numbs = Console.ReadLine().Split(' ').Select(int.Parse).ToList();
            int pol = 0;
            int crimes = 0;
            bool flag = false;

            while (numbs[numbs.Count - 1] > 0)
                numbs.RemoveAt(numbs.Count - 1);

            while (numbs[0] < 0)
            {
                numbs.RemoveAt(0);
                crimes++;
            }
            for (int i = 0; i < numbs.Count; i ++)
            {
                if (numbs[i] > 0)
                    pol += numbs[i];
                else if (numbs[i] < 0)
                    pol--;
            }

            Console.WriteLine(pol > 0 ? crimes : (Math.Abs(pol) + crimes));
                Console.ReadLine();

        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication20
{
    class Program
    {
        static void Main(string[] args)
        {
            int amount = int.Parse(Console.ReadLine());
            var numbs = Console.ReadLine().Split(' ').Select(int.Parse).ToList();
            int pol = 0;
            int crimes = 0;
            bool flag = false;

            while (numbs[numbs.Count - 1] > 0)
                numbs.RemoveAt(numbs.Count - 1);

            for (int i = 0; i < numbs.Count; i ++)
            {
                if (numbs[i] > 0)
                    pol += numbs[i];
                else if (numbs[i] < 0)
                    pol--;
            }

            Console.WriteLine(pol > 0 ? 0 : Math.Abs(pol));
                Console.ReadLine();

        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication20
{
    class Program
    {
        static void Main(string[] args)
        {
            int amount = int.Parse(Console.ReadLine());
            var numbs = Console.ReadLine().Split(' ').Select(int.Parse).ToList();
            int pol = 0;
            int crimes = 0;
            bool flag = false;

            while (numbs[numbs.Count - 1] > 0 && numbs.Count > 1)
                numbs.RemoveAt(numbs.Count - 1);

            while (numbs[0] < 0 && numbs.Count > 1)
            {
                numbs.RemoveAt(0);
                crimes++;
            }

            for (int i = 0; i < numbs.Count; i ++)
            {
                if (numbs[i] > 0)
                    pol += numbs[i];
                else if (numbs[i] < 0)
                    pol--;
            }

            Console.WriteLine(pol > 0 ? crimes : (Math.Abs(pol) + crimes));
                Console.ReadLine();

        }
    }
}


using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace LongPath
{
    public class Problem427A
    {
        public static void Main(string[] args)
        {
            var input = int.Parse(Console.ReadLine());
            var data = Console.ReadLine().Split().Select(x => int.Parse(x)).ToArray();

            var police = 0;
            var untreatedCrimes = 0;

            for (int i = 0; i < input; i++)
            {
                if (data[i] == -1)
                {
                    if (police > 0)
                    {
                        --police;
                    }
                    else
                    {
                        ++untreatedCrimes;
                    }
                }
                else
                {
                    police += data[i];
                }
            }

            Console.WriteLine(untreatedCrimes);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpPrograms.Codeforces
{
    class _427A
    {
        static void Main()
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string[] temp = Console.ReadLine().Split();
            int[] arr = Array.ConvertAll(temp, x => Convert.ToInt32(x));
            int count = 0, police = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == -1)
                {
                    if (police != 0)
                        police--;
                    else
                        count++;
                }
                else
                    police += arr[i];
            }
            Console.WriteLine(count);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Training_App
{
    class Program
    {
        static void Main(string[] args)
        {
            int number = int.Parse(Console.ReadLine());
            String input = Console.ReadLine();
            List<int> values = new List<int>();
            String[] splits = input.Split(' ');
            for (int i = 0; i < number; i++)
            {
                values.Add(int.Parse(splits[i]));
            }

            int crimes = 0;
            int officers = 0;

            foreach(int value in values)
            {
                if(value<0&&officers==0)
                {
                    crimes++;
                }
                else if(value<0&&officers>0)
                {
                    officers--;
                }
                else
                {
                    officers += value;
                }
            }

            Console.WriteLine(crimes);

        }
    }
}


using System;

class A427 {
    public static void Main() {
        var n = int.Parse(Console.ReadLine());
        var a = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
        int c = 0, ans = 0;
        for (int i = 0; i < n; ++i) {
            c += a[i];
            if (c < 0) { ans -= c; c = 0; }
        }
        Console.WriteLine(ans);
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Codeforces_244_A
{
    class Program
    {
        static void Main(string[] args)
        {
            int result = 0;
            int police = 0;
            int count= int.Parse(Console.ReadLine());
            string[] mass = Console.ReadLine().Split(' ');
            for(int i=0; i<count; i++)
            {
                switch (mass[i])
                {
                    case "-1":
                        if (police > 0)
                            police--;
                        else
                            result++;
                        break;
                    case "1":
                        police++;
                        break;
                }
            }
            Console.WriteLine(result);

        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Codeforces_244_A
{
    class Program
    {
        static void Main(string[] args)
        {
            int result = 0;
            int police = 0;
            int count= int.Parse(Console.ReadLine());
            string[] mass = Console.ReadLine().Split(' ');
            for(int i=0; i<count; i++)
            {

                int value = int.Parse(mass[i]);
                if (value == -1)
                {
                    if (police > 0)
                        police--;
                    else
                        result++;
                }
                else
                {
                    police = police + value;
                }
            }
            Console.WriteLine(result);

        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization; // .ToString(new CultureInfo("en-US")));
using System.Text;

namespace Codeforces_244_2
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            int p = 0, ret = 0;
            foreach (string s in Console.ReadLine().Split(' '))
            {
                int e = int.Parse(s);
                if (-1 == e)
                {
                    if (0 < p)
                    {
                        --p;
                    }
                    else
                    {
                        ++ret;
                    }
                }
                else
                {
                    p += e;
                }
            }
            Console.WriteLine(ret);
        }
    }
}


using System;
using System.Linq;

namespace Test
{
    class Program
    {
        static void Main()
        {
            Console.ReadLine();
            sbyte[] inputs = Console.ReadLine().Split(' ').Select(x => Convert.ToSByte(x)).ToArray();
            int recruitedCount = 0;
            int untreatedCount = 0;

            foreach (sbyte input in inputs)
            {
                if (input == -1)
                {
                    if (recruitedCount > 0)
                        recruitedCount--;
                    else
                        untreatedCount++;
                }
                else
                    recruitedCount += input;
            }
            Console.WriteLine(untreatedCount);
        }
    }
}


using System;
using System.Linq;

namespace Police_Recruits
{
    class Program
    {
        static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());
            int[] row = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();

            int sum = 0, untreated = 0;
            for (int n = 0; n < N; n++)
            {
                if (row[n] == -1)
                {
                    if (sum <= 0)
                        untreated++;
                    else
                        sum += row[n];
                }
                else
                    sum += row[n];
            }

            //Console.WriteLine(untreated);

            //Console.ReadKey();
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Police_Recruits
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] lines = File.ReadAllLines("input.txt");
            int curLine = 0;
            int N = int.Parse(lines[curLine++]);
            int[] row = lines[curLine++].Split(' ').Select(int.Parse).ToArray();

            int officers = 0, untreated = 0;
            for (int n = 0; n < N; n++)
            {
                if (row[n] == -1)
                {
                    if (officers <= 0)
                        untreated++;
                    else
                        officers += row[n];
                }
                else
                    officers += row[n];
            }

            Console.WriteLine(untreated);

            Console.ReadKey();
        }
    }
}


#include<iostream>
#include <vector>
#include <queue>
#include <set>

using namespace std;

#define MAXN 3001
#define MAXM 20001

int id[MAXN][MAXN];
int e[2 * MAXM];

struct edge{
    int id,to;

    edge(){}
    edge(int _id, int _to):
        id(_id),to(_to){}
};

struct node{
    int id,pos,dist;

    node(){}
    node(int _id, int _pos, int _dist):
        id(_id),pos(_pos),dist(_dist){}
};

vector<edge> L[MAXN];
bool visited[2 * MAXM];
set< pair<int, int> > S;
int par[2 * MAXM];

int main(){
    int n,m,k;

   // scanf("%d %d %d",&N,&M,&K);
    cin>>n>>m>>k;
    for(int i = 0,u,v;i < m;++i){
        //scanf("%d %d",&u,&v);
        cin>>u>>v;
		id[u][v] = 2 * (i + 1) + 1;
        id[v][u] = 2 * (i + 1);

        e[2 * (i + 1)] = u;
        e[2 * (i + 1) + 1] = v;

        L[u].push_back(edge(2 * (i + 1) + 1,v));
        L[v].push_back(edge(2 * (i + 1),u));
    }

    for(int i = 0,a,b,c;i < k;++i){
        //scanf("%d %d %d",&a,&b,&c);
        cin>>a>>b>>c;
        int e1 = id[a][b],e2 = id[b][c];

        if(e1 && e2) S.insert(make_pair(e1,e2));
    }

    queue<node> Q;
    Q.push(node(1,1,0));
    visited[1] = true;
    par[1] = -1;

    while(!Q.empty()){
        node cur = Q.front();
        Q.pop();

		if(cur.pos == n){
            //printf("%d\n",cur.dist);
            cout<<cur.dist<<endl;
            int pos = cur.id;
            vector<int> path;

            while(pos != 1){
                path.push_back(e[pos]);
                pos = par[pos];
            }

            path.push_back(1);

            int sz = cur.dist + 1;
            for(int i = sz - 1;i >= 0;--i)// printf("%d ",path[i]);
				cout<<path[i]<<" ";
				//printf("\n");
            cout<<endl;
            return 0;
        }

        for(int i = L[cur.pos].size() - 1,e;i >= 0;--i){
            e = L[cur.pos][i].id;

            if(!visited[e] && S.find(make_pair(cur.id,e)) == S.end()){
                Q.push(node(e,L[cur.pos][i].to,cur.dist + 1));
                visited[e] = true;
                par[e] = cur.id;
            }
        }
    }

    //printf("-1\n");
    cout<<-1<<endl;
    return 0;
}


#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<list>
#include<set>

using namespace std;

const int MAXN = 10086;
const int INF = 1000000000;

list<short> E[3001];
map<pair<short,short> , set<short> > mp;//(a,b,c)
int dp[3001][3001] ;
short pre[3001][3001];

void print(int last , int now){
    if(last == -1)return;
    print(pre[last][now] , last);
    printf("%d ",last);
}

int main()
{
    for(int n , m, k;~scanf("%d%d%d",&n,&m,&k);){
        for(int i = 1 ; i <= n; i ++){
            E[i].clear();
        }
        int a,b,c;
        for(int i = 0 ; i < m ; i++){
            scanf("%d%d",&a,&b);
            E[a].push_back(b);
            E[b].push_back(a);
        }
        mp.clear();
        for(int i = 0 ; i < k ; i++){
            scanf("%d%d%d",&a,&b,&c);
            mp[make_pair(a,b)].insert(c);
        }

        fill(dp[1],dp[n+1],INF);

        queue<pair<short,short> > Q;
        for(list<short>::iterator it = E[1].begin() ; it != E[1].end() ; it++){
            dp[1][*it] = 1;
            pre[1][*it] = -1;
            Q.push(make_pair(1,*it));
        }
        E[1].clear();
        while(!Q.empty()){
            pair<short,short> p = Q.front();
            Q.pop();
            a = p.first;
            b = p.second;
            set<short> &iset = mp[p];
            for(list<short>::iterator it = E[b].begin() ; it != E[b].end();){
                if(iset.count(*it) > 0){
                    it++;
                }
                else{
                    dp[b][*it] = dp[a][b] + 1;
                    pre[b][*it] = a;
                    Q.push(make_pair(b,*it));
                    it = E[b].erase(it);//处理判重！！
                }
            }
        }

        int ans = INF , ansPre;
        for(int i = 1 ; i < n ; i++){
            if(dp[i][n] < ans){
                ans = dp[i][n];
                ansPre = i;
            }
        }

        if(ans == INF)puts("-1");
        else{
            printf("%d\n",ans);
            print(ansPre,n);
            printf("%d\n",n);
        }
    }
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
using namespace std;

#define maxm 3050
#define inf (1<<29)

struct node{
    int now,prev,cost;
};

vector<int>v[maxm],w[maxm];
int d[maxm][maxm],n,m,kk;
int pre[maxm][maxm],forbid[maxm][maxm];

bool operator <(const node &a,const node &b){
    return (a.cost > b.cost);
}
priority_queue<node>pq;
void dij(int s);
void print(int now,int prev);

int main(){

    int i,j,k,l,test,t=1;

    //freopen("in.txt","r",stdin);

    scanf("%d %d %d",&n,&m,&kk);

    for(i=1;i<=m;i++){
        scanf("%d %d",&k,&l);
        v[k].push_back(l); w[k].push_back(1);
        v[l].push_back(k); w[l].push_back(1);
    }
    for(i=1;i<=kk;i++){
        scanf("%d %d %d",&k,&l,&j);
        forbid[k][l]=j;
    }

    dij(1);

    return 0;
}

void dij(int s){

    int i,j,k,l;
    node temp,temp1;

    memset(d,-1,sizeof(d));

    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            d[i][j]=inf;
        }
    }
    d[s][s]=0;
    temp.cost=0; temp.now=s; temp.prev=s;
    pq.push(temp);

    while(!pq.empty()){

        temp=pq.top(); pq.pop();

        if(temp.now==n){
            printf("%d\n",temp.cost);
            print(n,temp.prev);
            printf("\n");
            return ;
        }
        int nn=temp.now;

        for(i=0;i<v[nn].size();i++){
            k=v[nn][i];
            if(forbid[temp.prev][temp.now]==k) continue;
            if(d[nn][k]>temp.cost+w[nn][i]){
                d[nn][k]=temp.cost+w[nn][i];
                temp1.now=k; temp1.prev=nn;
                temp1.cost=d[nn][k];
                pre[k][nn]=temp.prev;
                pq.push(temp1);
            }
        }

    }

    printf("-1\n"); return ;
}

void print(int now,int prev){

    if(pre[now][prev]==0){
        printf("%d",now);
        return ;
    }
    print(prev,pre[now][prev]);
    printf(" %d",now);
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;

#define maxm 3050
#define inf (1<<29)

struct node{
    int now,prev,cost;
};

vector<int>v[maxm],w[maxm];
int d[maxm][maxm],n,m,kk;
int pre[maxm][maxm];
set<int>forbid[maxm][maxm];

bool operator <(const node &a,const node &b){
    return (a.cost > b.cost);
}
priority_queue<node>pq;
void dij(int s);
void print(int now,int prev);

int main(){

    int i,j,k,l,test,t=1;

    //freopen("in.txt","r",stdin);

    scanf("%d %d %d",&n,&m,&kk);

    for(i=1;i<=m;i++){
        scanf("%d %d",&k,&l);
        v[k].push_back(l); w[k].push_back(1);
        v[l].push_back(k); w[l].push_back(1);
    }
    for(i=1;i<=kk;i++){
        scanf("%d %d %d",&k,&l,&j);
        forbid[k][l].insert(j);
    }

    dij(1);

    return 0;
}

void dij(int s){

    int i,j,k,l;
    node temp,temp1;

    memset(d,-1,sizeof(d));

    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            d[i][j]=inf;
        }
    }
    d[s][s]=0;
    temp.cost=0; temp.now=s; temp.prev=s;
    pq.push(temp);

    while(!pq.empty()){

        temp=pq.top(); pq.pop();

        if(temp.now==n){
            printf("%d\n",temp.cost);
            print(n,temp.prev);
            printf("\n");
            return ;
        }
        int nn=temp.now;

        for(i=0;i<v[nn].size();i++){
            k=v[nn][i];
            if(forbid[temp.prev][temp.now].find(k)!=forbid[temp.prev][temp.now].end()) continue;
            if(d[nn][k]>temp.cost+w[nn][i]){
                d[nn][k]=temp.cost+w[nn][i];
                temp1.now=k; temp1.prev=nn;
                temp1.cost=d[nn][k];
                pre[k][nn]=temp.prev;
                pq.push(temp1);
            }
        }

    }

    printf("-1\n"); return ;
}

void print(int now,int prev){

    if(pre[now][prev]==0){
        printf("%d",now);
        return ;
    }
    print(prev,pre[now][prev]);
    printf(" %d",now);
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;

#define maxm 3050
#define inf (1<<29)

struct node{
    int now,prev,cost;
};
struct triple{
    int a,b,c;
};

vector<int>v[maxm],w[maxm];
int d[maxm][maxm],n,m,kk;
int pre[maxm][maxm];
set<int>forbid[100010];
int name[maxm][maxm];

bool operator <(const node &a,const node &b){
    return (a.cost > b.cost);
}
priority_queue<node>pq;
void dij(int s);
void print(int now,int prev);
bool comp(triple a,triple b){
    if(a.a==b.a){
         if(a.b==b.b) return a.c<b.c;
         return a.b<b.b;
    }
    return a.a<b.a;
}

int main(){

    int i,j,k,l,test,t=1;

    //freopen("in.txt","r",stdin);

    scanf("%d %d %d",&n,&m,&kk);

    for(i=1;i<=m;i++){
        scanf("%d %d",&k,&l);
        v[k].push_back(l); w[k].push_back(1);
        v[l].push_back(k); w[l].push_back(1);
    }
    for(i=1;i<=kk;i++){
        scanf("%d %d %d",&k,&l,&j);
        //trips[i-1].a=k; trips[i-1].b=l; trips[i-1].c=j;
        if(name[k][l]==0){
            name[k][l]=i;
        }
        forbid[name[k][l]].insert(j);
    }
    //sort(trips,trips+kk,comp2);

    dij(1);

    return 0;
}

void dij(int s){

    int i,j,k,l;
    node temp,temp1;

    memset(d,-1,sizeof(d));

    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            d[i][j]=inf;
        }
    }
    d[s][s]=0;
    temp.cost=0; temp.now=s; temp.prev=s;
    pq.push(temp);

    while(!pq.empty()){

        temp=pq.top(); pq.pop();

        if(temp.now==n){
            printf("%d\n",temp.cost);
            print(n,temp.prev);
            printf("\n");
            return ;
        }
        int nn=temp.now;

        for(i=0;i<v[nn].size();i++){
            k=v[nn][i];
            l=name[temp.prev][temp.now];
            if(l){
                if(forbid[l].find(k)!=forbid[l].end()) continue;
            }
            if(d[nn][k]>temp.cost+w[nn][i]){
                d[nn][k]=temp.cost+w[nn][i];
                temp1.now=k; temp1.prev=nn;
                temp1.cost=d[nn][k];
                pre[k][nn]=temp.prev;
                pq.push(temp1);
            }
        }

    }

    printf("-1\n"); return ;
}

void print(int now,int prev){

    if(pre[now][prev]==0){
        printf("%d",now);
        return ;
    }
    print(prev,pre[now][prev]);
    printf(" %d",now);
}


#include <stdio.h>
#include <vector>
#include <list>
#include <set>

#define MAXN 3000
#define MAXM 100000

typedef std::vector< int > CIntList;
typedef std::list< std::pair< int, int > > CQueue;

CIntList g[MAXN];

struct Triple {
    int a,b,c;
    Triple( int a_ = 0, int b_ = 0, int c_ = 0 ) : a(a_), b(b_), c(c_) {}

    bool operator<( Triple const & r ) const
    {
        if( a<r.a ) return true;
        if( a>r.a ) return false;

        if( b<r.b ) return true;
        if( b>r.b ) return false;

        if( c<r.c ) return true;
        return false;
    }
};

typedef std::set< Triple > CTriples;
CTriples r;

int d[MAXN][MAXN];
short p1[MAXN][MAXN];
short p2[MAXN][MAXN];

int main()
{
    //freopen( "in3.txt", "rt", stdin );

    int n,m,k;
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < m; ++ i )
    {
        int a,b;
        scanf( "%d %d", &a, &b );
        --a; --b;
        g[a].push_back( b );
        g[b].push_back( a );
    }
    for( int i = 0; i < k; ++ i )
    {
        int a,b,c;
        scanf( "%d %d %d", &a, &b, &c );
        --a; --b; --c;
        r.insert( Triple( a,b,c ) );
    }

    memset( d, -1, sizeof(d) );
    memset( p1, -1, sizeof(p1) );
    memset( p2, -1, sizeof(p2) );
    CQueue q;
    q.push_back( std::make_pair( 0, 0 ) );
    d[0][0] = 0; p1[0][0] = -1; p2[0][0] = -1;

    while( ! q.empty() )
    {
        int cur = q.front().second;
        int prev = q.front().first;

        for( CIntList::const_iterator i = g[cur].begin(); i != g[cur].end(); ++ i )
        {
            if( d[cur][*i]==-1 && r.find( Triple( prev, cur, *i ) ) == r.end() )
            {
                d[cur][*i] = d[prev][cur] + 1;
                p1[cur][*i] = cur;
                p2[cur][*i] = prev;
                q.push_back( std::make_pair( cur, *i ) );
            }
        }
        q.pop_front();
    }

    int best = -1;
    for( int i = 0; i < n; ++ i )
        if( d[i][n-1] != -1 && ( d[i][n-1] < d[best][n-1] ) ) best = i;

    if( best != -1 )
    {

        CIntList sol;
        int cur = n-1, prev = best;
        while( cur != -1 )
        {
            sol.push_back( cur );
            int t = cur;
            cur = p1[prev][t];
            prev = p2[prev][t];
        }

        int size = sol.size();
        printf( "%d\n", size - 1 );
        for( int i = size-1; i >= 0; --i )
            printf( "%d ", sol[i]+1 );
    }
    else
    {
        printf( "-1" );
    }

    return 0;
}


#include <stdio.h>
#include <vector>
#include <list>
#include <set>

#define MAXN 3000
#define MAXM 100000

typedef std::vector< int > CIntList;
typedef std::list< std::pair< int, int > > CQueue;

CIntList g[MAXN];

struct Triple {
    int a,b,c;
    Triple( int a_ = 0, int b_ = 0, int c_ = 0 ) : a(a_), b(b_), c(c_) {}

    bool operator<( Triple const & r ) const
    {
        if( a<r.a ) return true;
        if( a>r.a ) return false;

        if( b<r.b ) return true;
        if( b>r.b ) return false;

        if( c<r.c ) return true;
        return false;
    }
};

typedef std::set< Triple > CTriples;
CTriples r;

int d[MAXN][MAXN];
int p1[MAXN][MAXN];
int p2[MAXN][MAXN];

int main()
{
    //freopen( "in3.txt", "rt", stdin );

    int n,m,k;
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < m; ++ i )
    {
        int a,b;
        scanf( "%d %d", &a, &b );
        --a; --b;
        g[a].push_back( b );
        g[b].push_back( a );
    }
    for( int i = 0; i < k; ++ i )
    {
        int a,b,c;
        scanf( "%d %d %d", &a, &b, &c );
        --a; --b; --c;
        r.insert( Triple( a,b,c ) );
    }

    memset( d, -1, sizeof(d) );
    memset( p1, -1, sizeof(p1) );
    memset( p2, -1, sizeof(p2) );
    CQueue q;
    q.push_back( std::make_pair( 0, 0 ) );
    d[0][0] = 0; p1[0][0] = -1; p2[0][0] = -1;

    while( ! q.empty() )
    {
        int cur = q.front().second;
        int prev = q.front().first;

        for( CIntList::const_iterator i = g[cur].begin(); i != g[cur].end(); ++ i )
        {
            if( d[cur][*i]==-1 && r.find( Triple( prev, cur, *i ) ) == r.end() )
            {
                d[cur][*i] = d[prev][cur] + 1;
                p1[cur][*i] = cur;
                p2[cur][*i] = prev;
                q.push_back( std::make_pair( cur, *i ) );
            }
        }
        q.pop_front();
    }

    int best = -1;
    for( int i = 0; i < n; ++ i )
        if( d[i][n-1] != -1 && ( d[i][n-1] < d[best][n-1] ) ) best = i;

    if( best != -1 )
    {

        CIntList sol;
        int cur = n-1, prev = best;
        while( cur != -1 )
        {
            sol.push_back( cur );
            int t = cur;
            cur = p1[prev][t];
            prev = p2[prev][t];
        }

        int size = sol.size();
        printf( "%d\n", size - 1 );
        for( int i = size-1; i >= 0; --i )
            printf( "%d ", sol[i]+1 );
    }
    else
    {
        printf( "-1" );
    }

    return 0;
}


#include <stdio.h>
#include <vector>
#include <list>
#include <set>

#define MAXN 3000
#define MAXM 100000

typedef std::vector< short > CIntList;
typedef std::list< std::pair< short, short > > CQueue;

CIntList g[MAXN];

struct Triple {
    short a,b,c;
    Triple( short a_ = 0, short b_ = 0, short c_ = 0 ) : a(a_), b(b_), c(c_) {}

    bool operator<( Triple const & r ) const
    {
        if( a<r.a ) return true;
        if( a>r.a ) return false;

        if( b<r.b ) return true;
        if( b>r.b ) return false;

        if( c<r.c ) return true;
        return false;
    }
};

typedef std::set< Triple > CTriples;
CTriples r;

int d[MAXN][MAXN];
short p1[MAXN][MAXN];
short p2[MAXN][MAXN];

int main()
{
    //freopen( "in3.txt", "rt", stdin );

    int n,m,k;
    scanf( "%d %d %d", &n, &m, &k );
    for( int i = 0; i < m; ++ i )
    {
        int a,b;
        scanf( "%d %d", &a, &b );
        --a; --b;
        g[a].push_back( b );
        g[b].push_back( a );
    }
    for( int i = 0; i < k; ++ i )
    {
        int a,b,c;
        scanf( "%d %d %d", &a, &b, &c );
        --a; --b; --c;
        r.insert( Triple( a,b,c ) );
    }

    memset( d, -1, sizeof(d) );
    memset( p1, -1, sizeof(p1) );
    memset( p2, -1, sizeof(p2) );
    CQueue q;
    q.push_back( std::make_pair( 0, 0 ) );
    d[0][0] = 0; p1[0][0] = -1; p2[0][0] = -1;

    while( ! q.empty() )
    {
        int cur = q.front().second;
        int prev = q.front().first;

        for( CIntList::const_iterator i = g[cur].begin(); i != g[cur].end(); ++ i )
        {
            if( d[cur][*i]==-1 && r.find( Triple( prev, cur, *i ) ) == r.end() )
            {
                d[cur][*i] = d[prev][cur] + 1;
                p1[cur][*i] = cur;
                p2[cur][*i] = prev;
                q.push_back( std::make_pair( cur, *i ) );
            }
        }
        q.pop_front();
    }

    int best = -1;
    for( int i = 0; i < n; ++ i )
        if( d[i][n-1] != -1 && ( best == -1 || d[i][n-1] < d[best][n-1] ) ) best = i;

    if( best != -1 )
    {

        CIntList sol;
        int cur = n-1, prev = best;
        while( cur != -1 )
        {
            sol.push_back( cur );
            int t = cur;
            cur = p1[prev][t];
            prev = p2[prev][t];
        }

        int size = sol.size();
        printf( "%d\n", size - 1 );
        for( int i = size-1; i >= 0; --i )
            printf( "%d ", sol[i]+1 );
    }
    else
    {
        printf( "-1" );
    }

    return 0;
}


#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>

using namespace std;

#define file "file"
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<string> vs;

const int MAXN = 3e4+5;
const double EPS = 1e-9;
const ll INF = 1e9;

vector<int> g[MAXN];
set< pair<pii,int> > st;

ll d[MAXN];
int p[MAXN];
int p2[MAXN];
bool used[MAXN];

int main()
{
	//freopen(file ".in","r",stdin);freopen(file ".out","w",stdout);
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	int n,m,k;
	int u,v;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
	}

	int a1,a2,a3;
	for(int i=0;i<k;i++)
	{
		scanf("%d%d%d",&a1,&a2,&a3);
		st.insert(mp(mp(a1,a2),a3));
	}

	for(int i=0;i<=n;i++) d[i] = INF;

	d[1] = 0;
	p[1] = 0;
	for(int i=0;i<n;i++)
	{
		v = -1;
		for(int j=1;j<=n;j++)
		{
			if(!used[j])
			{
				if(v==-1 || d[v]>d[j])
				{
					v = j;
				}
			}
		}

		used[v] = true;
		int sz = g[v].size();
		for(int j=0;j<sz;j++)
		{
			int a = p[v];
			int b = v;
			int c = g[v][j];
			if(st.count(mp(mp(a,b),c))==0)
			{
				if(d[c]>d[v]+1)
				{
					d[c] = d[v]+1;
					p[c] = v;
				}
			}
			else
			{
				if(g[b].size()>2)
				{
					int to = -1;
					for(int ii=0;ii<sz;ii++)
					{
						if(g[v][ii]!=a && g[v][ii]!=c)
						{
							to = g[v][ii];
							break;
						}
					}

					if(to!=-1)
					{
						if(d[c]>d[v]+3)
						{
							d[c] = d[v]+3;
							p[c] = v;
							p2[c] = to;
						}
					}
				}
			}
		}
	}

	if(d[n]==INF)
	{
		printf("-1");
		return 0;
	}

	printf("%d\n",d[n]);
	vector<int> res;
	int cur = n;
	res.pb(n);
	while(cur!=1)
	{
		bool need = false;
		v = 0;
		if(abs(1.*d[cur]-d[p[cur]])>1)
		{
			need = true;
			v = p2[cur];
		}
		cur = p[cur];
		res.pb(cur);
		if(need)
		{
			res.pb(v);
			res.pb(cur);
		}
	}

	int sz = res.size();
	for(int i=sz-1;i>=0;i--)
	{
		printf("%d ",res[i]);
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>

using namespace std;

#define file "file"
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<string> vs;

const int MAXN = 3e4+5;
const double EPS = 1e-9;
const ll INF = 1e9;

vector<int> g[MAXN];
set< pair<pii,int> > st;

ll d[MAXN];
int p[MAXN];
int p2[MAXN];
bool used[MAXN];

int main()
{
	//freopen(file ".in","r",stdin);freopen(file ".out","w",stdout);
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	int n,m,k;
	int u,v;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
	}

	int a1,a2,a3;
	for(int i=0;i<k;i++)
	{
		scanf("%d%d%d",&a1,&a2,&a3);
		st.insert(mp(mp(a1,a2),a3));
	}

	for(int i=0;i<=n;i++) d[i] = INF;

	d[1] = 0;
	p[1] = 0;
	for(int i=0;i<n;i++)
	{
		v = -1;
		for(int j=1;j<=n;j++)
		{
			if(!used[j])
			{
				if(v==-1 || d[v]>d[j])
				{
					v = j;
				}
			}
		}

		used[v] = true;
		int sz = g[v].size();
		for(int j=0;j<sz;j++)
		{
			int a = p[v];
			int b = v;
			int c = g[v][j];
			if(st.count(mp(mp(a,b),c))==0)
			{
				if(d[c]>d[v]+1)
				{
					d[c] = d[v]+1;
					p[c] = v;
				}
			}
			else
			{
				if(g[b].size()>2)
				{
					int to = -1;
					for(int ii=0;ii<sz;ii++)
					{
						if(g[v][ii]!=a && g[v][ii]!=c)
						{
							to = g[v][ii];
							if(st.count(mp(mp(to,v),c))==0)
							{
								break;
							}
						}
					}

					if(to!=-1)
					{
						if(d[c]>d[v]+3)
						{
							d[c] = d[v]+3;
							p[c] = v;
							p2[c] = to;
						}
					}
				}
			}
		}
	}

	if(d[n]==INF)
	{
		printf("-1");
		return 0;
	}

	printf("%d\n",d[n]);
	vector<int> res;
	int cur = n;
	res.pb(n);
	while(cur!=1)
	{
		bool need = false;
		v = 0;
		if(abs(1.*d[cur]-d[p[cur]])>1)
		{
			need = true;
			v = p2[cur];
		}
		cur = p[cur];
		res.pb(cur);
		if(need)
		{
			res.pb(v);
			res.pb(cur);
		}
	}

	int sz = res.size();
	for(int i=sz-1;i>=0;i--)
	{
		printf("%d ",res[i]);
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>

using namespace std;

#define file "file"
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<string> vs;

const int MAXN = 3e4+5;
const double EPS = 1e-9;
const ll INF = 1e9;

vector<int> g[MAXN];
set< pair<pii,int> > st;

ll d[MAXN];
int p[MAXN];
int p2[MAXN];
bool used[MAXN];

int main()
{
	//freopen(file ".in","r",stdin);freopen(file ".out","w",stdout);
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	int n,m,k;
	int u,v;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
	}

	int a1,a2,a3;
	for(int i=0;i<k;i++)
	{
		scanf("%d%d%d",&a1,&a2,&a3);
		st.insert(mp(mp(a1,a2),a3));
	}

	for(int i=0;i<=n;i++) d[i] = INF;

	d[1] = 0;
	p[1] = 0;
	for(int i=0;i<n;i++)
	{
		v = -1;
		for(int j=1;j<=n;j++)
		{
			if(!used[j])
			{
				if(v==-1 || d[v]>d[j])
				{
					v = j;
				}
			}
		}

		used[v] = true;
		int sz = g[v].size();
		for(int j=0;j<sz;j++)
		{
			int a = p[v];
			int b = v;
			int c = g[v][j];
			if(st.count(mp(mp(a,b),c))==0)
			{
				if(d[c]>d[v]+1)
				{
					d[c] = d[v]+1;
					p[c] = v;
				}
			}
			else
			{
				int to = -1;
				for(int ii=0;ii<sz;ii++)
				{
					if(g[v][ii]!=a && g[v][ii]!=c)
					{
						to = g[v][ii];
						if(st.count(mp(mp(to,v),c))==0 && st.count(mp(mp(v,to),v))==0
							&& st.count(mp(mp(a,b),to))==0)
						{
							break;
						}
					}
				}

				if(to!=-1)
				{
					if(d[c]>d[v]+3)
					{
						d[c] = d[v]+3;
						p[c] = v;
						p2[c] = to;
					}
				}

			}
		}
	}

	if(d[n]==INF)
	{
		printf("-1");
		return 0;
	}

	printf("%d\n",d[n]);
	vector<int> res;
	int cur = n;
	res.pb(n);
	while(cur!=1)
	{
		bool need = false;
		v = 0;
		if(abs(1.*d[cur]-d[p[cur]])>1)
		{
			need = true;
			v = p2[cur];
		}
		cur = p[cur];
		res.pb(cur);
		if(need)
		{
			res.pb(v);
			res.pb(cur);
		}
	}

	int sz = res.size();
	for(int i=sz-1;i>=0;i--)
	{
		printf("%d ",res[i]);
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>

using namespace std;

#define file "file"
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<string> vs;

const int MAXN = 3e4+5;
const double EPS = 1e-9;
const ll INF = 1e9;

vector<int> g[MAXN];
set< pair<pii,int> > st;

ll d[MAXN];
int p[MAXN];
int p2[MAXN];
bool used[MAXN];

int main()
{
	//freopen(file ".in","r",stdin);freopen(file ".out","w",stdout);
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	int n,m,k;
	int u,v;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
	}

	int a1,a2,a3;
	for(int i=0;i<k;i++)
	{
		scanf("%d%d%d",&a1,&a2,&a3);
		st.insert(mp(mp(a1,a2),a3));
	}

	for(int i=0;i<=n;i++) d[i] = INF;

	d[1] = 0;
	p[1] = 0;
	for(int i=0;i<n;i++)
	{
		v = -1;
		for(int j=1;j<=n;j++)
		{
			if(!used[j])
			{
				if(v==-1 || d[v]>d[j])
				{
					v = j;
				}
			}
		}

		used[v] = true;
		int sz = g[v].size();
		for(int j=0;j<sz;j++)
		{
			int a = p[v];
			int b = v;
			int c = g[v][j];
			if(st.count(mp(mp(a,b),c))==0)
			{
				if(d[c]>d[v]+1)
				{
					d[c] = d[v]+1;
					p[c] = v;
				}
			}
			else
			{
				int to = -1;
				for(int ii=0;ii<sz;ii++)
				{
					if(g[v][ii]!=a && g[v][ii]!=c)
					{
						to = g[v][ii];
						if(st.count(mp(mp(to,v),c))==0
							&& st.count(mp(mp(a,b),to))==0)
						{
							break;
						}
					}
				}

				if(to!=-1)
				{
					if(d[c]>d[v]+3)
					{
						d[c] = d[v]+3;
						p[c] = v;
						p2[c] = to;
					}
				}

			}
		}
	}

	if(d[n]==INF)
	{
		printf("-1");
		return 0;
	}

	printf("%d\n",d[n]);
	vector<int> res;
	int cur = n;
	res.pb(n);
	while(cur!=1)
	{
		bool need = false;
		v = 0;
		if(abs(1.*d[cur]-d[p[cur]])>1)
		{
			need = true;
			v = p2[cur];
		}
		cur = p[cur];
		res.pb(cur);
		if(need)
		{
			res.pb(v);
			res.pb(cur);
		}
	}

	int sz = res.size();
	for(int i=sz-1;i>=0;i--)
	{
		if(res[i]==0)
		{
			while(1)
			{
				v++;
			}
		}
		printf("%d ",res[i]);
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>

using namespace std;

#define file "file"
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<string> vs;

const int MAXN = 3000+5;
const double EPS = 1e-9;
const ll INF = 1e9;

set< pair<pii,int> > st;
vector<int> g[MAXN];
int d[MAXN][MAXN];
pii p[MAXN][MAXN];

void dfs(int vv)
{
	queue<int> q;
	queue<int> q2;
	q.push(vv);
	q2.push(vv);
	d[vv][vv] = 0;
	p[vv][vv] = mp(0,0);
	while(!q.empty())
	{
		int v = q.front();q.pop();
		int prev = q2.front();q2.pop();
		int sz = g[v].size();
		for(int i=0;i<sz;i++)
		{
			int to = g[v][i];
			if(st.count(mp(mp(prev,v),to))==0)
			{
				if(d[v][to]>d[prev][v]+1)
				{
					d[v][to] = d[prev][v]+1;
					p[v][to] = mp(prev,v);
					q.push(to);
					q2.push(v);
				}
			}
		}
	}
}

int main()
{
	//freopen(file ".in","r",stdin);freopen(file ".out","w",stdout);
	#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	#endif
	int n,m,k;
	int u,v;
	int a,c,b;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
	}

	for(int i=0;i<k;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		st.insert( mp(mp(a,b),c) );
	}

	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			d[i][j] = INF;

	dfs(1);

	int ans = INF;
	int cur2 = n,cur1 = 0;
	for(int i=1;i<=n;i++)
	{
		if(ans>d[i][n])
		{
			ans = d[i][n];
			cur1 = i;
		}
	}

	if(ans==INF)
	{
		printf("-1");
		return 0;
	}

	vector<int> res;
	res.pb(cur2);
	res.pb(cur1);
	while(cur1)
	{
		pii p2 = p[cur1][cur2];
		cur1 = p2.first;
		cur2 = p2.second;
		res.pb(cur1);
	}

	printf("%d\n",ans);
	int sz = res.size();
	for(int i=sz-3;i>=0;i--)
	{
		printf("%d ",res[i]);
	}
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<algorithm>
using namespace std;

#define MAX_V 5007

struct DATA{
	long a,b,c;
};

struct POS{
	long a,b,c;
	long Ds;
};

bool operator<( const DATA &S1,const DATA &S2 )
{
	if( S1.a != S2.a ) return S1.a < S2.a;
	else if( S1.b != S2.b ) return S1.b < S2.b;
	else return S1.c < S2.c;
};

bool operator==( const DATA &S1,const DATA &S2 )
{
	return S1.a == S2.a && S1.b == S2.b && S1.c == S2.c;
};

vector<DATA> Vec;

bool Find( DATA d )
{
	long L = 0;
	long U = Vec.size()-1;
	while( L<=U){
		long M = (L+U)/2;
		if( Vec[M]==d) return true;
		else if( Vec[M]<d) L = M+1;
		else U = M-1;
	}
	return false;
}

vector<long> Edge[MAX_V+7];
long N,M,K;
set<DATA> Set;

bool Visit[ MAX_V+7][ MAX_V+7];
long P[ MAX_V+7][ MAX_V+7];

void Print( long b,long c )
{
	if( c==1){
		printf("1");
	}
	else{
		Print( P[b][c],b );
		printf(" %ld",c );
	}
}

bool Bfs( void)
{
	queue<POS> q;
	POS Nt,Nw = { 0,0,1,0 };
	long i;

	Visit[0][1] = true;
	P[0][1] = 0;
	q.push( Nw );

	while( !q.empty()){
		Nw = q.front();
		q.pop();
		Nt.a = Nw.b;
		Nt.b = Nw.c;
		for( i=0;i<Edge[Nw.c].size();i++){
			Nt.c = Edge[Nw.c][i];
			if( Visit[Nt.b][Nt.c]) continue;
			DATA d = { Nt.a,Nt.b,Nt.c };
			//if( Set.find( d ) != Set.end()) continue;
			if( Find( d )) continue;
			Nt.Ds = Nw.Ds+1;
			Visit[Nt.b][Nt.c] = true;
			P[Nt.b][Nt.c] = Nt.a;
			if( Nt.c==N){
				printf("%ld\n",Nt.Ds);
				Print( Nt.b,Nt.c );
				printf("\n");
				return true;
			}
			q.push( Nt );
		}
	}
	return false;
}

int main( void)
{
	long i,u,v;

	//freopen("text1.txt","r",stdin );

	scanf("%ld%ld%ld",&N,&M,&K);
	for( i=1;i<=M;i++){
		scanf("%ld%ld",&u,&v );
		Edge[u].push_back( v );
		Edge[v].push_back( u );
	}
	DATA D;
	for( i=1;i<=K;i++){
		scanf("%ld%ld%ld",&D.a,&D.b,&D.c );
		//Set.insert( D );
		Vec.push_back( D );
	}
	sort( Vec.begin(),Vec.end());

	if( !Bfs()){
		printf("-1\n");
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	d[0][0] = 0;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				q.push(p);
			}
		}
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		while (v) {
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	for(int i = 0; i < n; i ++)
		d[i][0] = 0;
	while (!q.empty()) {
		int v = q.front();
		if (v == n - 1)
			break;
		q.pop();
		bool nxt = false;
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				nxt = true;
			}
			if (nxt)
				q.push(p);
		}
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		//int cnt = 0;
		while (v) {
			//cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			/*if (cnt > 6000)
				cout << "Error";*/
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	for(int i = 0; i < n; i ++)
		d[i][0] = 0;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		bool nxt = false;
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				nxt = true;
			}
			if (nxt)
				q.push(p);
		}
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		//int cnt = 0;
		while (v) {
			//cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			/*if (cnt > 6000)
				cout << "Error";*/
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	d[0][0] = 0;
	bool is_end = false;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				q.push(p);
				if (p == n - 1) {
					is_end = true;
					break;
				}
			}
			if (is_end)
				break;
		}
		if (is_end)
			break;
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		//int cnt = 0;
		while (v) {
			//cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			/*if (cnt > 6000)
				cout << "Error";*/
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	for(int i = 0; i < n; i ++)
		d[i][0] = 0;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		if (v == n - 1)
			continue;
		bool nxt = false;
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				nxt = true;
			}
			if (nxt)
				q.push(p);
		}
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		//int cnt = 0;
		while (v) {
			//cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			/*if (cnt > 6000)
				cout << "Error";*/
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
};

const int MM = 20 * 1000 + 10;
const int MK = 1000 * 100 + 10;
const int MN = 3000 + 10;
const int inf = 1 << 30;

vector <tripl> forb;
queue <int> q;
vector <int> sp[MM];
int dp[MN][MN];
int n, m, k;

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	fill(&dp[0][0], &dp[0][0] + MN * MN, inf);
	sort(forb.begin(), forb.end());
	dp[0][0] = 0;
	q.push(0);
	int kol(0);
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		if (v == n - 1)
			break;
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (dp[v][p] != inf)
				continue;
			bool is_push = false;
			for(int i = 0; i < n; i ++) {
				if ((i == v && v) || dp[i][v] == inf)
					continue;
				tripl w;
				w.a = i;
				w.b = v;
				w.c = p;
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (f)
					continue;
				is_push = true;
				dp[v][p] = min(dp[v][p], dp[i][v] + 1);
			}
			if (is_push)
				q.push(p);
		}
	}
	int d = inf;
	for(int i = 0; i < n; i ++)
		d = min(d, dp[i][n-1]);
	if (d == inf)
		cout << -1;
	else {
		cout << d << endl;
		vector <int> ans;
		ans.push_back(n);
		int v = n - 1;
		while (d) {
			for(int i = 0; i < n; i ++)
				if (dp[i][v] == d) {
					ans.push_back(i+1);
					v = i;
					d --;
					break;
				}
		}
		reverse(ans.begin(), ans.end());
		for(int i = 0; i < ans.size(); i ++)
			cout << ans[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	for(int i  =0; i < n; i ++)
		d[i][0] = 0;
	bool is_end = false;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				q.push(p);
				if (p == n - 1) {
					is_end = true;
					break;
				}
			}
			if (is_end)
				break;
		}
		if (is_end)
			break;
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		//int cnt = 0;
		while (v) {
			//cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			/*if (cnt > 6000)
				cout << "Error";*/
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct tripl {
	int a, b, c;
	bool operator<(const tripl &nw) const {
		return (a < nw.a || (a == nw.a && b < nw.b) || (a == nw.a && b == nw.b && c < nw.c));
	}
	tripl() {
	}
	tripl(int x, int y, int z) {
		a = x;
		b = y;
		c = z;
	}
};

const int inf = 1 << 30;
const int MN = 3000 + 10;
int n, m, k;

vector <tripl> forb;
vector <int> sp[MN];
int d[MN][MN];

int main() {
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	fill(&d[0][0], &d[0][0] + MN * MN, inf);
	cin >> n >> m >> k;
	for(int i = 0; i < m; i ++) {
		int x, y;
		cin >> x >> y;
		x --;
		y --;
		sp[x].push_back(y);
		sp[y].push_back(x);
	}
	for(int i = 0; i < k; i ++) {
		tripl w;
		scanf("%d%d%d", &w.a, &w.b, &w.c);
		w.a --;
		w.b --;
		w.c --;
		forb.push_back(w);
	}
	sort(forb.begin(), forb.end());
	queue <int> q;
	q.push(0);
	d[0][0] = 0;
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for(int i = 0; i < sp[v].size(); i ++) {
			int p = sp[v][i];
			if (d[v][p] != inf)
				continue;
			for(int j = 0; j < n; j ++) {
				tripl w(j, v, p);
				bool f = binary_search(forb.begin(), forb.end(), w);
				if (d[j][v] == inf || f)
					continue;
				d[v][p] = min(d[v][p], d[j][v] + 1);
				q.push(p);
			}
		}
	}
	int ans = inf, v;
	for(int i = 0; i < n; i ++) {
		if (d[i][n-1] < ans) {
			ans = d[i][n-1];
			v = i;
		}
	}
	if (ans == inf)
		cout << "-1";
	else {
		vector <int> rez;
		cout << ans << endl;
		rez.push_back(n);
		int cnt = 0;
		while (v) {
			cnt ++;
			rez.push_back(v+1);
			for(int i = 0; i < n; i ++)
				if (d[i][v] == ans - 1) {
					ans --;
					v = i;
					break;
				}
			if (cnt > 6000)
				cout << "Error";
		}
		rez.push_back(1);
		reverse(rez.begin(), rez.end());
		for(int i = 0; i < rez.size(); i ++)
			cout << rez[i] << " ";
	}
	return 0;
}


#define forn(i, n) for (int i = 0; i < (int)(n); i++)
#define fornd(i, n) for (int i = (int)(n) - 1; i >= 0; i--)
#define forab(i, a, b) for (int i = (int)(a); i <= (int)(b); i++)
#define forabd(i, a, b) for (int i = (int)(b); i >= (int)(a); i--)
#define zero(a) memset(a, 0, sizeof(a))
#include <iostream>
#include <cstring>
using namespace std;
const int N=3100,K=110000,inf=1e9,M=200000;
struct queue {
    int i,j;
} q[N*N];
int n,m,k,dest,d[N][N],a,b,st,en,headk[3100][3100],prev[N][N],curm,nextk[K],tok[K],headm[3100],nextm[M],tom[M],from[N],not[N];
void write (int i, int j) {
    if (i==0 && j==1) printf("%d ",1);
    else {
        write(prev[i][j],i);
        printf("%d ",j);
    }
}
int main () {
#ifndef ONLINE_JUDGE
    freopen ("input.txt","r",stdin);
    freopen ("output.txt","w",stdout);
#endif
    cin>>n>>m>>k;
    for (int i=1; i<=m; i++) {
        cin>>a>>b;
        ++curm;
        nextm[curm]=headm[a];
        headm[a]=curm;
        tom[curm]=b;
        ++curm;
        nextm[curm]=headm[b];
        headm[b]=curm;
        tom[curm]=a;
    }
    for (int i=1; i<=k; i++) {
        cin>>a>>b>>dest;
        nextk[i]=headk[a][b];
        headk[a][b]=i;
        tok[i]=dest;
    }
    for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++) d[i][j]=inf;
    d[0][1]=0;
    q[en].i=0;
    q[en].j=1;
    en++;
    while (st<en) {
        int from=q[st].i,to=q[st].j;
        st++;
        zero(not);
        for (int e=headk[from][to]; e!=0; e=nextk[e]) not[tok[e]]=1;
        for (int e=headm[to]; e; e=nextm[e])
            if (!not[tom[e]] && d[from][to]+1<d[to][tom[e]]) {
                d[to][tom[e]]=d[from][to]+1;
                q[en].i=to;
                q[en].j=tom[e];
                prev[to][tom[e]]=from;
                en++;
            }
    }
    int mini=1;
    for (int i=2; i<=n; i++)
        if (d[i][n]<d[mini][n]) mini=i;
    if (d[mini][n]<inf) {
        cout<<d[mini][n]<<endl;
        write(mini,n);
    } else printf("-1");
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>

using namespace std;

vector<int> ll[3010];

struct triple {
	int a,b,c;
	bool operator < (const triple &ot) const {
		if (a != ot.a) return a < ot.a;
		if (b != ot.b) return b < ot.b;
		return c > ot.c;
	}
};

set<triple> restricted;

struct vertex {
	int source;
	int dest;
	int id;
};

struct arc {
	vertex source;
	vertex dest;
	int nxt;
};

arc l[200010];
int beg[100010];

int el = 0;

inline void addArc(const vertex &source, const vertex &dest) {
	l[el].source = source;
	l[el].dest = dest;
	l[el].nxt = beg[source.id];
	beg[source.id] = el++;
}

int sizes[3010];

int d[100010];
int from[100010];

struct ByDistance {
	bool operator () (int a, int b) {
		return d[a] < d[b] || (d[a] == d[b] && a < b);
	}
};

vertex v[100010];
int main() {
	//freopen("input.txt", "r", stdin);

	int n,m,k; cin >> n >> m >> k;
	for (int i=0; i<m; i++) {
		int a,b; cin >> a >> b;
		ll[a].push_back(b);
		ll[b].push_back(a);
	}

	memset(beg, -1, sizeof beg);
	for (int i=0; i<k; i++) {
		triple t;
		cin >> t.a >> t.b >> t.c;
		restricted.insert(t);
	}

	for (int i=1; i<=n; i++) {
		sizes[i] = sizes[i-1] + ll[i].size();
	}

	for (int i=n; i>=1; i--)
		sizes[i] = sizes[i-1];

	for (int first = 1; first <=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			int &second = ll[first][i];
			for (int u=0; u<ll[second].size(); u++) {
				int &third = ll[second][u];
				triple tmp = {first, second, third};
				if (restricted.find(tmp) == restricted.end()) {
					vertex source = {first, second, sizes[first] + i};
					vertex to = {second, third, sizes[second] + u};
					addArc(source, to);
				}
			}
		}
	}
	memset(d, 0x7f, sizeof d);

	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			vertex tmp = {first, ll[first][i], -1};
			v[sizes[first] + i] = tmp;
		}
	}

	set<int, ByDistance> sss;

	for (int i=0; i<ll[1].size(); i++) {
		int id = i; // sizes[1] + i;
		d[id] = 0;
		from[id] = -1;
		sss.insert(id);
	}

	while (sss.size()) {
		int cur = *sss.begin();
		sss.erase(sss.begin());

		for (int nxt = beg[cur]; nxt != -1; nxt = l[nxt].nxt) {
			if (d[l[nxt].dest.id] > d[cur] + 1) {
				sss.erase(l[nxt].dest.id);
				d[l[nxt].dest.id] = d[cur] + 1;
				from[l[nxt].dest.id] = cur;
				sss.insert(l[nxt].dest.id);
			}
		}
	}

	int mn = 0x7f7f7f7f;
	int last = -1;

	vector<int> lastIndeces;
	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			if (ll[first][i] == n) {
				lastIndeces.push_back(sizes[first] + i);
			}
		}
	}

	for (int i=0; i<lastIndeces.size(); i++) {
		if (d[lastIndeces[i]] < mn) {
			mn = d[lastIndeces[i]];
			last = lastIndeces[i];
		}
	}

	if (last == -1) {
		cout << -1 << endl;
	} else {
		cout << mn+1 << endl;
		vector<int> way;
		for(;last != -1; last = from[last]) {
			way.push_back(v[last].dest);
		}
		way.push_back(1);
		for (int i=way.size()-1; i>=0; i--)
			cout << way[i] << ' ';
		cout << endl;
	}

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>

using namespace std;

vector<int> ll[3010];

struct triple {
	int a,b,c;
	bool operator < (const triple &ot) const {
		if (a != ot.a) return a < ot.a;
		if (b != ot.b) return b < ot.b;
		return c > ot.c;
	}
};

set<triple> restricted;

struct vertex {
	int source;
	int dest;
	int id;
};

struct arc {
	vertex source;
	vertex dest;
	int nxt;
};

arc l[200010];
int beg[100010];

int el = 0;

inline void addArc(const vertex &source, const vertex &dest) {
	l[el].source = source;
	l[el].dest = dest;
	l[el].nxt = beg[source.id];
	beg[source.id] = el++;
}

int sizes[3010];

int d[100010];
int from[100010];

struct ByDistance {
	bool operator () (const int a, const int b) const {
		return d[a] < d[b] || (d[a] == d[b] && a < b);
	}
};

vertex v[100010];
int main() {
	//freopen("input.txt", "r", stdin);

	int n,m,k; cin >> n >> m >> k;
	for (int i=0; i<m; i++) {
		int a,b; cin >> a >> b;
		ll[a].push_back(b);
		ll[b].push_back(a);
	}

	memset(beg, -1, sizeof beg);
	for (int i=0; i<k; i++) {
		triple t;
		cin >> t.a >> t.b >> t.c;
		restricted.insert(t);
	}

	for (int i=1; i<=n; i++) {
		sizes[i] = sizes[i-1] + ll[i].size();
	}

	for (int i=n; i>=1; i--)
		sizes[i] = sizes[i-1];

	for (int first = 1; first <=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			int &second = ll[first][i];
			for (int u=0; u<ll[second].size(); u++) {
				int &third = ll[second][u];
				triple tmp = {first, second, third};
				if (restricted.find(tmp) == restricted.end()) {
					vertex source = {first, second, sizes[first] + i};
					vertex to = {second, third, sizes[second] + u};
					addArc(source, to);
				}
			}
		}
	}
	memset(d, 0x7f, sizeof d);

	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			vertex tmp = {first, ll[first][i], -1};
			v[sizes[first] + i] = tmp;
		}
	}

	set<int, ByDistance> sss;

	for (int i=0; i<ll[1].size(); i++) {
		int id = i; // sizes[1] + i;
		d[id] = 0;
		from[id] = -1;
		sss.insert(id);
	}

	while (sss.size()) {
		int cur = *sss.begin();
		sss.erase(sss.begin());

		for (int nxt = beg[cur]; nxt != -1; nxt = l[nxt].nxt) {
			if (d[l[nxt].dest.id] > d[cur] + 1) {
				sss.erase(l[nxt].dest.id);
				d[l[nxt].dest.id] = d[cur] + 1;
				from[l[nxt].dest.id] = cur;
				sss.insert(l[nxt].dest.id);
			}
		}
	}

	int mn = 0x7f7f7f7f;
	int last = -1;

	vector<int> lastIndeces;
	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			if (ll[first][i] == n) {
				lastIndeces.push_back(sizes[first] + i);
			}
		}
	}

	for (int i=0; i<lastIndeces.size(); i++) {
		if (d[lastIndeces[i]] < mn) {
			mn = d[lastIndeces[i]];
			last = lastIndeces[i];
		}
	}

	if (last == -1) {
		cout << -1 << endl;
	} else {
		cout << mn+1 << endl;
		vector<int> way;
		for(;last != -1; last = from[last]) {
			way.push_back(v[last].dest);
		}
		way.push_back(1);
		for (int i=way.size()-1; i>=0; i--)
			cout << way[i] << ' ';
		cout << endl;
	}

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>

using namespace std;

const int MAX = 200010;

vector<int> ll[3010];

struct triple {
	int a,b,c;
	bool operator < (const triple &ot) const {
		if (a != ot.a) return a < ot.a;
		if (b != ot.b) return b < ot.b;
		return c > ot.c;
	}
};

set<triple> restricted;

struct vertex {
	int source;
	int dest;
	int id;
};

struct arc {
	vertex source;
	vertex dest;
	int nxt;
};

arc l[MAX * 2];
int beg[MAX];

int d[MAX];
int from[MAX];

vertex v[MAX];

int el = 0;

inline void addArc(const vertex &source, const vertex &dest) {
	l[el].source = source;
	l[el].dest = dest;
	l[el].nxt = beg[source.id];
	beg[source.id] = el++;
}

int sizes[3010];

struct ByDistance {
	bool operator () (const int a, const int b) const {
		return d[a] < d[b] || (d[a] == d[b] && a < b);
	}
};

int main() {
	//freopen("input.txt", "r", stdin);

	int n,m,k; cin >> n >> m >> k;
	for (int i=0; i<m; i++) {
		int a,b; cin >> a >> b;
		ll[a].push_back(b);
		ll[b].push_back(a);
	}

	memset(beg, -1, sizeof beg);
	for (int i=0; i<k; i++) {
		triple t;
		cin >> t.a >> t.b >> t.c;
		restricted.insert(t);
	}

	for (int i=1; i<=n; i++) {
		sizes[i] = sizes[i-1] + ll[i].size();
	}

	for (int i=n; i>=1; i--)
		sizes[i] = sizes[i-1];

	for (int first = 1; first <=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			int &second = ll[first][i];
			for (int u=0; u<ll[second].size(); u++) {
				int &third = ll[second][u];
				triple tmp = {first, second, third};
				if (restricted.find(tmp) == restricted.end()) {
					vertex source = {first, second, sizes[first] + i};
					vertex to = {second, third, sizes[second] + u};
					addArc(source, to);
				}
			}
		}
	}
	memset(d, 0x7f, sizeof d);

	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			vertex tmp = {first, ll[first][i], -1};
			v[sizes[first] + i] = tmp;
		}
	}

	set<int, ByDistance> sss;

	for (int i=0; i<ll[1].size(); i++) {
		int id = i; // sizes[1] + i;
		d[id] = 0;
		from[id] = -1;
		sss.insert(id);
	}

	while (sss.size()) {
		int cur = *sss.begin();
		sss.erase(sss.begin());

		for (int nxt = beg[cur]; nxt != -1; nxt = l[nxt].nxt) {
			if (d[l[nxt].dest.id] > d[cur] + 1) {
				sss.erase(l[nxt].dest.id);
				d[l[nxt].dest.id] = d[cur] + 1;
				from[l[nxt].dest.id] = cur;
				sss.insert(l[nxt].dest.id);
			}
		}
	}

	int mn = 0x7f7f7f7f;
	int last = -1;

	vector<int> lastIndeces;
	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			if (ll[first][i] == n) {
				lastIndeces.push_back(sizes[first] + i);
			}
		}
	}

	for (int i=0; i<lastIndeces.size(); i++) {
		if (d[lastIndeces[i]] < mn) {
			mn = d[lastIndeces[i]];
			last = lastIndeces[i];
		}
	}

	if (last == -1) {
		cout << -1 << endl;
	} else {
		cout << mn+1 << endl;
		vector<int> way;
		for(;last != -1; last = from[last]) {
			way.push_back(v[last].dest);
		}
		way.push_back(1);
		for (int i=way.size()-1; i>=0; i--)
			cout << way[i] << ' ';
		cout << endl;
	}

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>

using namespace std;

const int MAX = 200010;

vector<int> ll[3010];

struct triple {
	int a,b,c;
	bool operator < (const triple &ot) const {
		if (a != ot.a) return a < ot.a;
		if (b != ot.b) return b < ot.b;
		return c > ot.c;
	}
};

set<triple> restricted;

struct vertex {
	int source;
	int dest;
	int id;
};

struct arc {
	vertex source;
	vertex dest;
	int nxt;
};

arc l[MAX * 2];
int beg[MAX];

int d[MAX];
int from[MAX];

vertex v[MAX];

int el = 0;

inline void addArc(const vertex &source, const vertex &dest) {
	l[el].source = source;
	l[el].dest = dest;
	l[el].nxt = beg[source.id];
	beg[source.id] = el++;
}

int sizes[3010];

struct ByDistance {
	bool operator () (const int a, const int b) const {
		return d[a] < d[b] || (d[a] == d[b] && a < b);
	}
};

void test() {
		{
		freopen("input.txt", "w", stdout);
		int n,m,k;
		n = 1000;
		m = 20000;
		k = 100000;

		cout << n << ' ' << m << ' ' << k << endl;
		for (int i=0; i<m; i++) {
			int a = (rand() % n) + 1;
			int b = (rand() % n) + 1;
			cout << a << ' ' << b << endl;
		}

		for (int i=0; i<k; i++) {
			int a = (rand() % n) + 1;
			int b = (rand() % n) + 1;
			int c = (rand() % n) + 1;
			cout << a << ' ' << b << ' ' << c << endl;
		}

		exit(0);
	}
}

int main() {
	//test();
	//freopen("input.txt", "r", stdin);

	int n,m,k; cin >> n >> m >> k;
	for (int i=0; i<m; i++) {
		int a,b; cin >> a >> b;
		ll[a].push_back(b);
		ll[b].push_back(a);
	}

	memset(beg, -1, sizeof beg);
	for (int i=0; i<k; i++) {
		triple t;
		cin >> t.a >> t.b >> t.c;
		restricted.insert(t);
	}

	for (int i=1; i<=n; i++) {
		sizes[i] = sizes[i-1] + ll[i].size();
	}

	for (int i=n; i>=1; i--)
		sizes[i] = sizes[i-1];

	//for (int first = 1; first <=n; first++) {
	//	for (int i=0; i<ll[first].size(); i++) {
	//		int &second = ll[first][i];
	//		for (int u=0; u<ll[second].size(); u++) {
	//			int &third = ll[second][u];
	//			triple tmp = {first, second, third};
	//			if (restricted.find(tmp) == restricted.end()) {
	//				vertex source = {first, second, sizes[first] + i};
	//				vertex to = {second, third, sizes[second] + u};
	//				addArc(source, to);
	//			}
	//		}
	//	}
	//}
	memset(d, 0x7f, sizeof d);

	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			vertex tmp = {first, ll[first][i], -1};
			v[sizes[first] + i] = tmp;
		}
	}

	set<int, ByDistance> sss;

	for (int i=0; i<ll[1].size(); i++) {
		int id = i; // sizes[1] + i;
		d[id] = 0;
		from[id] = -1;
		sss.insert(id);
	}

	while (sss.size()) {
		int cur = *sss.begin();
		sss.erase(sss.begin());

		for (int i=0; i<ll[v[cur].dest].size(); i++) {
			triple tmp = {v[cur].source, v[cur].dest, ll[v[cur].dest][i]};
			if (restricted.find(tmp) == restricted.end()) {
				int goId = sizes[v[cur].dest] + i;
				if (d[goId] > d[cur] + 1) {
					sss.erase(goId);
					d[goId] = d[cur] + 1;
					from[goId] = cur;
					sss.insert(goId);
				}
			}
		}
	}

	int mn = 0x7f7f7f7f;
	int last = -1;

	vector<int> lastIndeces;
	for (int first=1; first<=n; first++) {
		for (int i=0; i<ll[first].size(); i++) {
			if (ll[first][i] == n) {
				lastIndeces.push_back(sizes[first] + i);
			}
		}
	}

	for (int i=0; i<lastIndeces.size(); i++) {
		if (d[lastIndeces[i]] < mn) {
			mn = d[lastIndeces[i]];
			last = lastIndeces[i];
		}
	}

	if (last == -1) {
		cout << -1 << endl;
	} else {
		cout << mn+1 << endl;
		vector<int> way;
		for(;last != -1; last = from[last]) {
			way.push_back(v[last].dest);
		}
		way.push_back(1);
		for (int i=way.size()-1; i>=0; i--)
			cout << way[i] << ' ';
		cout << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const int MAXN=3000+10;

int arr[MAXN][MAXN], use[MAXN][MAXN] , isEnd[MAXN],n,m,k, path[MAXN][MAXN], isChange[MAXN];

int main()
{
	//freopen("input.txt","r",stdin);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int v1,v2;
		cin>>v1>>v2;
		arr[v1][v2]=arr[v2][v1]=1;
	}
	for(int i=0;i<k;i++)
	{
		int v1,v2,v3;
		scanf("%d%d%d",&v1,&v2,&v3);
		if( (arr[v1][v2]== 1 || arr[v1][v2]==5) && (arr[v2][v3]==1 ||arr[v2][v3]==5) )
		{
			arr[v1][v2]+=4;
			isEnd[v3]=1;
		}
	}
	vector<int> lst;
	use[0][1]=2;
	lst.push_back(1);
	int step=1;
	while(lst.size() && step < MAXN)
	{
		for(int i=0;i<lst.size();i++)
		{
			int curV=lst[i];
			for(int j=1;j<=n;j++)
			{
				if( arr[curV][j]==1 && (use[step][j] == 0 || use[step][j]==1) && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=2;
					path[step][j]=curV;
				}
				if( arr[curV][j]==5 && use[step][j] != 2 && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=1;
					path[step][j]=curV;
				}
			}
		}
		lst.clear();
		for(int j=1;j<=n;j++)
		{
			if(isChange[j])
			{
				isChange[j]=0;
				lst.push_back(j);
			}
		}
		if(use[step][n]!=0)
			break;
		step++;
	}
	lst.clear();
	if(use[step][n]==0)
		cout<<-1;
	else
	{
		while(n)
		{
			lst.push_back(n);
			n=path[step--][n];
			if(lst.back()==1)
				break;
		}
		cout<<lst.size()-1<<endl;
		for(int i=lst.size()-1;i>=0;i--)
			cout<<lst[i]<<" ";

	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const int MAXN=3000+10;

int arr[MAXN][MAXN], use[MAXN][MAXN] , isEnd[MAXN],n,m,k, path[MAXN][MAXN], isChange[MAXN];

int main()
{
	//freopen("input.txt","r",stdin);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int v1,v2;
		cin>>v1>>v2;
		arr[v1][v2]=arr[v2][v1]=1;
	}
	for(int i=0;i<k;i++)
	{
		int v1,v2,v3;
		scanf("%d%d%d",&v1,&v2,&v3);
		arr[v1][v2]+=4;
		isEnd[v3]=1;
	}
	vector<int> lst;
	use[0][1]=2;
	lst.push_back(1);
	int step=1;
	while(lst.size() && step < MAXN)
	{
		for(int i=0;i<lst.size();i++)
		{
			int curV=lst[i];
			for(int j=1;j<=n;j++)
			{
				if( arr[curV][j]==1 && (use[step][j] == 0 || use[step][j]==1) && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=2;
					path[step][j]=curV;
				}
				if( arr[curV][j]==5 && use[step][j] != 2 && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=1;
					path[step][j]=curV;
				}
			}
		}
		lst.clear();
		for(int j=1;j<=n;j++)
		{
			if(isChange[j])
			{
				isChange[j]=0;
				lst.push_back(j);
			}
		}
		if(use[step][n]!=0)
			break;
		step++;
	}
	lst.clear();
	if(use[step][n]==0)
		cout<<-1;
	else
	{
		while(n)
		{
			lst.push_back(n);
			n=path[step--][n];
			if(lst.back()==1)
				break;
		}
		cout<<lst.size()-1<<endl;
		for(int i=lst.size()-1;i>=0;i--)
			cout<<lst[i]<<" ";

	}

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
struct BadC
{
	int a,b,c;
	bool operator<(const BadC rhs) const
	{
		return a<rhs.a || (a==rhs.a && b<rhs.b) || (a==rhs.a && b==rhs.b && c<rhs.c);
	}
	static BadC make(int A,int B,int C)
	{
		BadC t;t.a=A;t.b=B;t.c=C;
		return t;
	}
};
const int MAXN=3004;
int arr[MAXN][MAXN],path[MAXN][MAXN],path2[MAXN][MAXN];
vector<BadC> tripl(100000);
int main()
{
	//freopen("input.txt","r",stdin);
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int t1,t2;
		cin>>t1>>t2;
		arr[t1][t2]=arr[t2][t1]=1;
	}
	for(int i=0;i<k;i++)
		cin>>tripl[i].a>>tripl[i].b>>tripl[i].c;
	sort(tripl.begin(),tripl.end());
	list<pair<int,int> > lst;
	int A,B=-1,C=n;
	lst.push_back(make_pair(1,0));
	while(lst.size())
	{
		int a=lst.front().first;
		int pr=lst.front().second;
		lst.pop_front();
		for(int i=1;i<=n;i++)
			if(arr[a][i] && !path[a][i] && !binary_search(tripl.begin(),tripl.end(),BadC::make(pr,a,i) ) )
			{
				path[a][i]=path[pr][i]+1;
				path2[a][i]=pr;
				lst.push_back(make_pair(i,a));
				if(i==n)
				{
					B=a;
					lst.clear();
					break;
				}
			}
	}

	vector<int> ans;
	if(B==-1)
		cout<<B;
	else
	{
		while(C)
		{
			ans.push_back(C);
			A=path2[B][C];
			C=B;
			B=A;
		}
		cout<<ans.size()-1<<endl;
		for(int i=ans.size()-1;i>=0;i--)
			cout<<ans[i]<<" ";
	}
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const int MAXN=3000+10;

int arr[MAXN][MAXN], use[MAXN][MAXN] , isEnd[MAXN],n,m,k, path[MAXN][MAXN], isChange[MAXN];

int main()
{
	//freopen("input.txt","r",stdin);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int v1,v2;
		cin>>v1>>v2;
		arr[v1][v2]=arr[v2][v1]=1;
	}
	for(int i=0;i<k;i++)
	{
		int v1,v2,v3;
		scanf("%d%d%d",&v1,&v2,&v3);
		if( (arr[v1][v2]== 1 || arr[v1][v2]==5) && (arr[v2][v3]==1 ||arr[v2][v3]==5) )
		{
			arr[v1][v2]+=4;
			isEnd[v3]=1;
		}
	}
	vector<int> lst;
	use[0][1]=2;
	lst.push_back(1);
	int step=1;
	while(lst.size() && step < MAXN)
	{
		for(int i=0;i<lst.size();i++)
		{
			int curV=lst[i];
			for(int j=1;j<=n;j++)
			{
				if( arr[curV][j]==1 && (use[step][j] == 0 || use[step][j]==1) && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=2;
					path[step][j]=curV;
					if(j==n)
						break;
				}
				if( arr[curV][j]==5 && use[step][j] != 2 && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=1;
					path[step][j]=curV;
					if(j==n)
						break;
				}
			}
		}
		lst.clear();
		for(int j=1;j<=n;j++)
		{
			if(isChange[j])
			{
				isChange[j]=0;
				lst.push_back(j);
			}
		}
		if(use[step][n]!=0)
			break;
		step++;
	}
	lst.clear();
	if(use[step][n]==0)
		cout<<-1;
	else
	{
		while(n)
		{
			lst.push_back(n);
			n=path[step--][n];
			if(lst.back()==1)
				break;
		}
		cout<<lst.size()-1<<endl;
		for(int i=lst.size()-1;i>=0;i--)
			cout<<lst[i]<<" ";

	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const int MAXN=3000+10;

int arr[MAXN][MAXN], use[MAXN][MAXN] , isEnd[MAXN],n,m,k, path[MAXN][MAXN], isChange[MAXN];

int main()
{
	//freopen("input.txt","r",stdin);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int v1,v2;
		cin>>v1>>v2;
		arr[v1][v2]=arr[v2][v1]=1;
	}
	for(int i=0;i<k;i++)
	{
		int v1,v2,v3;
		scanf("%d%d%d",&v1,&v2,&v3);
		if( (arr[v1][v2]== 1 || arr[v1][v2]==5) && (arr[v2][v3]==1 || arr[v2][v3]==5) )
		{
			arr[v1][v2]=5;
			isEnd[v3]=1;
		}
	}
	vector<int> lst;
	use[0][1]=2;
	lst.push_back(1);
	int step=1;
	while(lst.size() && step < MAXN)
	{
		for(int i=0;i<lst.size();i++)
		{
			int curV=lst[i];
			for(int j=1;j<=n;j++)
			{
				if( arr[curV][j]==1 && (use[step][j] == 0 || use[step][j]==1) && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=2;
					path[step][j]=curV;
					if(j==n)
						break;
				}
				if( arr[curV][j]==5 && use[step][j] != 2 && !(use[step-1][curV]==1 && isEnd[j]) )
				{
					isChange[j]=1;
					use[step][j]=1;
					path[step][j]=curV;
					if(j==n)
						break;
				}
			}
		}
		lst.clear();
		for(int j=1;j<=n;j++)
		{
			if(isChange[j])
			{
				isChange[j]=0;
				lst.push_back(j);
			}
		}
		if(use[step][n]!=0)
			break;
		step++;
	}
	lst.clear();
	if(use[step][n]==0)
		cout<<-1;
	else
	{
		while(n)
		{
			lst.push_back(n);
			n=path[step--][n];
			if(lst.back()==1)
				break;
		}
		cout<<lst.size()-1<<endl;
		for(int i=lst.size()-1;i>=0;i--)
			cout<<lst[i]<<" ";

	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const int MAXN=3000+10;

int arr[MAXN][MAXN], use[MAXN][MAXN] , isEnd[MAXN][MAXN],n,m,k, path[MAXN][MAXN], isChange[MAXN];

int main()
{
	//freopen("input.txt","r",stdin);
	cin>>n>>m>>k;
	for(int i=0;i<m;i++)
	{
		int v1,v2;
		cin>>v1>>v2;
		arr[v1][v2]=arr[v2][v1]=1;
	}
	for(int i=0;i<k;i++)
	{
		int v1,v2,v3;
		scanf("%d%d%d",&v1,&v2,&v3);
		if( (arr[v1][v2]== 1 || arr[v1][v2]==5) && (arr[v2][v3]==1 || arr[v2][v3]==5) )
		{
			arr[v1][v2]=5;
			isEnd[v2][v3]=1;
		}
	}
	vector<int> lst;
	use[0][1]=2;
	lst.push_back(1);
	int step=1;
	while(lst.size() && step < MAXN)
	{
		for(int i=0;i<lst.size();i++)
		{
			int curV=lst[i];
			for(int j=1;j<=n;j++)
			{
				if( arr[curV][j]==1 && (use[step][j] == 0 || use[step][j]==1) && !(use[step-1][curV]==1 && isEnd[curV][j]) )
				{
					isChange[j]=1;
					use[step][j]=2;
					path[step][j]=curV;
					if(j==n)
						break;
				}
				if( arr[curV][j]==5 && use[step][j] != 2 && !(use[step-1][curV]==1 && isEnd[curV][j]) )
				{
					isChange[j]=1;
					use[step][j]=1;
					path[step][j]=curV;
					if(j==n)
						break;
				}
			}
		}
		lst.clear();
		for(int j=1;j<=n;j++)
		{
			if(isChange[j])
			{
				isChange[j]=0;
				lst.push_back(j);
			}
		}
		if(use[step][n]!=0)
			break;
		step++;
	}
	lst.clear();
	if(use[step][n]==0)
		cout<<-1;
	else
	{
		while(n)
		{
			lst.push_back(n);
			n=path[step--][n];
			if(lst.back()==1)
				break;
		}
		cout<<lst.size()-1<<endl;
		for(int i=lst.size()-1;i>=0;i--)
			cout<<lst[i]<<" ";

	}

	return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <bitset>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <sstream>
#include <cmath>
#include <fstream>
#include <list>
using namespace std;
#define rp(i,n) for(int (i)=0;(i)<(n);++(i))
#define pb push_back
#define L(s) (int)s.size()
#define mp make_pair
#define pii pair<int,int>
#define x first
#define y second
#define inf 1000000000
#define VI vector<int>
#define ll long long
#define all(s) (s).begin(),(s).end()
#define C(u) memset((u),0,sizeof((u)))
#define ull unsigned ll
#define uint unsigned int
#define pdd pair<double,double>
set< pair < pii, int > > s;
int n,m,k;
VI a[3333];
int d[3333][3333];
int p[3333][3333];
queue<pii > q;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	rp(i,m)
	{
		int p,q;
		scanf("%d%d",&p,&q);
		--p;--q;
		a[p].pb(q);
		a[q].pb(p);
	}
	rp(i,k)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		--x;--y;--z;
		s.insert(mp(mp(x,y),z));
	}
	memset(d,63,sizeof(d));
	rp(i,L(a[0]))
	{
		d[0][a[0][i]]=1;
		q.push(mp(0,a[0][i]));
	}
	while(!q.empty())
	{
		pii cur=q.front();
		q.pop();
		rp(i,L(a[cur.y]))
		{
			int v=a[cur.y][i];
			if (s.find(mp(cur,v))==s.end())
				if (d[cur.y][v]>inf)
				{
					d[cur.y][v]=d[cur.x][cur.y]+1;
					p[cur.y][v]=cur.x;
					q.push(mp(cur.y,v));
				}
		}
	}
	int ans=inf;
	int who=-1;
	rp(i,n)
		if (d[i][n-1]<ans)
		{
			ans=d[i][n-1];
			who=i;
		}
	if (ans==inf)
		cout<<"-1\n";
	else
	{
		cout<<ans<<endl;
		VI v(0);
		int now=n-1;
		int prv=who;
		while(prv)
		{
			v.pb(now);
			int tmp=p[prv][now];
			now=prv;
			prv=tmp;
		}
		v.pb(now);
		v.pb(0);
		reverse(all(v));
		rp(i,L(v))
		{
			if (i)
				printf(" ");
			printf("%d",v[i]+1);
		}
		printf("\n");
	}
}


#pragma comment(linker,"/STACK:64000000")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cmath>
#include <map>
#include <set>
#include <ctime>
#include <algorithm>
#include <memory.h>

using namespace std;

#define WR printf
#define RE scanf
#define PB push_back
#define SE second
#define FI first

#define FOR(i,k,n) for(int i=(k); i<=(n); i++)
#define DFOR(i,k,n) for(int i=(k); i>=(n); i--)
#define SZ(a) (int)((a).size())
#define FA(i,v) FOR(i,0,SZ(v)-1)
#define RFA(i,v) DFOR(i,SZ(v)-1,0)
#define CLR(a) memset(a, 0, sizeof(a))

#define LL long long
#define VI  vector<int>
#define PAR pair<int ,int>
#define o_O 1000000000
void __never(int a){printf("\nOPS %d", a);}
#define ass(s) {if (!(s)) {__never(__LINE__);cout.flush();cerr.flush();abort();}}

struct HELEM
{
	int x, y, z;
	HELEM * nxt;
};

struct HASH
{
	HELEM * table[70000];
	HELEM H[200000];
	int sz;
	HASH()
	{
		sz=0;
	}

	void add(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		H[sz].x = x;
		H[sz].y = y;
		H[sz].z = z;
		H[sz].nxt = table[k];
		table[k] = &H[sz];
		sz++;
	}

	bool has(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		for (HELEM * h = table[k]; h; h = h->nxt)
			if (h->x == x && h->y == y && h->z == z)
				return true;
		return false;
	}
} H;

int n, m, k;
//set< pair< PAR, int > > bad;
/*VI G[41000];*/
PAR E[41000];
int e_sz=0;
int be[3200], en[3200];
int q[41000], pre[41000];
bool F[41000];

bool is_bad(int x, int y, int z)
{
	//return bad.find(make_pair(make_pair(x,y),z)) != bad.end();
	return H.has(x,y,z);
}

void sol()
{
	sort(E,E+e_sz);
	FOR(a,1,n)
	{
		be[a]=o_O;
		en[a]=-1;
	}
	FOR(a,0,e_sz-1)
	{
		be[E[a].first] = min(be[E[a].first], a);
		en[E[a].first] = max(en[E[a].first], a);
	}

	/*FOR(a,0,e_sz-1) FOR(b,be[E[a].second],en[E[a].second])
		if (bad.find(make_pair(E[a],E[b].second)) == bad.end())
			G[a].push_back(b);*/

	int z = 0;
	FOR(a,be[1],en[1])
	{
		if (E[a].second==n)
		{
			WR("1\n");
			WR("%d %d", E[a].first, E[a].second);
			return;
		}
		F[a]=true;
		pre[a]=-1;
		q[z++] = a;
	}

	FOR(a,0,z-1) FOR(b,be[E[q[a]].second],en[E[q[a]].second])
		if (!F[b])
			if (!is_bad(E[q[a]].first,E[q[a]].second,E[b].second))
			{
				F[b]=true;
				pre[b]=q[a];
				q[z++]=b;
				if (E[b].second==n)
				{
					VI ans;
					int i=q[z-1];
					while (i!=-1)
					{
						ans.push_back(E[i].second);
						i=pre[i];
					}
					ans.push_back(1);
					reverse(ans.begin(), ans.end());

					WR("%d\n", SZ(ans)-1);
					FA(c,ans) WR("%d ", ans[c]);
					return;
				}
			}

	WR("-1");
}

int main()
{
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);

	cin >> n >> m >> k;
	FOR(a,1,m)
	{
		int x, y;
		RE("%d%d", &x, &y);
		E[e_sz++] = make_pair(x,y);
		E[e_sz++] = make_pair(y,x);
	}
	FOR(a,1,k)
	{
		int x, y, z;
		RE("%d%d%d", &x, &y, &z);
		//bad.insert(make_pair(make_pair(x,y),z));
		H.add(x,y,z);
	}
	sol();

	return 0;
}


#pragma comment(linker,"/STACK:64000000")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cmath>
#include <map>
#include <set>
#include <ctime>
#include <algorithm>
#include <memory.h>

using namespace std;

#define WR printf
#define RE scanf
#define PB push_back
#define SE second
#define FI first

#define FOR(i,k,n) for(int i=(k); i<=(n); i++)
#define DFOR(i,k,n) for(int i=(k); i>=(n); i--)
#define SZ(a) (int)((a).size())
#define FA(i,v) FOR(i,0,SZ(v)-1)
#define RFA(i,v) DFOR(i,SZ(v)-1,0)
#define CLR(a) memset(a, 0, sizeof(a))

#define LL long long
#define VI  vector<int>
#define PAR pair<int ,int>
#define o_O 1000000000
void __never(int a){printf("\nOPS %d", a);}
#define ass(s) {if (!(s)) {__never(__LINE__);cout.flush();cerr.flush();abort();}}

struct HELEM
{
	int x, y, z;
	HELEM * nxt;
};

struct HASH
{
	HELEM * table[70000];
	HELEM H[200000];
	int sz;
	HASH()
	{
		sz=0;
	}

	void add(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		H[sz].x = x;
		H[sz].y = y;
		H[sz].z = z;
		H[sz].nxt = table[k];
		table[k] = &H[sz];
		sz++;
	}

	bool has(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		for (HELEM * h = table[k]; h; h = h->nxt)
			if (h->x == x && h->y == y && h->z == z)
				return true;
		return false;
	}
} H;

int n, m, k;
//set< pair< PAR, int > > bad;
/*VI G[41000];*/
PAR E[41000];
int e_sz=0;
int be[3200], en[3200];
int q[41000], pre[41000];
bool F[41000];

bool is_bad(int x, int y, int z)
{
	//return bad.find(make_pair(make_pair(x,y),z)) != bad.end();
	return H.has(x,y,z);
}

void sol()
{
	sort(E,E+e_sz);
	FOR(a,1,n)
	{
		be[a]=o_O;
		en[a]=-1;
	}
	FOR(a,0,e_sz-1)
	{
		be[E[a].first] = min(be[E[a].first], a);
		en[E[a].first] = max(en[E[a].first], a);
	}

	/*FOR(a,0,e_sz-1) FOR(b,be[E[a].second],en[E[a].second])
		if (bad.find(make_pair(E[a],E[b].second)) == bad.end())
			G[a].push_back(b);*/

	int z = 0;
	FOR(a,be[1],en[1])
	{
		if (E[a].second==n)
		{
			WR("1\n");
			WR("%d %d", E[a].first, E[a].second);
			return;
		}
		F[a]=true;
		pre[a]=-1;
		q[z++] = a;
	}

	FOR(a,0,z-1) FOR(b,be[E[q[a]].second],en[E[q[a]].second])
		if (!F[b])
			if (!is_bad(E[q[a]].first,E[q[a]].second,E[b].second))
			{
				F[b]=true;
				pre[b]=q[a];
				q[z++]=b;
				if (E[b].second==n)
				{
					VI ans;
					int i=z-1;
					while (i!=-1)
					{
						ans.push_back(E[i].second);
						i=pre[i];
					}
					ans.push_back(1);
					reverse(ans.begin(), ans.end());

					WR("%d\n", SZ(ans)-1);
					FA(c,ans) WR("%d ", ans[c]);
					return;
				}
			}

	WR("-1");
}

int main()
{
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);

	cin >> n >> m >> k;
	FOR(a,1,m)
	{
		int x, y;
		RE("%d%d", &x, &y);
		E[e_sz++] = make_pair(x,y);
		E[e_sz++] = make_pair(y,x);
	}
	FOR(a,1,k)
	{
		int x, y, z;
		RE("%d%d%d", &x, &y, &z);
		//bad.insert(make_pair(make_pair(x,y),z));
		H.add(x,y,z);
	}
	sol();

	return 0;
}


#include <iostream>
#include <fstream>

#include <vector>
#include <queue>
#include <map>

using namespace std;

const int MAXN = 5001;
#define mp(a, b) make_pair(a, b)
map < pair <int,int> , int > lsd;
vector <int> edge [MAXN];
pair <int,int> was[MAXN];
bool wss[MAXN][MAXN];
int i,j,n,m,k,a,b,c;
vector <int> ans;
int lst[MAXN][MAXN];
pair <int,int> null_pair;

struct order{
    int last;
    int v;
    int type;
};

inline bool can(order t,int v) {
    if (lsd.find(mp(t.last,t.v)) != lsd.end()) {
        if (lsd[mp(t.last,t.v)] == v) {
            return false;
        }
    }
    return true;
}

bool can(int a, int b, int c) {
    order t;
    t.last = a;
    t.v = b;
    return can(t,c);
}

void dfs(int a,int b) {
    if (lst[a][b] >  -1) {
        ans.push_back(b);
        dfs(lst[a][b],a);
    }
}

void bfs(int v) {
    int i,j;
    order t,tt;
    t.last = 0;
    t.v = v;
    queue <order> q;
    q.push(t);
    was[v] = mp(-1,0);
    lst[0][1] = -1;
    while (!q.empty()) {
        t = q.front();
        q.pop();
        for (i = 0; i < edge[t.v].size(); ++i) {
            if (!(wss[t.v][edge[t.v][i]])) {
                if (can(t,edge[t.v][i])) {
                    was[edge[t.v][i]] = mp(t.v,0);
                    tt.last = t.v;
                    tt.v = edge[t.v][i];
                    q.push(tt);
                    wss[t.v][edge[t.v][i]] = 1;
                    lst[t.v][edge[t.v][i]] = t.last;
                    if (edge[t.v][i]==n) {
                        dfs(t.v,edge[t.v][i]);
                        return;
                    }
                }
            }
        }
    }
}

int main()
{

    cin >> n >> m >> k;
    for (i = 0; i < m; ++i) {
        cin >> a >> b;
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    for (i =0; i < k; ++i) {
        cin >> a >> b >> c;
        lsd[mp(a,b)] = c;
    }

    bfs(1);

    if (ans.size()>0) {
        reverse(ans.begin(),ans.end());
        cout << ans.size() << "\n1 ";
        for (i = 0; i < ans.size(); ++i) {
            cout << ans[i] << " ";
        }
    } else {
        cout << "-1";
    }
    return 0;
}


#include <iostream>
#include <fstream>

#include <vector>
#include <queue>
#include <set>

using namespace std;

struct three{
    int fr;
    int se;
    int th;
};

const int MAXN = 5001;
#define mp(a, b) make_pair(a, b)
set <three> lsd;
vector <int> edge [MAXN];
pair <int,int> was[MAXN];
bool wss[MAXN][MAXN];
int i,j,n,m,k,a,b,c;
vector <int> ans;
int lst[MAXN][MAXN];
pair <int,int> null_pair;

struct order{
    int last;
    int v;
    int type;
};

bool operator <(three a,three b){
    if (a.fr!=b.fr) {
        return a.fr < b.fr;
    } else {
        if (a.se!=b.se) {
            return a.se < b.se;
        } else {
            return a.th < b.th;
        }
    }
}
inline three make_three(int a,int b,int c) {
    three t;
    t.fr = a;
    t.se = b;
    t.th = c;
    return t;
}

inline bool can(order t,int v) {
    if (lsd.find(make_three(t.last,t.v,v)) != lsd.end()) {
            return false;
    }
    return true;
}

void dfs(int a,int b) {
    if (lst[a][b] >  -1) {
        ans.push_back(b);
        dfs(lst[a][b],a);
    }
}

void bfs(int v) {
    int i,j;
    order t,tt;
    t.last = 0;
    t.v = v;
    queue <order> q;
    q.push(t);
    was[v] = mp(-1,0);
    lst[0][1] = -1;
    while (!q.empty()) {
        t = q.front();
        q.pop();
        for (i = 0; i < edge[t.v].size(); ++i) {
            if (!(wss[t.v][edge[t.v][i]])) {
                if (can(t,edge[t.v][i])) {
                    was[edge[t.v][i]] = mp(t.v,0);
                    tt.last = t.v;
                    tt.v = edge[t.v][i];
                    q.push(tt);
                    wss[t.v][edge[t.v][i]] = 1;
                    lst[t.v][edge[t.v][i]] = t.last;
                    if (edge[t.v][i]==n) {
                        dfs(t.v,edge[t.v][i]);
                        return;
                    }
                }
            }
        }
    }
}

int main()
{

    cin >> n >> m >> k;
    for (i = 0; i < m; ++i) {
        cin >> a >> b;
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    for (i =0; i < k; ++i) {
        cin >> a >> b >> c;
        lsd.insert(make_three(a,b,c));
    }

    bfs(1);

    if (ans.size()>0) {
        reverse(ans.begin(),ans.end());
        cout << ans.size() << "\n1 ";
        for (i = 0; i < ans.size(); ++i) {
            cout << ans[i] << " ";
        }
    } else {
        cout << "-1";
    }
    return 0;
}


#include <iostream>
#include <fstream>

#include <vector>
#include <queue>
#include <map>

using namespace std;

const int MAXN = 3000;
#define mp(a, b) make_pair(a, b)
map < pair <int,int> , int > lsd;
vector <int> edge [MAXN];
pair <int,int> was[MAXN];
int i,j,n,m,k,a,b,c;
vector <int> ans;
pair <int,int> null_pair;

struct order{
    int last;
    int v;
};

inline bool can(order t,int v) {
    if (lsd.find(mp(t.last,t.v)) != lsd.end()) {
        if (lsd[mp(t.last,t.v)] == v) {
            return false;
        }
    }
    return true;
}

bool can(int a, int b, int c) {
    order t;
    t.last = a;
    t.v = b;
    return can(t,c);
}

void bfs(int v) {
    int i,j;
    order t,tt;
    t.last = 0;
    t.v = v;
    queue <order> q;
    q.push(t);
    was[v] = mp(-1,0);
    while (!q.empty()) {
        t = q.front();
        q.pop();
        for (i = 0; i < edge[t.v].size(); ++i) {
            if (was[edge[t.v][i]]==null_pair) {
                if (can(t,edge[t.v][i])) {
                    was[edge[t.v][i]] = mp(t.v,0);
                    tt.last = t.v;
                    tt.v = edge[t.v][i];
                    q.push(tt);
                } else {
                    for (j = 0; j < edge[t.v].size(); ++j) {
                        if (can(t,edge[t.v][j])&&can(t.v,edge[t.v][i],edge[t.v][i])&&can(edge[t.v][j],t.v,edge[t.v][i])) {
                            was[edge[t.v][i]] = mp(t.v,edge[t.v][j]);
                            tt.last = t.v;
                            tt.v = edge[t.v][i];
                            q.push(tt);
                            j = edge[t.v].size();
                        }
                    }
                }
            }
        }
    }
}

void dfs(int v) {
    if (was[v].first >  -1) {
        if (was[v].second == 0) {
            ans.push_back(was[v].first);
        } else {
            ans.push_back(was[v].first);
            ans.push_back(was[v].second);
            ans.push_back(was[v].first);
        }
        dfs(was[v].first);
    }
}

int main()
{

    cin >> n >> m >> k;
    for (i = 0; i < m; ++i) {
        cin >> a >> b;
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    for (i =0; i < k; ++i) {
        cin >> a >> b >> c;
        lsd[mp(a,b)] = c;
    }

    bfs(1);

    if (was[n]!=mp(0,0)) {
        dfs(n);
        reverse(ans.begin(),ans.end());
        cout << ans.size() << "\n";
        ans.push_back(n);
        for (i = 0; i < ans.size(); ++i) {
            cout << ans[i] << " ";
        }
    } else {
        cout << "-1";
    }
    return 0;
}