#include <bits/stdc++.h>
using namespace std;
struct node {
  int u;
  long long int cost;
  node(int _u, long long int _cost) {
    u = _u;
    cost = _cost;
  }
  bool operator<(const node& p) const {
    return (long long int)cost < (long long int)p.cost;
  }
};
int numNodes, numEdges;
int source;
bool p;
vector<vector<int> > G;
map<pair<int, int>, int> cost;
vector<long long int> dist;
vector<int> par;
void clear() {
  G.clear();
  cost.clear();
  dist.clear();
}
void dijstkra() {
  priority_queue<pair<long long int, int>, vector<pair<long long int, int> >,
                 greater<pair<long long int, int> > >
      q;
  dist[source] = 0LL;
  q.push({0LL, source});
  while (!q.empty()) {
    int u = q.top().second;
    q.pop();
    for (auto v : G[u]) {
      if (dist[u] + cost[{u, v}] < dist[v]) {
        dist[v] = dist[u] + cost[{u, v}];
        par[v] = u;
        q.push({dist[v], v});
      }
    }
  }
}
void find_path(int s, int e) {
  if ((s == e) || (e == -1)) {
    if (p) cout << ' ';
    p = true;
    cout << s;
  } else {
    find_path(s, par[e]);
    if (p) cout << ' ';
    p = true;
    cout << e;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  p = false;
  source = 1;
  cin >> numNodes >> numEdges;
  dist.resize(numNodes + 1, LLONG_MAX);
  par.resize(numNodes + 1, -1);
  G.resize(numNodes + 1);
  for (int i = 1; i <= numEdges; i++) {
    int u, v;
    int w;
    cin >> u >> v >> w;
    G[u].push_back(v);
    G[v].push_back(u);
    cost[pair<int, int>(u, v)] = w;
    cost[pair<int, int>(v, u)] = w;
  }
  dijstkra();
  if (par[numNodes] == -1) {
    cout << "-1\n";
    return 0;
  }
  find_path(source, numNodes);
  clear();
}
