#include <bits/stdc++.h>
using namespace std;
unsigned long long ha[100089 * 50], ba[100089];
int tot, L[100089 * 50], R[100089 * 50], head[100089], ans, n, m, rt,
    dis[100089], T[100089], pre[100089], s, t;
bool vis[100089];
const int maxn = 1e5 + 30;
const int mod = 1e9 + 7;
inline int rd() {
  int x = 0;
  char c = getchar();
  bool f = 0;
  while (!isdigit(c)) {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  return f ? -x : x;
}
struct edge {
  int n, to, l;
} e[100089 << 1];
inline int power(long long x, int y) {
  long long ans = 1;
  while (y) {
    if (y & 1) ans = ans * x % mod;
    x = x * x % mod;
    y >>= 1;
  }
  return ans;
}
bool cmp(int now, int pre, int l, int r) {
  if (l == r) {
    return ha[now] < ha[pre];
  }
  int mid = (l + r) >> 1;
  if (ha[R[pre]] == ha[R[now]])
    return cmp(L[now], L[pre], l, mid);
  else
    return cmp(R[now], R[pre], mid + 1, r);
}
struct node {
  int id, rt;
  inline bool operator<(const node &b) const { return !cmp(rt, b.rt, 0, maxn); }
};
priority_queue<node> q;
inline void add(int u, int v, int l) {
  e[++tot].n = head[u];
  e[tot].to = v;
  head[u] = tot;
  e[tot].l = l;
}
bool upd(int &now, int pre, int l, int r, int x) {
  now = ++tot;
  L[now] = L[pre];
  R[now] = R[pre];
  ha[now] = ha[pre];
  if (l == r) {
    ha[now] = ha[pre] ^ 1;
    return ha[pre];
  }
  int mid = (l + r) >> 1, gan = 0;
  if (mid < x)
    gan = upd(R[now], R[pre], mid + 1, r, x);
  else {
    gan = upd(L[now], L[pre], l, mid, x);
    if (gan) gan = upd(R[now], R[pre], mid + 1, r, mid + 1);
  }
  ha[now] = ha[L[now]] + ha[R[now]] * ba[mid - l + 1];
  return gan;
}
int build(int l, int r) {
  int p = ++tot;
  ha[p] = 1;
  int mid = (l + r) >> 1;
  if (l == r) return p;
  L[p] = build(l, mid);
  R[p] = build(mid + 1, r);
  ha[p] = ha[L[p]] + ha[R[p]] * ba[mid - l + 1];
  return p;
}
void dfs(int now, int l, int r) {
  if (l == r) {
    if (ha[now]) (ans += power(2, l)) %= mod;
    return;
  }
  int mid = (l + r) >> 1;
  dfs(L[now], l, mid);
  dfs(R[now], mid + 1, r);
}
void dfs2(int now) {
  if (now != s) dfs2(pre[now]);
  printf("%d ", now);
}
void check(int now, int l, int r) {
  if (l == r) {
    return;
  }
  int mid = (l + r) >> 1;
  if (ha[L[now]]) check(L[now], l, mid);
  if (ha[R[now]]) check(R[now], mid + 1, r);
}
int main() {
  n = rd();
  m = rd();
  int u, v, w;
  ba[0] = 1;
  for (int i = 1; i <= maxn; ++i) ba[i] = ba[i - 1] * 233ull;
  for (int i = 1; i <= m; ++i) {
    u = rd();
    v = rd();
    w = rd();
    add(u, v, w);
    add(v, u, w);
  }
  s = rd();
  t = rd();
  rt = build(0, maxn);
  for (int i = 1; i <= n; ++i) T[i] = rt;
  T[s] = 0;
  q.push(node{s, T[s]});
  dis[s] = 1;
  while (!q.empty()) {
    int u = q.top().id;
    q.pop();
    if (vis[u]) continue;
    vis[u] = 1;
    for (int i = head[u]; i; i = e[i].n) {
      int v = e[i].to;
      upd(rt, T[u], 0, maxn, e[i].l);
      if (cmp(rt, T[v], 0, maxn)) {
        T[v] = rt;
        dis[v] = dis[u] + 1;
        pre[v] = u;
        q.push(node{v, T[v]});
      }
    }
  }
  if (!dis[t]) {
    printf("-1\n");
    return 0;
  }
  dfs(T[t], 0, maxn);
  printf("%d\n%d\n", ans, dis[t]);
  dfs2(t);
  return 0;
}
