#include <bits/stdc++.h>
using namespace std;
template <class T>
void read(T &x) {
  T f = 1;
  x = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while ('0' <= c && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T>
void print(T x, char c) {
  if (x < 0) putchar('-'), x = -x;
  int s[20], top = 0;
  while (s[++top] = x % 10, x /= 10)
    ;
  while (top) putchar(s[top--] + '0');
  putchar(c);
}
char st;
int n, m, cnt, h[100055], S, T, mx, p[100055], full[100055];
struct Edge {
  int to, next, w;
} a[100055 << 1];
void Add(int x, int y, int z) {
  cnt++;
  a[cnt].to = y;
  a[cnt].next = h[x];
  a[cnt].w = z;
  h[x] = cnt;
}
int root[100055], lc[100055 << 6], rc[100055 << 6], sum[100055 << 6];
void build(int &rt, int l = 1, int r = mx) {
  rt = ++cnt;
  if (l == r) return;
  int mid = l + r >> 1;
  build(lc[rt], l, mid);
  build(rc[rt], mid + 1, r);
}
bool cmp(int t1, int t2, int l = 1, int r = mx) {
  if (l == r) return sum[t1] > sum[t2];
  int mid = l + r >> 1;
  if (sum[rc[t1]] == sum[rc[t2]]) return cmp(lc[t1], lc[t2], l, mid);
  return cmp(rc[t1], rc[t2], mid + 1, r);
}
int pos;
void findr(int rt, int k, int l = 1, int r = mx) {
  if (k <= l && sum[rt] == full[r - l]) return pos = r, void();
  if (l == r) return;
  int mid = l + r >> 1;
  if (k > mid)
    findr(rc[rt], k, mid + 1, r);
  else {
    findr(lc[rt], k, l, mid);
    if (pos == mid) findr(rc[rt], k, mid + 1, r);
  }
}
void pushup(int rt, int dlt) {
  sum[rt] = (sum[lc[rt]] + 1ll * sum[rc[rt]] * p[dlt]) % 1000000007;
}
void cover(int &rt, int pre, int o, int L, int R, int l = 1, int r = mx) {
  if (L <= l && r <= R) return rt = o, void();
  rt = ++cnt;
  lc[rt] = lc[pre], rc[rt] = rc[pre];
  int mid = l + r >> 1;
  if (L <= mid) cover(lc[rt], lc[pre], lc[o], L, R, l, mid);
  if (mid + 1 <= R) cover(rc[rt], rc[pre], rc[o], L, R, mid + 1, r);
  pushup(rt, mid - l + 1);
}
void insert(int &rt, int pre, int l = 1, int r = mx) {
  rt = ++cnt;
  lc[rt] = lc[pre], rc[rt] = rc[pre];
  if (l == r) return sum[rt] = 1, void();
  int mid = l + r >> 1;
  pos <= mid ? insert(lc[rt], lc[pre], l, mid)
             : insert(rc[rt], rc[pre], mid + 1, r);
  pushup(rt, mid - l + 1);
}
void carry(int &rt, int pre, int k) {
  pos = k - 1;
  findr(pre, k);
  if (k <= pos) cover(rt, pre, root[S], k, pos);
  if (++pos <= mx) insert(rt, rt);
}
struct node {
  int rt, x;
  bool operator<(const node &b) const { return cmp(rt, b.rt); }
};
int vst[100055], pre[100055];
void road() {
  print(sum[root[T]], '\n');
  int top = 0;
  for (int x = T; x; x = pre[x]) vst[++top] = x;
  print(top, '\n');
  while (top) print(vst[top--], ' ');
}
char ed;
void dij() {
  build(root[S]);
  priority_queue<node> q;
  q.push(node{root[S], S});
  vst[S] = 1;
  while (!q.empty()) {
    node u = q.top();
    q.pop();
    int x = u.x;
    if (u.rt != root[x]) continue;
    if (x == T) return road();
    for (int i = h[x]; i; i = a[i].next) {
      int y = a[i].to, nrt = root[x];
      carry(nrt, root[x], a[i].w);
      if (!root[y] || cmp(root[y], nrt)) {
        pre[y] = x, root[y] = nrt, q.push(node{nrt, y});
      }
    }
  }
  puts("-1");
}
int main() {
  read(n), read(m);
  for (int i = 1, x, y, z; i <= m; ++i)
    read(x), read(y), read(z), z++, Add(x, y, z), Add(y, x, z), mx = max(mx, z);
  read(S), read(T);
  mx += log2(n);
  if (!m) {
    if (S == T)
      printf("0\n%d\n%d", S, T);
    else
      puts("-1");
    return 0;
  }
  p[0] = full[0] = 1;
  for (int i = 1; i <= mx; ++i)
    p[i] = p[i - 1] * 2 % 1000000007,
    full[i] = (p[i] + full[i - 1]) % 1000000007;
  dij();
}
