#include <bits/stdc++.h>
using namespace std;
struct Node;
typedef Node* NodePtr;
struct Node {
  static const unsigned long long P1 = 2169677289756953;
  static const unsigned long long P2 = 3293433323;
  unsigned long long hash;
  bool ones;
  NodePtr left, right;
  Node(unsigned long long value)
      : hash(value), ones(value == 1), left(NULL), right(NULL) {}
  Node(NodePtr left, NodePtr right) : left(left), right(right) {
    unsigned long long leftHash, rightHash;
    if (left) leftHash = left->hash;
    if (right) rightHash = right->hash;
    hash = leftHash * P1 + rightHash * (rightHash + 3) * P2;
    if (left && right)
      ones = left->ones && right->ones;
    else
      ones = false;
  }
};
NodePtr zero(NodePtr(new Node(0ll)));
NodePtr one(NodePtr(new Node(1ll)));
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
const int Xh = 17;
const int X = 1 << Xh;
vector<NodePtr> zeros;
vector<NodePtr> ones;
void initialize() {
  zeros.push_back(zero);
  ones.push_back(one);
  for (int i = 0; i < Xh; ++i) {
    zeros.push_back(NodePtr(new Node(zeros.back(), zeros.back())));
    ones.push_back(NodePtr(new Node(ones.back(), ones.back())));
  }
}
bool cmp(NodePtr a, NodePtr b, int height) {
  if (height == 0) return (a == zero && b == one);
  if (a->right->hash == b->right->hash)
    return cmp(a->left, b->left, height - 1);
  return cmp(a->right, b->right, height - 1);
}
bool cmp(NodePtr a, NodePtr b) { return cmp(a, b, Xh); }
NodePtr addValue(NodePtr node, int height, int length, int value,
                 bool& transfer) {
  transfer = false;
  if (value == 0 && node->ones) {
    transfer = true;
    return zeros[height];
  }
  if (height == 0) {
    if (node == zero) return one;
    if (node == one) {
      transfer = true;
      return zero;
    }
  }
  int half = length / 2;
  if (value >= half)
    return NodePtr(new Node(node->left, addValue(node->right, height - 1, half,
                                                 value - half, transfer)));
  bool leftTransfer;
  NodePtr left = addValue(node->left, height - 1, half, value, leftTransfer);
  if (!leftTransfer) return NodePtr(new Node(left, node->right));
  return NodePtr(
      new Node(left, addValue(node->right, height - 1, half, 0, transfer)));
}
NodePtr addValue(NodePtr node, int value) {
  bool transfer;
  return addValue(node, Xh, X, value, transfer);
}
int n, m;
int s, t;
vector<pair<int, int> > edges[N];
NodePtr distances[N];
int previous[N];
struct QCmp {
  bool operator()(pair<NodePtr, int> a, pair<NodePtr, int> b) {
    return cmp(b.first, a.first);
  }
};
vector<int> gathered;
void gatherDistance(NodePtr node, int height) {
  if (height == 0) {
    gathered.push_back(node->hash);
    return;
  }
  gatherDistance(node->right, height - 1);
  gatherDistance(node->left, height - 1);
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    int u, v, x;
    scanf("%d %d %d", &u, &v, &x);
    --u;
    --v;
    edges[u].push_back(make_pair(v, x));
    edges[v].push_back(make_pair(u, x));
  }
  scanf("%d %d", &s, &t);
  --s;
  --t;
  initialize();
  for (int i = 0; i < n; ++i) {
    distances[i] = ones[Xh];
    previous[i] = -1;
  }
  priority_queue<pair<NodePtr, int>, vector<pair<NodePtr, int> >, QCmp> Q;
  distances[s] = zeros[Xh];
  Q.push(make_pair(distances[s], s));
  while (!Q.empty()) {
    pair<NodePtr, int> top = Q.top();
    Q.pop();
    int u = top.second;
    NodePtr du = top.first;
    if (cmp(distances[u], du)) continue;
    for (int i = 0; i < (int)edges[u].size(); ++i) {
      int v = edges[u][i].first;
      NodePtr dv = addValue(du, edges[u][i].second);
      assert(cmp(du, dv));
      if (cmp(dv, distances[v])) {
        distances[v] = dv;
        previous[v] = u;
        Q.push(make_pair(dv, v));
      }
    }
  }
  if (distances[t] == ones[Xh]) {
    printf("-1\n");
    return 0;
  }
  gatherDistance(distances[t], Xh);
  int result = 0;
  for (int i = 0; i < (int)gathered.size(); ++i) {
    result = ((result << 1) + gathered[i]) % MOD;
  }
  printf("%d\n", result);
  vector<int> path;
  while (t != s) {
    path.push_back(t);
    t = previous[t];
  }
  printf("%d\n", (int)path.size() + 1);
  printf("%d", s + 1);
  reverse(path.begin(), path.end());
  for (int i = 0; i < (int)path.size(); ++i) {
    printf(" %d", path[i] + 1);
  }
  printf("\n");
  return 0;
}
