#include <bits/stdc++.h>
using namespace std;
const long long z = 127, inv = 7936508, MOD = 1e9 + 7;
const int MAXX = 2e5 + 50, MAXNODES = 1e7 + 5;
long long Z[MAXX + 1], H[MAXNODES];
int ST[2][MAXNODES], S[MAXNODES], L[MAXNODES], VAL[2] = {53, 97}, K = 0;
struct edge {
  int v, x;
  edge() {}
  edge(int v, int x) : v(v), x(x) {}
};
const int MAXN = 1e5;
vector<edge> G[MAXN];
int P[MAXN], D[MAXN], N, M;
int build(int n, int l, int r) {
  int k = ++K;
  H[k] = (Z[r - l + 1] - 1) * inv * VAL[L[n]] % MOD;
  S[k] = (r - l + 1) * (1 - L[n]);
  L[k] = L[n];
  ST[0][k] = ST[1][k] = -1;
  return k;
}
int get(int n, int k, int l, int r) {
  if (ST[k][n] != -1) return ST[k][n];
  return ST[k][n] = build(n, l, r);
}
int update(int n, int l, int r, int i, int v) {
  if (r < i || i < l) return n;
  int k = ++K;
  if (l == r) {
    H[k] = VAL[v];
    S[k] = 1 - v;
    ST[0][k] = ST[1][k] = -1;
  } else {
    int m = (l + r) / 2;
    if (i <= m)
      ST[0][k] = update(get(n, 0, l, m), l, m, i, v),
      ST[1][k] = get(n, 1, m + 1, r);
    else
      ST[0][k] = get(n, 0, l, m),
      ST[1][k] = update(get(n, 1, m + 1, r), m + 1, r, i, v);
    S[k] = S[ST[0][k]] + S[ST[1][k]];
    H[k] = (H[ST[0][k]] + Z[m - l + 1] * H[ST[1][k]]) % MOD;
  }
  return k;
}
int update(int n, int i, int v) { return update(n, 0, MAXX - 1, i, v); }
int query(int n, int l, int r, int i, int j) {
  if (r < i || j < l) return 0;
  if (i <= l && r <= j) return S[n];
  int m = (l + r) / 2;
  return query(get(n, 0, l, m), l, m, i, j) +
         query(get(n, 1, m + 1, r), m + 1, r, i, j);
}
int query(int n, int i, int j) {
  if (j < i) return 0;
  return query(n, 0, MAXX - 1, i, j);
}
int update(int n, int l, int r, int i, int j, int v) {
  if (r < i || j < l) return n;
  int k = ++K;
  if (i <= l && r <= j) {
    H[k] = (Z[r - l + 1] - 1) * inv * VAL[v] % MOD;
    S[k] = (r - l + 1) * (1 - v);
    L[k] = v;
    ST[0][k] = ST[1][k] = -1;
  } else {
    int m = (l + r) / 2;
    ST[0][k] = update(get(n, 0, l, m), l, m, i, j, v);
    ST[1][k] = update(get(n, 1, m + 1, r), m + 1, r, i, j, v);
    S[k] = S[ST[0][k]] + S[ST[1][k]];
    H[k] = (H[ST[0][k]] + Z[m - l + 1] * H[ST[1][k]]) % MOD;
  }
  return k;
}
int update(int n, int i, int j, int v) {
  if (j < i) return n;
  return update(n, 0, MAXX - 1, i, j, v);
}
int comp(int n, int k) {
  if (n == -1) return -1;
  if (k == -1) return 1;
  int l = 0, r = MAXX - 1;
  while (l != r) {
    int m = (l + r) / 2;
    if (H[get(n, 1, m + 1, r)] == H[get(k, 1, m + 1, r)]) {
      n = get(n, 0, l, m);
      k = get(k, 0, l, m);
      r = m;
    } else {
      n = get(n, 1, m + 1, r);
      k = get(k, 1, m + 1, r);
      l = m + 1;
    }
  }
  return S[n] == S[k] ? 0 : S[n] > S[k] ? 1 : -1;
}
int update_plus(int n, int x) {
  int c = 1 + query(n, 0, x - 1), k = n;
  int l = 0, r = MAXX - 1;
  while (l != r) {
    int m = (l + r) / 2;
    if (S[get(k, 0, l, m)] >= c) {
      k = get(k, 0, l, m);
      r = m;
    } else {
      c -= S[get(k, 0, l, m)];
      k = get(k, 1, m + 1, r);
      l = m + 1;
    }
  }
  n = update(n, x, l - 1, 0);
  n = update(n, r, 1);
  return n;
}
void compute(int n, int l, int r, long long &power, long long &answer) {
  if (l == r) {
    answer += power * (1 - S[n]);
    if (answer >= MOD) answer -= MOD;
    power *= 2;
    if (power >= MOD) power -= MOD;
    return;
  }
  int m = (l + r) / 2;
  compute(get(n, 0, l, m), l, m, power, answer);
  compute(get(n, 1, m + 1, r), m + 1, r, power, answer);
}
struct state {
  int d, u;
  state() {}
  state(int d, int u) : d(d), u(u) {}
  bool operator<(const state &o) const {
    int c = comp(d, o.d);
    return c != 0 ? c == -1 : u < o.u;
  }
};
int main() {
  Z[0] = 1;
  for (int i = 1; i <= MAXX; ++i) Z[i] = z * Z[i - 1] % MOD;
  ST[0][0] = ST[1][0] = -1;
  L[0] = 0;
  S[0] = MAXX;
  H[0] = (Z[MAXX] - 1) * inv * VAL[0] % MOD;
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int u, v, x;
    cin >> u >> v >> x;
    --u;
    --v;
    G[u].emplace_back(v, x);
    G[v].emplace_back(u, x);
  }
  int s, t;
  cin >> s >> t;
  --s;
  --t;
  for (int i = 0; i < N; ++i) D[i] = P[i] = -1;
  D[s] = 0;
  priority_queue<state> PQ;
  PQ.emplace(D[s], s);
  while (!PQ.empty()) {
    state s = PQ.top();
    PQ.pop();
    int d = s.d, u = s.u;
    if (u == t) break;
    if (D[u] != d && comp(D[u], d) == 1) continue;
    for (edge e : G[u]) {
      int v = e.v, x = e.x, d = update_plus(D[u], x);
      if (comp(d, D[v]) == 1) {
        D[v] = d;
        P[v] = u;
        PQ.emplace(D[v], v);
      }
    }
  }
  if (D[t] == -1)
    cout << "-1\n";
  else {
    long long power = 1, answer = 0;
    compute(D[t], 0, MAXX - 1, power, answer);
    cout << answer << '\n';
    stack<int> W;
    int v = t;
    while (v != -1) {
      W.push(v);
      v = P[v];
    }
    cout << W.size() << '\n';
    while (!W.empty()) {
      cout << 1 + W.top() << ' ';
      W.pop();
    }
    cout << '\n';
  }
  return 0;
}
