#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100 * 1000 + 1234;
const long long P1 = 5, P2 = 7, Q1 = 1000 * 1000 * 1000 + 7,
                Q2 = 1000 * 1000 * 1000 + 9;
long long ppows1[MAXN], ppows2[MAXN];
struct Hash {
  int len;
  long long val1;
  long long val2;
  Hash() {
    len = 0;
    val1 = 0;
    val2 = 0;
  }
  Hash(int x) {
    len = 1;
    val1 = x + 1;
    val2 = x + 1;
  }
};
Hash operator+(Hash l, Hash r) {
  Hash res;
  res.len = l.len + r.len;
  res.val1 = (l.val1 * ppows1[r.len] + r.val1) % Q1;
  res.val2 = (l.val2 * ppows2[r.len] + r.val2) % Q2;
  return res;
}
bool operator==(Hash l, Hash r) {
  return l.len == r.len && l.val1 == r.val1 && l.val2 == r.val2;
}
struct Node {
  Node* l;
  Node* r;
  Hash val;
  int zeroCnt;
  Node() {
    l = NULL;
    r = NULL;
    val = Hash();
    zeroCnt = 0;
  }
  Node(Node* x) {
    l = x->l;
    r = x->r;
    val = x->val;
    zeroCnt = x->zeroCnt;
  }
  Node(int x) {
    l = NULL;
    r = NULL;
    val = Hash(x);
    if (x == 0) {
      zeroCnt = 1;
    } else {
      zeroCnt = 0;
    }
  }
  void upd() {
    val = l->val + r->val;
    zeroCnt = l->zeroCnt + r->zeroCnt;
  }
};
Node* build(int l, int r, int val) {
  Node* res = new Node(val);
  if (l == r) return res;
  int m = (l + r) / 2;
  res->l = build(l, m, val);
  res->r = build(m + 1, r, val);
  res->upd();
  return res;
}
Node* zeroNodes[MAXN];
Node* setVal(Node* v, int tl, int tr, int pos, int val) {
  Node* res = NULL;
  if (tl == tr) {
    res = new Node(val);
    return res;
  } else {
    Node* res = new Node(v);
    int tm = (tl + tr) / 2;
    if (pos <= tm) {
      res->l = setVal(res->l, tl, tm, pos, val);
    } else {
      res->r = setVal(res->r, tm + 1, tr, pos, val);
    }
    res->upd();
    return res;
  }
}
Node* setZero(Node* v, int tl, int tr, int l, int r) {
  if (r < tl || l > tr) return v;
  if (tl >= l && tr <= r) return new Node(zeroNodes[tr - tl + 1]);
  Node* res = new Node(v);
  int tm = (tl + tr) / 2;
  res->l = setZero(res->l, tl, tm, l, r);
  res->r = setZero(res->r, tm + 1, tr, l, r);
  res->upd();
  return res;
}
int isLess(Node* v1, Node* v2, int tl, int tr) {
  if (tl == tr) {
    int x1 = 1;
    if (v1->zeroCnt) x1 = 0;
    int x2 = 1;
    if (v2->zeroCnt) x2 = 0;
    if (x1 < x2) return -1;
    if (x1 == x2) return 0;
    return 1;
  }
  int tm = (tl + tr) / 2;
  if (v1->l->val == v2->l->val) return isLess(v1->r, v2->r, tm + 1, tr);
  return isLess(v1->l, v2->l, tl, tm);
}
void dfs(Node* v, int tl, int tr) {
  if (tl == tr) {
    zeroNodes[1] = new Node(v);
  } else {
    zeroNodes[tr - tl + 1] = new Node(v);
    int tm = (tl + tr) / 2;
    dfs(v->l, tl, tm);
    dfs(v->r, tm + 1, tr);
  }
}
int findNearZero(Node* v, int tl, int tr, int pos) {
  if (tl > pos) return -1;
  if (v->zeroCnt == 0) return -1;
  if (tl == tr) return tl;
  int tm = (tl + tr) / 2;
  int res1 = findNearZero(v->r, tm + 1, tr, pos);
  if (res1 != -1) return res1;
  return findNearZero(v->l, tl, tm, pos);
}
int get(Node* v, int tl, int tr, int pos) {
  if (tl == tr) {
    if (v->zeroCnt == 0) return 1;
    return 0;
  }
  int tm = (tl + tr) / 2;
  if (pos <= tm) {
    return get(v->l, tl, tm, pos);
  } else {
    return get(v->r, tm + 1, tr, pos);
  }
}
vector<pair<int, int> > g[MAXN];
Node* dist[MAXN];
int p[MAXN];
long long calc(Node* v) {
  long long res = 0;
  for (int i = 1; i < MAXN; i++) {
    res = (2 * res + get(v, 1, MAXN - 1, i)) % Q1;
  }
  return res;
}
struct Comparator {
  bool operator()(int x, int y) {
    int cmp = isLess(dist[x], dist[y], 1, MAXN - 1);
    if (cmp == -1) return true;
    if (cmp == 1) return false;
    return x < y;
  }
};
int main() {
  ppows1[0] = 1;
  ppows2[0] = 1;
  for (int i = 1; i < MAXN; i++) {
    ppows1[i] = (ppows1[i - 1] * P1) % Q1;
    ppows2[i] = (ppows2[i - 1] * P2) % Q2;
  }
  Node* base = build(1, MAXN - 1, 0);
  dfs(base, 1, MAXN - 1);
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    g[u].push_back(make_pair(v, w));
    g[v].push_back(make_pair(u, w));
  }
  int s, t;
  scanf("%d %d", &s, &t);
  Node* base1 = build(1, MAXN - 1, 1);
  for (int i = 1; i <= n; i++) {
    dist[i] = new Node(base1);
  }
  dist[s] = new Node(base);
  p[s] = -1;
  set<int, Comparator> heap;
  for (int i = 1; i <= n; i++) {
    heap.insert(i);
  }
  while (!heap.empty()) {
    int v = *heap.begin();
    heap.erase(v);
    if (get(dist[v], 1, MAXN - 1, 1) == 1) continue;
    for (int i = 0; i < (int)g[v].size(); i++) {
      int to = g[v][i].first, tow = MAXN - 1 - g[v][i].second;
      Node* cur = new Node(dist[v]);
      int pos = findNearZero(cur, 1, MAXN - 1, tow);
      cur = setVal(cur, 1, MAXN - 1, pos, 1);
      if (pos != tow) {
        cur = setZero(cur, 1, MAXN - 1, pos + 1, tow);
      }
      if (isLess(cur, dist[to], 1, MAXN - 1) == -1) {
        p[to] = v;
        heap.erase(to);
        dist[to] = cur;
        heap.insert(to);
      }
    }
  }
  Node* res = dist[t];
  if (get(res, 1, MAXN - 1, 1) == 1) {
    puts("-1");
    return 0;
  }
  long long resVal = 0;
  for (int i = 1; i < MAXN; i++) {
    resVal = (2 * resVal + get(res, 1, MAXN - 1, i)) % Q1;
  }
  printf("%lld\n", resVal);
  vector<int> path;
  int vv = t;
  while (vv != -1) {
    path.push_back(vv);
    vv = p[vv];
  }
  reverse(path.begin(), path.end());
  printf("%d\n", (int)path.size());
  for (int i = 0; i < (int)path.size(); i++) {
    printf("%d ", path[i]);
  }
  printf("\n");
  return 0;
}
