#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
const int lim = 1e5 + 40;
int ksm(int num, int t, int mod) {
  int res = 1;
  for (; t; t >>= 1, num = 1ll * num * num % mod) {
    if (t & 1) res = 1ll * num * res % mod;
  }
  return res;
}
const int mod = 1e9 + 7;
bool debug = 0;
struct chairman_tree {
  int cnt;
  int hbase[2], hmod[2], hmi[2][maxn], hinv[2][maxn];
  vector<int> hash[2], ls, rs, val;
  int new_node() {
    cnt++;
    hash[0].push_back(0);
    hash[1].push_back(0);
    ls.push_back(0);
    rs.push_back(0);
    val.push_back(0);
    return cnt;
  }
  int clone(int tar) {
    int idx = new_node();
    val[idx] = val[tar];
    ls[idx] = ls[tar], rs[idx] = rs[tar];
    hash[0][idx] = hash[0][tar];
    hash[1][idx] = hash[1][tar];
    return idx;
  }
  chairman_tree() {
    new_node();
    cnt = 0;
    hbase[0] = 233, hbase[1] = 2333;
    hmod[0] = 1e9 + 7, hmod[1] = 19260817;
    for (int i = (0), iend = (1); i <= iend; i++) {
      hmi[i][0] = 1;
      for (int j = (1), jend = (maxn - 1); j <= jend; j++)
        hmi[i][j] = 1ll * hmi[i][j - 1] * hbase[i];
      for (int j = (0), jend = (maxn - 1); j <= jend; j++)
        hinv[i][j] = ksm(hmi[i][j], hmod[i] - 2, hmod[i]);
    }
  }
  void push_up(int rt, int l, int r) {
    int mid = (l + r) >> 1;
    int len1 = mid - l + 1;
    hash[0][rt] =
        (hash[0][ls[rt]] + 1ll * hash[0][rs[rt]] * hmi[0][len1]) % hmod[0];
    hash[1][rt] =
        (hash[1][ls[rt]] + 1ll * hash[1][rs[rt]] * hmi[1][len1]) % hmod[1];
    val[rt] = val[ls[rt]] & val[rs[rt]];
  }
  int override0(int l, int r, int rt, int tl, int tr) {
    rt = clone(rt);
    if (tl <= l && r <= tr) {
      hash[0][rt] = hash[1][rt] = ls[rt] = rs[rt] = val[rt] = 0;
      return 0;
    }
    int mid = (l + r) >> 1;
    if (tl <= mid) ls[rt] = override0(l, mid, ls[rt], tl, tr);
    if (tr >= mid + 1) rs[rt] = override0(mid + 1, r, rs[rt], tl, tr);
    push_up(rt, l, r);
    return rt;
  }
  int override1(int l, int r, int rt, int tar) {
    rt = clone(rt);
    if (l == r) {
      hash[0][rt] = hbase[0];
      hash[1][rt] = hbase[1];
      val[rt] = 1;
      return rt;
    }
    int mid = (l + r) >> 1;
    int jkl = -1, jkr = -1;
    if (tar <= mid)
      jkl = override1(l, mid, ls[rt], tar);
    else
      jkr = override1(mid + 1, r, rs[rt], tar);
    if (jkl != -1) ls[rt] = jkl;
    if (jkr != -1) rs[rt] = jkr;
    push_up(rt, l, r);
    return rt;
  }
  bool all1(int l, int r, int rt, int tl, int tr) {
    if (!rt) return 0;
    if (tl <= l && r <= tr) {
      return val[rt];
    }
    int mid = (l + r) >> 1;
    int ans = 1;
    if (tl <= mid) ans &= all1(l, mid, ls[rt], tl, tr);
    if (tr >= mid + 1) ans &= all1(mid + 1, r, rs[rt], tl, tr);
    return ans;
  }
  bool check_same(int l, int r, int rt1, int rt2, int tl, int tr) {
    if (tl <= l && r <= tr) {
      return ((hash[0][rt1] == hash[0][rt2]) && (hash[1][rt1] == hash[1][rt2]));
    }
    int mid = (l + r) >> 1;
    int ans = 1;
    if (tl <= mid) ans &= check_same(l, mid, ls[rt1], ls[rt2], tl, tr);
    if (tr >= mid + 1) ans &= check_same(mid + 1, r, rs[rt1], rs[rt2], tl, tr);
    return ans;
  }
  int get_val(int l, int r, int rt, int tar) {
    if (l == r) return val[rt];
    int mid = (l + r) >> 1;
    if (tar <= mid)
      return get_val(l, mid, ls[rt], tar);
    else
      return get_val(mid + 1, r, rs[rt], tar);
  }
  int iterate(int basis, int addloc) {
    int l = addloc, r = lim;
    if (!all1(0, lim, basis, addloc, addloc)) {
      if (debug) cout << "go for iterate plan a" << endl;
      basis = override1(0, lim, basis, addloc);
    } else {
      while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (all1(0, lim, basis, addloc, mid))
          l = mid;
        else
          r = mid - 1;
      }
      basis = override0(0, lim, basis, addloc, l);
      basis = override1(0, lim, basis, l + 1);
    }
    return basis;
  }
  bool cmp(int a, int b) {
    if (hash[0][a] == hash[0][b] && hash[1][a] == hash[1][b]) return -1;
    int l = 0, r = lim;
    while (l < r) {
      int mid = (l + r) >> 1;
      if (check_same(0, lim, a, b, mid, lim))
        r = mid;
      else
        l = mid + 1;
    }
    int gg = get_val(0, lim, a, l - 1) < get_val(0, lim, b, l - 1);
    return gg;
  }
} t;
struct Pack {
  int u, last, val_id, ans;
  void clear() { u = last = val_id = ans = 0; }
  bool operator<(const Pack &a) const {
    int sta = t.cmp(val_id, a.val_id);
    if (sta == -1) return 0;
    return (!sta);
  }
};
priority_queue<Pack, vector<Pack> > q;
vector<int> side[maxn], w[maxn];
int from[maxn];
int dis[maxn], lenth[maxn];
int mi2[maxn];
bool vis[maxn];
int output[maxn];
int main() {
  memset(lenth, -1, sizeof(lenth));
  int n, m;
  scanf("%d%d", &n, &m);
  mi2[0] = 1;
  for (int i = (1), iend = (maxn - 1); i <= iend; i++)
    mi2[i] = 1ll * mi2[i - 1] * 2 % mod;
  for (int i = (1), iend = (m); i <= iend; i++) {
    int u, v, val;
    scanf("%d%d%d", &u, &v, &val);
    side[u].push_back(v);
    w[u].push_back(val);
    side[v].push_back(u);
    w[v].push_back(val);
  }
  int S, T;
  scanf("%d%d", &S, &T);
  Pack init;
  init.clear();
  init.u = S;
  init.val_id = t.new_node();
  dis[S] = init.val_id;
  q.push(init);
  while (!q.empty()) {
    Pack bk = q.top();
    q.pop();
    int u = bk.u;
    if (vis[u]) continue;
    vis[u] = 1;
    from[u] = bk.last;
    dis[u] = bk.val_id;
    lenth[u] = bk.ans;
    for (int i = (0), iend = ((int)(side[u].size()) - 1); i <= iend; i++) {
      int v = side[u][i], val = w[u][i];
      if (vis[v]) continue;
      q.push((Pack){v, u, t.iterate(dis[u], val),
                    (int)((1ll * bk.ans + mi2[val]) % mod)});
    }
  }
  printf("%d\n", lenth[T]);
  if (lenth[T] != -1) {
    int x = T;
    int top = 0;
    while (x) output[++top] = x, x = from[x];
    printf("%d\n", top);
    while (top) printf("%d ", output[top--]);
  }
  return 0;
}
