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

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define INF 1 << 30
#define EPS 1e-10
#define MAX_N 100

typedef pair<int, int> P;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;

struct edge{ int to, cost; };

vector<vector<edge> >G(MAX_N);
int n;
int d[MAX_N];

void dijkstra(int s){
  priority_queue<P, vector<P>, greater<P> >q;
  fill(d, d + n, INF);
  d[s] = 0;
  q.push(P(0, s));

  while(!q.empty()){
    P p = q.top(); q.pop();
    int v = p.S;
    if(d[v] < p.F) continue;
    rep(i, G[v].size()){
      edge e = G[v][i];
      if(d[e.to] > d[v] + e.cost){
	d[e.to] = d[v] + e.cost;
	q.push(P(d[e.to], e.to));
      }
    }
  }
}

int main(){
  int k;
  while(scanf("%d%d", &n, &k) && n+k){
    rep(i, MAX_N) G[i].clear();
    int a, b, c;
    rep(i, k){
      scanf("%d", &a);
      if(a){
	scanf("%d%d%d", &a, &b, &c); b--; a--;
	edge e;
	e.to = b; e.cost = c;
	G[a].PB(e);
	e.to = a;
	G[b].PB(e);
      }else{
	scanf("%d%d", &a, &b); a--; b--;
	dijkstra(a);
	printf("%d\n", d[b]==INF?-1:d[b]);
      }
    }
  }
  return 0;
}
#include <bits/stdc++.h>

using ll = long long int;
using P = std::pair<int, int>;

#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rag(con) std::begin(con), std::end(con)

constexpr int MAX = 1010;

std::vector<int> to[MAX];

int main()
{
    int n, m;
    std::cin >> n >> m;

    rep(i, m)
    {
        int a, b;
        std::cin >> a >> b;
        to[a].push_back(b);
    }

    std::vector<int> ans(n + 1);
    constexpr int INF = 1e9;

    rep(i, n)
    {
        std::queue<int> que;

        std::vector<int> dis(n + 1, INF);
        std::vector<int> par(n + 1);

        que.push(i);
        dis[i] = 0;

        while (!que.empty())
        {

            int x = que.front();
            que.pop();

            for (auto u : to[x])
            {
                if (dis[u] > dis[x] + 1)
                {
                    dis[u] = dis[x] + 1;
                    par[u] = x;
                    que.push(u);
                }
                else if (dis[u] == 0)
                    par[u] = x;
            }
        }
        if (!par[i])
            continue;
        int v = par[i];
        std::vector<int> vec;
        while (v != i)
        {
            vec.push_back(v);
            v = par[v];
        }
        vec.push_back(i);
        if (ans.size() > vec.size())
            ans = vec;
    }

    if (ans.size() == n + 1)
        std::cout << -1 << std::endl;
    else
    {
        std::cout << ans.size() << std::endl;
        for (auto x : ans)
            std::cout << x << std::endl;
    }

    return 0;
}