#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to;
  int cost;
};
using graph = vector<vector<edge> >;
using path = vector<int>;
struct result {
  long long distance;
  path route;
};
void add_edge(graph &g, int start, int finish, int cost) {
  g[start].push_back({finish, cost});
  g[finish].push_back({start, cost});
}
result dijkstra(graph &g, int source, int target) {
  vector<long long> min_dist(g.size(), 10e18);
  min_dist[source] = 0;
  if (source >= g.size()) cerr << "Source outside of graph range.";
  set<pair<int, int> > active_vertices;
  active_vertices.insert({0, source});
  while (!active_vertices.empty()) {
    int current = active_vertices.begin()->second;
    if (current == target) {
      long long cost = min_dist[current];
      path p{current};
      while (current != source) {
        int next = current;
        for (edge e : g[current]) {
          if (min_dist[e.to] == INT_MAX || min_dist[e.to] == -1 ||
              e.cost + min_dist[e.to] != min_dist[current])
            continue;
          next = e.to;
          p.push_back(next);
          break;
        }
        if (next == current) {
          break;
        }
        current = next;
      }
      std::reverse(p.begin(), p.end());
      return {cost, std::move(p)};
    }
    active_vertices.erase(active_vertices.begin());
    for (auto next : g[current]) {
      if (min_dist[next.to] > min_dist[current] + next.cost) {
        active_vertices.erase({min_dist[next.to], next.to});
        min_dist[next.to] = min_dist[current] + next.cost;
        active_vertices.insert({min_dist[next.to], next.to});
      }
    }
  }
  return {-1};
}
int main() {
  graph g;
  int v, e;
  cin >> v >> e;
  g.resize(1e5 + 5);
  while (e--) {
    int x, y, c;
    cin >> x >> y >> c;
    add_edge(g, x, y, c);
  }
  result res = dijkstra(g, 1, v);
  if (res.distance == -1) cout << res.distance;
  for (auto it : res.route) {
    cout << it << " ";
  }
}
