#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <sstream>
#include <numeric>
#include <functional>
#include <set>
#include <cmath>
#include <stack>
#include <fstream>
#include <cassert>
#ifdef HOME_PC
#include <ctime>
#endif
using namespace std;

#pragma comment(linker,"/stack:16000000")
#pragma warning (disable : 4996)

#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)v.size()
#define mset(A,x) memset((A),(x),sizeof(A))
#define FOR(i,start,N) for(int i=(start);i<(N);++i)
#define FORSZ(i,start,v) FOR(i,start,SZ(v))
#define REPSZ(i,v) FORSZ(i,0,v)
#define FORE(i,start,N) FOR(i,start,N+1)
#define make_unique(v) v.resize(unique(ALL(v))-v.begin())
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define adebug(A,N) FOR(i,0,N) cout<<#A<<"["<<i<<"] = "<<A[i]<<endl;
#define adebug2d(a,n,m) FOR(i,0,n) { FOR(j,0,m) { cout<<a[i][j]<<" ";} cout<<endl;}
#define vdebug(v) REPSZ(i,v) cout<<#v<<"["<<i<<"] = "<<v[i]<<endl;
#define selfx(x,f,a) x = f(x,a)
#define sqr(x) ((x)*(x))

typedef pair<int,int> pii;
typedef long long i64;
typedef vector<int> VI; typedef vector< vector<int> > VVI;
typedef vector<string> VS;

const int inf = 1<<25;
const double eps = 1e-9;

const int MAXN = 3100;

int par[MAXN][MAXN];
int d[MAXN][MAXN];

int main()
{
#ifdef HOME_PC
    //freopen ("input.txt","r",stdin);
    //freopen ("in.txt","r",stdin);
    //freopen ("output.txt","w",stdout);
#endif

    int n,m,k;
    cin>>n>>m>>k;

    VVI adj(n+1);

    FOR(i,0,m)
    {
        int u,v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    map<pii, set<int> > triples;
    FOR(i,0,k)
    {
        int a,b,c;
        cin>>a>>b>>c;
        triples[pii(a,b)].insert(c);
    }

    mset(par,-1);

    queue<pii> Q;

    d[0][1] = 0;
    Q.push(pii(0,1));

    int pmin = -1;
    while(!Q.empty()&&pmin == -1)
    {
        int p = Q.front().first, u = Q.front().second;
        Q.pop();

        int curd = d[p][u];

        map<pii, set<int> >::iterator it = triples.find(pii(p,u));

        REPSZ(i,adj[u])
        {
            int v = adj[u][i];
            // check if forbidden
            if(it != triples.end() && it->second.count(v))
                continue;
            if(v == n)
                pmin = u;
            if(par[u][v] == -1)
            {
                par[u][v] = p;
                d[u][v] = curd+1;
                Q.push(pii(u,v));
            }
        }
    }

    if(pmin == -1)
    {
        printf("-1\n");
        return 0;
    }

    VI ans;

    ans.push_back(n);
    int v = n;
    while(pmin>0)
    {
        ans.push_back(pmin);
        int nxt = par[pmin][v];
        v = pmin;
        pmin = nxt;
    }

    reverse(ALL(ans));
    cout<<ans.size()-1<<endl;
    REPSZ(i,ans)
        cout<<ans[i]<<" ";
    cout<<endl;

#ifdef HOME_PC
    cerr<<endl<<"Execution time = "<<clock()<<" ms"<<endl;
#endif
    return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 30 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return false;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
stack<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					printf("%d ", st.top());
					//cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
hash_set<long long> hst;

const long long base = 10000;
long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	int p = 0, bp = 0;
	while (p < 3) {
		if (bor[bp].find(v[p]) == bor[bp].end()) return false;
		bp = bor[bp][v[p]];
		++p;
	}
	return p == 3;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	int p = 0, bp = 0;
	while (p < 3) {
		if (bor[bp].find(v[p]) == bor[bp].end()) return false;
		bp = bor[bp][v[p]];
		++p;
	}
	return p == 3;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[300000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	if (v[0] == v[1]) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	if (v[0] == v[1]) return false;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					printf("%d ", st[abc]);
					//cout << st.top() << " ";
					//st.pop();
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
stack<int> st;
hash_set<long long> hst;

const long long base = 10000;
long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					printf("%d ", st.top());
					//cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					cout << st[abc] << " ";
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	int p = 0, bp = 0;
	while (p < 3) {
		if (bor[bp].find(v[p]) == bor[bp].end()) return false;
		bp = bor[bp][v[p]];
		++p;
	}
	return p == 3;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(a, b, c)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
set<int> mat[maxn][maxn];
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat[a][b].insert(c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(mat[par][node].find(to) == mat[par][node].end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

struct trio {
	int a, b, c;
};

const int maxn = 3000 + 10; // !! 3000 + 10
set<struct trio> mat;
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		struct trio t;
		t.a = a;
		t.b = b;
		t.c = c;
		mat.insert(t);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			struct trio t;
			t.a = par;
			t.b = node;
			t.c = to;
			if (!(mat.find(t) == mat.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 30 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return false;
	v[0] = a, v[1] = b, v[2] = c;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
hash_set<pair<pair<int, int>, int> > mat;
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat.insert(make_pair(make_pair(a, b), c));
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(mat.find(make_pair(make_pair(par, node), to)) == mat.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 30 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (i == j) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (i == j) return false;
	v[0] = a, v[1] = b, v[2] = c;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					//cout << st[abc] << " ";
					printf("%d ", st[abc]);
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
set<pair<pair<int, int>, int> > mat;
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat.insert(make_pair(make_pair(a, b), c));
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(mat.find(make_pair(make_pair(par, node), to)) == mat.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
pair<pair<int, int>, int> mat[100000 + 10];
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat[i] = make_pair(make_pair(a, b), c);
	}
	sort(mat, mat + k);

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (binary_search(mat, mat + k, make_pair(make_pair(par, node), to))) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	if (a == b) return false;
	v[0] = a, v[1] = b, v[2] = c;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					printf("%d ", st[abc]);
					//cout << st.top() << " ";
					//st.pop();
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> mat[maxn][maxn];
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat[a][b].push_back(c);
	}
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			sort(mat[i][j].begin(), mat[i][j].end());

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (binary_search(mat[par][node].begin(), mat[par][node].end(), to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	const int maxn = 3000 + 10; // !! 3000 + 10

	vector<int> g[maxn];
	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> a >> b;
		--a, --b;
		g[a].push_back(b);
		g[b].push_back(a);
	}

	hash_set<int> mat[maxn][maxn];
	for (int i = 0; i < k; ++i) {
		int a, b, c;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat[a][b].insert(c);
	}

	vector<pair<int, int> > que;
	int dst[maxn][maxn];
	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(mat[par][node].find(to) == mat[par][node].end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				stack<int> st;
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					printf("%d ", st[abc]);
					//cout << st.top() << " ";
					//st.pop();
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return false;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 >= dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				std::cout << st.size() + 1 << endl;
				std::cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					printf("%d ", st[abc]);
					//cout << st.top() << " ";
					//st.pop();
				}
				std::cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	std::cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[300000 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i)
		for (int j = i + 1; j < 3; ++j)
			if (v[i] == v[j]) return false;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
vector<int> st;
hash_set<long long> hst;

const long long base = 10000;
inline long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push_back(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				reverse(st.begin(), st.end());
				for (int abc = 0, sz = st.size(); abc < sz; ++abc) {
					printf("%d ", st[abc]);
					//cout << st.top() << " ";
					//st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
hash_set<long long> hst;

const long long base = 10000;
long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					printf("%d ", st.top());
					//cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
vector<int> g[maxn];
pair<int, int> que[maxn * maxn];
int dst[maxn][maxn];
stack<int> st;
hash_set<long long> hst;

const long long base = 10000;
long long hash_(long long a, long long b, long long c) {
	return ((base + a) * base + b) * base + c;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	//cin >> n >> m >> k;
	scanf("%d%d%d", &n, &m, &k);

	for (int i = 0; i < m; ++i) {
		int a, b;
		//cin >> 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;
		//cin >> a >> b >> c;
		scanf("%d%d%d", &a, &b, &c);
		--a, --b, --c;
		hst.insert(hash_(a, b, c));
	}

	const int inf = (int)1e9;

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	int lt, rt;
	lt = 0, rt = 1;
	que[0] = make_pair(0, 0);

	const int destination = n - 1;
	while (lt < rt) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(hst.find(hash_(par, node, to)) == hst.end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					printf("%d ", st.top());
					//cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que[rt++] = make_pair(to, lt - 1);
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 3000 + 10; // !! 3000 + 10
hash_set<int> mat[maxn][maxn];
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		mat[a][b].insert(c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (!(mat[par][node].find(to) == mat[par][node].end())) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <hash_set>
#include <hash_map>
#include <algorithm>

using namespace std;

const int maxn = 30 + 10; // !! 3000 + 10
vector<int> g[maxn];
vector<pair<int, int> > que;
int dst[maxn][maxn];
stack<int> st;
map<int, int> bor[100 + 10];
int borsz = 0;

int v[3];
void add(int a, int b, int c) {
	int bp = 0;
	v[0] = a, v[1] = b, v[2] = c;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) {
			bor[bp][v[i]] = borsz;
			++borsz;
		}
		bp = bor[bp][v[i]];
	}
}

bool offer(int a, int b, int c) {
	if (a == b) return false;
	v[0] = a, v[1] = b, v[2] = c;
	int bp = 0;
	for (int i = 0; i < 3; ++i) {
		if (bor[bp].find(v[i]) == bor[bp].end()) return false;
		bp = bor[bp][v[i]];
	}
	return true;
}

int main() {

#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, k;
	cin >> n >> m >> k;

	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> 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;
		cin >> a >> b >> c;
		--a, --b, --c;
		add(a, b, c);
	}

	const int inf = (int)1e9;

	int lt = 0;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			dst[i][j] = inf;

	dst[0][0] = 0;
	que.push_back(make_pair(0, 0));

	const int destination = n - 1;
	while (lt < que.size()) {
		int node = que[lt].first;
		int par = que[que[lt].second].first;
		++lt;

		for (int i = 0, sz = g[node].size(); i < sz; ++i) {
			int to = g[node][i];
			if (offer(par, node, to)) continue;
			if (dst[par][node] + 1 > dst[node][to]) continue;

			if (to == destination) {
				--lt;
				while (lt != 0) {
					st.push(que[lt].first + 1);
					lt = que[lt].second;
				}

				cout << st.size() + 1 << endl;
				cout << 1 << " ";
				while (!st.empty()) {
					cout << st.top() << " ";
					st.pop();
				}
				cout << n;

				return 0;
			}

			dst[node][to] = dst[par][node] + 1;
			que.push_back(make_pair(to, lt - 1));
		}
	}

	cout << -1;

	return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define FOR(i, a, b) for(int i = a; i < b; i++)
struct triple{
    int a, b, c;
    triple(int a_ = 0, int b_ = 0, int c_ = 0){
        a = a_;
        b = b_;
        c = c_;
    }
    bool operator < (const triple &tp) const{
        if(a < tp.a)
            return true;
        if(a == tp.a){
            if(b < tp.b)
                return true;
            if(b == tp.b && c < tp.c)
                return true;
        }
        return false;
    }
};
#define PII pair<int, int>
queue<PII> q;
int d[3001][3001], path[3001][3001];
int n, m, k;
vector<int> gr[3001];
map<triple, bool> mp;
int main(){
    cin >> n >> m >> k;
    int a, b, c;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &a, &b);
        gr[a - 1].push_back(b - 1);
        gr[b - 1].push_back(a - 1);
    }
    FOR(i, 0, k){
        scanf("%d%d%d", &a, &b, &c);
        mp[triple(a - 1, b - 1, c - 1)] = 1;
    }
    memset(d, -1, sizeof d);
    d[0][0] = 0;
    q.push(PII(0, 0));
    int p1 = -1;
    while(!q.empty()){
        PII p = q.front();
        q.pop();
        if(p.second == n - 1){
            p1 = p.first;
            break;
        }
        int x = p.first, y = p.second;
        triple tp(x, y);
        for(int i = 0; i < gr[y].size(); i++){
            tp.c = gr[y][i];
            if(d[y][gr[y][i]] == -1 && !mp[tp]){
                q.push(PII(y, gr[y][i]));
                d[y][gr[y][i]] = d[x][y] + 1;
                path[y][gr[y][i]] = x;
            }
        }
    }
    if(p1 == -1)
        cout << -1 << endl;
    else{
        cout << d[p1][n - 1] << endl;
        int a[3001], sz = 0;
        int p2 = n - 1;
        while(p1 != p2){
            a[sz++] = p1;
            int x = p1;
            p1 = path[p1][p2];
            p2 = x;
        }
        for(int i = sz - 1; i >= 0; i--)
            printf("%d ", a[i] + 1);
        cout << n << endl;
    }

    return 0;
}


#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <hash_set>

// Types definition
//
typedef signed char                 int8;
typedef unsigned char               uint8;
typedef signed short                int16;
typedef unsigned short              uint16;
typedef signed long                 int32;
typedef unsigned long               uint32;
typedef signed long long            int64;
typedef unsigned long long          uint64;

typedef std::vector<size_t>         SizeTVector;
typedef std::set<size_t>            SizeTSet;
typedef std::multiset<size_t>       SizeTMultiset;

typedef std::vector<std::string>    StringVector;
typedef std::set<std::string>       StringSet;
typedef std::multiset<std::string>  StringMultiset;

// Auxiliary functions definition
//
inline void DoNothing() { }
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double eps = 1.0e-8;
inline double IsEqual(const double a, const double b) { return Abs(a - b) < eps; }
inline double IsGreater(const double a, const double b) { return a > b + eps; }
inline double IsLess(const double a, const double b) { return a + eps < b; }

struct Rand
{
    uint32 z_, w_;
    uint32 get32() { z_ = 36969 * (z_ & 65535) + (z_ >> 16); w_ = 18000 * (w_ & 65535) + (w_ >> 16); return (z_ << 16) + (w_ & 65535); }
    void Reset() { z_ = 1; w_ = 1; }
    Rand() { Reset(); }
};

template <typename T> inline std::vector<std::vector<T> > CreateVector2d(const size_t rowCnt, const size_t colCnt)
{
    return std::vector<std::vector<T> > (rowCnt, std::vector<T>(colCnt));
}

#ifndef ONLINE_JUDGE
#define PRINT(a) std::cout << '\t' << #a << " = " << (a) << "; "
#define NEWLINE() std::cout << std::endl;
#else //ONLINE_JUDGE
#define PRINT(a) DoNothing()
#define NEWLINE() DoNothing()
#endif //ONLINE_JUDGE

// Auxiliary functions forward definition
//
void Prepare();

class StopWatchEx
{
public:
    StopWatchEx();
    ~StopWatchEx();

private:
    struct Data;
    Data *pData;
};

// Local functions definition
//
typedef uint16  VertexId;
typedef stdext::hash_set<VertexId>              VertexHashSet;
typedef std::vector<VertexId>                   VertexVector;
typedef std::vector<std::vector<VertexId> >     VertexVector2d;

struct DataField
{
    uint16 be;
    uint32 minWay;

    DataField(): be(0), minWay(0) {}
};

typedef std::vector<std::vector<DataField> >    DataFieldVector2d;

struct TwoPoints
{
    VertexId a, b;

    bool operator<(const TwoPoints& rval) const
    {
        if (a < rval.a) { return true; }
        else if (rval.a < a) { return false; }
        else { return b < rval.b; }
    }

    TwoPoints(const VertexId _a, const VertexId _b): a(_a), b(_b) {}
};

typedef std::map<TwoPoints, VertexHashSet>      MapEdgeToVertexSet;

typedef stdext::hash_set<size_t>                SizeTHashSet;
typedef std::vector<std::vector<size_t> >       SizeTVector2d;
typedef std::vector<std::set<size_t> >          SizeTSetVector;
typedef std::vector<std::vector<SizeTHashSet> > HashSetVector2d;

struct Edge
{
    VertexId from;
    VertexId to;
    uint32 minWayPrev;
    Edge(const VertexId _from, const VertexId _to, const uint32 _minWayPrev): from(_from), to(_to), minWayPrev(_minWayPrev) {}
};

typedef std::deque<Edge>                        EdgeDeque;

template<typename T>
inline bool IsFound(const stdext::hash_set<T>& container, const T val)
{
    return (container.find(val) != container.end());
}

inline bool IsForbidden(const MapEdgeToVertexSet& mapping, const TwoPoints& ab, const VertexId c)
{
    MapEdgeToVertexSet::const_iterator pI = mapping.find(ab);
    if (pI != mapping.end() &&
        pI->second.find(c) != pI->second.end())
    {
        return true;
    }
    else
    {
        return false;
    }
}

inline bool IsForbidden(const MapEdgeToVertexSet& mapping, const VertexId a, const VertexId b, const VertexId c)
{
    return IsForbidden(mapping, TwoPoints(a, b), c);
}

inline bool IsLinked(const VertexVector2d& linksSorted, const VertexId a, const VertexId b)
{
    const VertexVector& links_a = linksSorted[a];
    return std::binary_search(links_a.begin(), links_a.end(), b);
}

bool Solve(bool bCheckInputStream = false)
{
    // First input operation
    //
    VertexId n;
    size_t m, k;
    std::cin >> n >> m >> k;

    if (bCheckInputStream && !std::cin)
    {
        return false;
    }

    //StopWatchEx _sw;

    VertexVector2d links(n);
    MapEdgeToVertexSet forbidden;
    // Other input operations and calculations
    //

    for (size_t i = 0; i < m; ++i)
    {
        VertexId x, y;
        std::cin >> x >> y;
        --x; --y;
        links[x].push_back(y);
        links[y].push_back(x);
    }

    for (VertexId i = 0; i < n; i++)
    {
        std::sort(links[i].begin(), links[i].end());
    }

    for (size_t i = 0; i < k; ++i)
    {
        VertexId a, b, c;
        std::cin >> a >> b >> c;
        --a; --b; --c;
        forbidden[TwoPoints(a, b)].insert(c);
    }

    DataFieldVector2d data = CreateVector2d<DataField>(n, n);

    const VertexId startId = 0;
    const VertexId stopId = n-1;

    EdgeDeque queue;
    // first step
    for(size_t i = 0; i < n; i++)
    {
        data[i][startId].minWay = 0;
        data[i][startId].be = 1;
    }
    for(size_t i = 0; i < links[startId].size(); ++i)
    {
        queue.push_back(Edge(startId, links[startId][i], 0));
    }

    // other steps
    while (!queue.empty())
    {
        const size_t queueSize = queue.size();

        bool bStopFound = false;
        for (size_t i = 0; i < queueSize && !bStopFound; i++)
        {
            const Edge nextEdge = queue.at(0);
            queue.pop_front();

            if (!data[nextEdge.from][nextEdge.to].be)
            {
                data[nextEdge.from][nextEdge.to].be = 1;
                data[nextEdge.from][nextEdge.to].minWay = nextEdge.minWayPrev + 1;

                if (nextEdge.to == stopId)
                {
                    bStopFound = true;
                }
                else
                {
                    const TwoPoints nextEdgeTP(nextEdge.from, nextEdge.to);
                    for (size_t i = 0; i < links[nextEdge.to].size(); i++)
                    {
                        const VertexId nextNextId = links[nextEdge.to][i];
                        if (!data[nextEdge.to][nextNextId].be)
                        {
                            if (!IsForbidden(forbidden, nextEdgeTP, nextNextId))
                            {
                                queue.push_back(Edge(nextEdge.to, nextNextId, data[nextEdge.from][nextEdge.to].minWay));
                            }
                        }
                    }
                }
            }
        }

        if (bStopFound)
        {
            break;
        }
    }

    VertexVector sequence;
    bool bReached = false;
    uint32 stepCnt = 0;

    for (size_t i = 0; i < n; ++i)
    {
        if (data[i][stopId].be && (!bReached || data[i][stopId].minWay < stepCnt))
        {
            bReached = true;
            stepCnt = data[i][stopId].minWay;
        }
    }

    if (bReached)
    {
        VertexId curId = stopId;
        sequence.push_back(curId);

        while (curId != startId)
        {
            bool bNextStepFound = false;
            VertexId prevId = 0;
            for (VertexId i = 0; i < n; ++i)
            {
                if (IsLinked(links, i, curId) && data[i][curId].minWay == stepCnt)
                {
                    bNextStepFound = true;
                    prevId = i;
                    break;
                }
            }
            if (!bNextStepFound)
            {
                break;
            }

            curId = prevId;
            sequence.push_back(curId);
            --stepCnt;
        }

        std::reverse(sequence.begin(), sequence.end());

        std::cout << sequence.size() - 1 << std::endl;
        for(size_t i = 0; i < sequence.size(); ++i)
        {
            std::cout << sequence[i] + 1 << ' ';
        }
        std::cout << std::endl;
    }
    else
    {
        std::cout << "-1" << std::endl;
    }

    return true;
    // End of all calculations
}

int main()
{
    Prepare();

#if defined(ONLINE_JUDGE)
    Solve();
#else //defined(ONLINE_JUDGE)
    while (Solve(true)) { }
    //Solve();
#endif //defined(ONLINE_JUDGE)
}

// Test-specific stuff

#if !defined(ONLINE_JUDGE)
#endif // !defined(ONLINE_JUDGE)

#if !defined(ONLINE_JUDGE)
#include <windows.h>
#endif //!defined(ONLINE_JUDGE)

struct StopWatchEx::Data
{
#if !defined(ONLINE_JUDGE)
    FILETIME timeStartSystem;
    FILETIME timeStartUser;
#endif //!defined(ONLINE_JUDGE)
};

StopWatchEx::StopWatchEx()
{
#if !defined(ONLINE_JUDGE)
    pData = new Data();
    FILETIME dummy;
    GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &dummy, &pData->timeStartUser);
    GetSystemTimeAsFileTime(&pData->timeStartSystem);
#endif //!defined(ONLINE_JUDGE)
}

#if !defined(ONLINE_JUDGE)
ULONGLONG FileTimeToU64(const FILETIME& time)
{
    return ((ULONGLONG)time.dwHighDateTime << 32) | time.dwLowDateTime;
}

ULONGLONG GetTimeDiffMs(const FILETIME& first, const FILETIME& second)
{
    return ((FileTimeToU64(first) - FileTimeToU64(second)) + 9999) / 10000;
}
#endif // !defined(ONLINE_JUDGE)

StopWatchEx::~StopWatchEx()
{
#if !defined(ONLINE_JUDGE)
    FILETIME timeCreated;
    FILETIME timeStopUser;
    FILETIME dummy;
    GetProcessTimes(GetCurrentProcess(), &timeCreated, &dummy, &dummy, &timeStopUser);

    FILETIME timeCurrent;
    GetSystemTimeAsFileTime(&timeCurrent);

    std::cout << std::setw(20) << "Total process = " << GetTimeDiffMs(timeCurrent, timeCreated) << " ms" << std::endl;
    std::cout << std::setw(20) << "UserTime diff = " << GetTimeDiffMs(timeStopUser, pData->timeStartUser) << " ms" << std::endl;
    std::cout << std::setw(20) << "SysTime diff = " << GetTimeDiffMs(timeCurrent, pData->timeStartSystem) << " ms" << std::endl;
    std::cout << std::endl;

    delete pData;
#endif //!defined(ONLINE_JUDGE)
}

void Prepare()
{
#if !defined(ONLINE_JUDGE)
    SetProcessAffinityMask(GetCurrentProcess(), 1);
#endif //!defined(ONLINE_JUDGE)
}


#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <hash_set>

// Types definition
//
typedef signed char                 int8;
typedef unsigned char               uint8;
typedef signed short                int16;
typedef unsigned short              uint16;
typedef signed long                 int32;
typedef unsigned long               uint32;
typedef signed long long            int64;
typedef unsigned long long          uint64;

typedef std::vector<size_t>         SizeTVector;
typedef std::set<size_t>            SizeTSet;
typedef std::multiset<size_t>       SizeTMultiset;

typedef std::vector<std::string>    StringVector;
typedef std::set<std::string>       StringSet;
typedef std::multiset<std::string>  StringMultiset;

// Auxiliary functions definition
//
inline void DoNothing() { }
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double eps = 1.0e-8;
inline double IsEqual(const double a, const double b) { return Abs(a - b) < eps; }
inline double IsGreater(const double a, const double b) { return a > b + eps; }
inline double IsLess(const double a, const double b) { return a + eps < b; }

struct Rand
{
    uint32 z_, w_;
    uint32 get32() { z_ = 36969 * (z_ & 65535) + (z_ >> 16); w_ = 18000 * (w_ & 65535) + (w_ >> 16); return (z_ << 16) + (w_ & 65535); }
    void Reset() { z_ = 1; w_ = 1; }
    Rand() { Reset(); }
};

template <typename T> inline std::vector<std::vector<T> > CreateVector2d(const size_t rowCnt, const size_t colCnt)
{
    return std::vector<std::vector<T> > (rowCnt, std::vector<T>(colCnt));
}

#ifndef ONLINE_JUDGE
#define PRINT(a) std::cout << '\t' << #a << " = " << (a) << "; "
#define NEWLINE() std::cout << std::endl;
#else //ONLINE_JUDGE
#define PRINT(a) DoNothing()
#define NEWLINE() DoNothing()
#endif //ONLINE_JUDGE

// Auxiliary functions forward definition
//
void Prepare();

class StopWatchEx
{
public:
    StopWatchEx();
    ~StopWatchEx();

private:
    struct Data;
    Data *pData;
};

// Local functions definition
//
typedef uint16  VertexId;
typedef stdext::hash_set<VertexId>              VertexHashSet;
typedef std::vector<VertexId>                   VertexVector;
typedef std::vector<std::vector<VertexId> >     VertexVector2d;

struct DataField
{
    uint16 be;
    uint32 minWay;

    DataField(): be(0), minWay(0) {}
};

typedef std::vector<std::vector<DataField> >    DataFieldVector2d;

struct TwoPoints
{
    VertexId a, b;

    bool operator<(const TwoPoints& rval) const
    {
        if (a < rval.a) { return true; }
        else if (rval.a < a) { return false; }
        else { return b < rval.b; }
    }

    TwoPoints(const VertexId _a, const VertexId _b): a(_a), b(_b) {}
};

typedef std::map<TwoPoints, VertexHashSet>      MapEdgeToVertexSet;

typedef stdext::hash_set<size_t>                SizeTHashSet;
typedef std::vector<std::vector<size_t> >       SizeTVector2d;
typedef std::vector<std::set<size_t> >          SizeTSetVector;
typedef std::vector<std::vector<SizeTHashSet> > HashSetVector2d;

struct Edge
{
    VertexId from;
    VertexId to;
    uint32 minWayPrev;
    Edge(const VertexId _from, const VertexId _to, const uint32 _minWayPrev): from(_from), to(_to), minWayPrev(_minWayPrev) {}
};

typedef std::deque<Edge>                        EdgeDeque;

template<typename T>
inline bool IsFound(const stdext::hash_set<T>& container, const T val)
{
    return (container.find(val) != container.end());
}

inline bool IsForbidden(const MapEdgeToVertexSet& mapping, const TwoPoints& ab, const VertexId c)
{
    MapEdgeToVertexSet::const_iterator pI = mapping.find(ab);
    if (pI != mapping.end() &&
        pI->second.find(c) != pI->second.end())
    {
        return true;
    }
    else
    {
        return false;
    }
}

inline bool IsForbidden(const MapEdgeToVertexSet& mapping, const VertexId a, const VertexId b, const VertexId c)
{
    return IsForbidden(mapping, TwoPoints(a, b), c);
}

inline bool IsLinked(const VertexVector2d& linksSorted, const VertexId a, const VertexId b)
{
    const VertexVector& links_a = linksSorted[a];
    return std::binary_search(links_a.begin(), links_a.end(), b);
}

bool Solve(bool bCheckInputStream = false)
{
    // First input operation
    //
    VertexId n;
    size_t m, k;
    std::cin >> n >> m >> k;

    if (bCheckInputStream && !std::cin)
    {
        return false;
    }

    StopWatchEx _sw;

    VertexVector2d links(n);
    MapEdgeToVertexSet forbidden;
    // Other input operations and calculations
    //

    for (size_t i = 0; i < m; ++i)
    {
        VertexId x, y;
        std::cin >> x >> y;
        --x; --y;
        links[x].push_back(y);
        links[y].push_back(x);
    }

    for (VertexId i = 0; i < n; i++)
    {
        std::sort(links[i].begin(), links[i].end());
    }

    for (size_t i = 0; i < k; ++i)
    {
        VertexId a, b, c;
        std::cin >> a >> b >> c;
        --a; --b; --c;
        forbidden[TwoPoints(a, b)].insert(c);
    }

    DataFieldVector2d data = CreateVector2d<DataField>(n, n);

    const VertexId startId = 0;
    const VertexId stopId = n-1;

    EdgeDeque queue;
    // first step
    for(size_t i = 0; i < n; i++)
    {
        data[i][startId].minWay = 0;
        data[i][startId].be = 1;
    }
    for(size_t i = 0; i < links[startId].size(); ++i)
    {
        queue.push_back(Edge(startId, links[startId][i], 0));
    }

    // other steps
    while (!queue.empty())
    {
        const size_t queueSize = queue.size();

        for (size_t i = 0; i < queueSize; i++)
        {
            const Edge nextEdge = queue.at(0);
            const size_t nextId = nextEdge.to;
            queue.pop_front();

            if (!data[nextEdge.from][nextEdge.to].be ||
                data[nextEdge.from][nextEdge.to].minWay > nextEdge.minWayPrev + 1)
            {
                data[nextEdge.from][nextEdge.to].be = 1;
                data[nextEdge.from][nextEdge.to].minWay = nextEdge.minWayPrev + 1;

                if (nextId != stopId)
                {
                    for (size_t i = 0; i < links[nextId].size(); i++)
                    {
                        const VertexId nextNextId = links[nextId][i];
                        if (!data[nextEdge.to][nextNextId].be)
                        {
                            if (!IsForbidden(forbidden, TwoPoints(nextEdge.from, nextEdge.to), nextNextId))
                            {
                                queue.push_back(Edge(nextEdge.to, nextNextId, data[nextEdge.from][nextEdge.to].minWay));
                            }
                        }
                    }
                }
                else
                {
                    queue.clear();
                }
            }
        }
    }

    VertexVector sequence;
    bool bReached = false;
    uint32 stepCnt = 0;

    for (size_t i = 0; i < n; ++i)
    {
        if (data[i][stopId].be && (!bReached || data[i][stopId].minWay < stepCnt))
        {
            bReached = true;
            stepCnt = data[i][stopId].minWay;
        }
    }

    if (bReached)
    {
        VertexId curId = stopId;
        sequence.push_back(curId);

        while (curId != startId)
        {
            bool bNextStepFound = false;
            VertexId prevId = 0;
            for (VertexId i = 0; i < n; ++i)
            {
                if (IsLinked(links, i, curId) && data[i][curId].minWay == stepCnt)
                {
                    bNextStepFound = true;
                    prevId = i;
                    break;
                }
            }
            if (!bNextStepFound)
            {
                break;
            }

            curId = prevId;
            sequence.push_back(curId);
            --stepCnt;
        }

        std::reverse(sequence.begin(), sequence.end());

        std::cout << sequence.size() - 1 << std::endl;
        for(size_t i = 0; i < sequence.size(); ++i)
        {
            std::cout << sequence[i] + 1 << ' ';
        }
    }
    else
    {
        std::cout << "-1" << std::endl;
    }

    return true;
    // End of all calculations
}

int main()
{
    Prepare();

#if defined(ONLINE_JUDGE)
    Solve();
#else //defined(ONLINE_JUDGE)
    while (Solve(true)) { }
    //Solve();
#endif //defined(ONLINE_JUDGE)
}

// Test-specific stuff

#if !defined(ONLINE_JUDGE)
#endif // !defined(ONLINE_JUDGE)

#if !defined(ONLINE_JUDGE)
#include <windows.h>
#endif //!defined(ONLINE_JUDGE)

struct StopWatchEx::Data
{
#if !defined(ONLINE_JUDGE)
    FILETIME timeStartSystem;
    FILETIME timeStartUser;
#endif //!defined(ONLINE_JUDGE)
};

StopWatchEx::StopWatchEx()
{
#if !defined(ONLINE_JUDGE)
    pData = new Data();
    FILETIME dummy;
    GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &dummy, &pData->timeStartUser);
    GetSystemTimeAsFileTime(&pData->timeStartSystem);
#endif //!defined(ONLINE_JUDGE)
}

#if !defined(ONLINE_JUDGE)
ULONGLONG FileTimeToU64(const FILETIME& time)
{
    return ((ULONGLONG)time.dwHighDateTime << 32) | time.dwLowDateTime;
}

ULONGLONG GetTimeDiffMs(const FILETIME& first, const FILETIME& second)
{
    return ((FileTimeToU64(first) - FileTimeToU64(second)) + 9999) / 10000;
}
#endif // !defined(ONLINE_JUDGE)

StopWatchEx::~StopWatchEx()
{
#if !defined(ONLINE_JUDGE)
    FILETIME timeCreated;
    FILETIME timeStopUser;
    FILETIME dummy;
    GetProcessTimes(GetCurrentProcess(), &timeCreated, &dummy, &dummy, &timeStopUser);

    FILETIME timeCurrent;
    GetSystemTimeAsFileTime(&timeCurrent);

    std::cout << std::setw(20) << "Total process = " << GetTimeDiffMs(timeCurrent, timeCreated) << " ms" << std::endl;
    std::cout << std::setw(20) << "UserTime diff = " << GetTimeDiffMs(timeStopUser, pData->timeStartUser) << " ms" << std::endl;
    std::cout << std::setw(20) << "SysTime diff = " << GetTimeDiffMs(timeCurrent, pData->timeStartSystem) << " ms" << std::endl;
    std::cout << std::endl;

    delete pData;
#endif //!defined(ONLINE_JUDGE)
}

void Prepare()
{
#if !defined(ONLINE_JUDGE)
    SetProcessAffinityMask(GetCurrentProcess(), 1);
#endif //!defined(ONLINE_JUDGE)
}