#include <bits/stdc++.h>
using namespace std;
int const p = 1e9 + 7, base = 2333, p2 = 998244353;
int target[400005], pre[400005], last[200005],
    tot = 1, root[400005], ch[12000005][2], ha[12000005], m, n, tree[12000005],
    dis[200005], cnt, pw[200005], pw2[200005], ha2[12000005], res, w[400005],
    pre2[200005], pw3[200005];
bool vis[200005];
bool comp(int l, int r, int x, int y) {
  if (l == r) return tree[x] < tree[y];
  int mid = (l + r) >> 1;
  if (ha[ch[x][1]] == ha[ch[y][1]] && ha2[ch[x][1]] == ha2[ch[y][1]])
    return comp(l, mid, ch[x][0], ch[y][0]);
  return comp(mid + 1, r, ch[x][1], ch[y][1]);
}
int query(int l, int r, int x, int a, int b) {
  if (!x) return 0;
  if (l >= a && r <= b) return tree[x];
  int mid = (l + r) >> 1, res = 0;
  if (a <= mid) res = query(l, mid, ch[x][0], a, b);
  if (b > mid) res += query(mid + 1, r, ch[x][1], a, b);
  return res;
}
void modify(int l, int r, int &x, int pre, int a) {
  if (!x) x = ++cnt;
  if (l == r) {
    tree[x] = ha[x] = ha2[x] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  if (a <= mid)
    modify(l, mid, ch[x][0], ch[pre][0], a), ch[x][1] = ch[pre][1];
  else
    modify(mid + 1, r, ch[x][1], ch[pre][1], a), ch[x][0] = ch[pre][0];
  tree[x] = tree[ch[x][0]] + tree[ch[x][1]];
  ha[x] = (1ll * pw[r - mid] * ha[ch[x][0]] + ha[ch[x][1]]) % p;
  ha2[x] = (1ll * pw3[r - mid] * ha2[ch[x][0]] + ha2[ch[x][1]]) % p;
}
int clear(int l, int r, int x, int a, int b) {
  if ((l >= a && r <= b) || (!x)) return 0;
  if (r < a || l > b) return x;
  int mid = (l + r) >> 1, y = ++cnt;
  ch[y][0] = clear(l, mid, ch[x][0], a, b);
  ch[y][1] = clear(mid + 1, r, ch[x][1], a, b);
  tree[y] = tree[ch[y][0]] + tree[ch[y][1]];
  ha[y] = (1ll * pw[r - mid] * ha[ch[y][0]] + ha[ch[y][1]]) % p;
  ha2[y] = (1ll * pw3[r - mid] * ha2[ch[y][0]] + ha2[ch[y][1]]) % p;
  return y;
}
void dfs(int l, int r, int x) {
  if (!tree[x]) return;
  if (l == r) {
    res = (res + pw2[l]) % p;
    return;
  }
  int mid = (l + r) >> 1;
  dfs(l, mid, ch[x][0]), dfs(mid + 1, r, ch[x][1]);
}
struct node {
  int dis, x;
  friend bool operator<(node a, node b) {
    return comp(0, 2e5, root[b.dis], root[a.dis]);
  }
};
priority_queue<node> q;
void add(int x, int y, int z) {
  target[++tot] = y;
  pre[tot] = last[x];
  last[x] = tot;
  w[tot] = z;
}
int main() {
  int s, t, x, y, z, sum = 0;
  scanf("%d%d", &n, &m);
  pw[0] = pw2[0] = 1;
  for (int i = 1; i <= 200000; i++)
    pw[i] = 1ll * pw[i - 1] * base % p, pw2[i] = 2 * pw2[i - 1] % p,
    pw3[i] = 1ll * pw3[i - 1] * 233 % p2, dis[i] = -1;
  for (int i = 1; i <= m; i++)
    scanf("%d%d%d", &x, &y, &z), add(x, y, z), add(y, x, z);
  memset(dis, -1, sizeof(dis));
  scanf("%d%d", &s, &t);
  dis[s] = 0;
  q.push({0, s});
  while (q.size()) {
    int now = q.top().x;
    q.pop();
    if (vis[now]) continue;
    vis[now] = 1;
    if (now == t) break;
    for (int i = last[now]; i; i = pre[i]) {
      int tar = target[i];
      if (vis[tar]) continue;
      ++sum;
      int ss = w[i], tt, ll = ss, rr = 200000;
      while (ll < rr) {
        int mid = (ll + rr) >> 1;
        if (query(0, 200000, root[dis[now]], ss, mid) <= mid - ss)
          rr = mid;
        else
          ll = mid + 1;
      }
      tt = ll;
      modify(0, 2e5, root[sum], root[dis[now]], tt);
      if (ss != tt) ++sum, root[sum] = clear(0, 2e5, root[sum - 1], ss, tt - 1);
      if (dis[tar] == -1 || comp(0, 2e5, root[sum], root[dis[tar]]))
        pre2[tar] = now, dis[tar] = sum, q.push({dis[tar], tar});
    }
  }
  if (!vis[t]) {
    puts("-1");
    return 0;
  }
  dfs(0, 2e5, root[dis[t]]);
  printf("%d\n", res);
  int now = t;
  vector<int> v;
  while (now != s) v.push_back(now), now = pre2[now];
  printf("%d\n", v.size() + 1);
  printf("%d ", s);
  for (int i = v.size() - 1; i >= 0; i--) printf("%d ", v[i]);
  return 0;
}
