#include <bits/stdc++.h>
using namespace std;
int n, m, conf_length, source, destination;
int T[100005];
int pb_h1[100005 + 20], pb_h2[100005 + 20], h1_full1[100005 + 20],
    h2_full1[100005 + 20];
vector<pair<int, int>> G[100005];
class SegmentTree {
 public:
  SegmentTree *left_son, *right_son;
  int sum, add;
  int h1, h2;
  SegmentTree() {
    left_son = right_son = nullptr;
    sum = add = 0;
    h1 = h2 = 0;
  }
};
vector<SegmentTree*> root;
SegmentTree* init_tree(int nod, int st, int dr) {
  if (st == dr) {
    return new SegmentTree();
  }
  int mij = (st + dr) >> 1;
  int nodst = nod << 1;
  int noddr = nodst | 1;
  SegmentTree* current_node = new SegmentTree();
  current_node->left_son = init_tree(nodst, st, mij);
  current_node->right_son = init_tree(noddr, mij + 1, dr);
  return current_node;
}
inline void propaga(SegmentTree* node, int st, int dr) {
  if (!(node->add) || st == dr) {
    return;
  }
  if (!node->left_son) {
    node->left_son = new SegmentTree();
  }
  if (!node->right_son) {
    node->right_son = new SegmentTree();
  }
  int mij = (st + dr) >> 1;
  node->left_son->sum = (node->add - 1) * (mij - st + 1);
  node->left_son->h1 = node->add == 1 ? 0 : h1_full1[mij - st + 1];
  node->left_son->h2 = node->add == 1 ? 0 : h2_full1[mij - st + 1];
  node->right_son->sum = (node->add - 1) * (dr - mij);
  node->right_son->h1 = node->add == 1 ? 0 : h1_full1[dr - mij];
  node->right_son->h2 = node->add == 1 ? 0 : h2_full1[dr - mij];
  node->left_son->add = node->right_son->add = node->add;
  node->add = 0;
}
pair<SegmentTree*, pair<int, int>> find_segment_with_0(SegmentTree* node,
                                                       int st, int dr,
                                                       int query_left,
                                                       int query_right) {
  propaga(node, st, dr);
  if (query_left <= st && dr <= query_right) {
    if (node->sum != dr - st + 1) {
      return make_pair(node, make_pair(st, dr));
    }
    return make_pair(nullptr, make_pair(0, 0));
  }
  int mij = (st + dr) >> 1;
  pair<SegmentTree*, pair<int, int>> ans = make_pair(nullptr, make_pair(0, 0));
  if (query_left <= mij) {
    ans = find_segment_with_0(node->left_son, st, mij, query_left, query_right);
  }
  if (ans.first != nullptr) {
    return ans;
  }
  if (query_right > mij) {
    ans = find_segment_with_0(node->right_son, mij + 1, dr, query_left,
                              query_right);
  }
  return ans;
}
int find_first_0(SegmentTree* node, int st, int dr) {
  if (st == dr) {
    return st;
  }
  propaga(node, st, dr);
  int mij = (st + dr) >> 1;
  if (node->left_son->sum != mij - st + 1) {
    return find_first_0(node->left_son, st, mij);
  } else {
    return find_first_0(node->right_son, mij + 1, dr);
  }
}
SegmentTree* update(SegmentTree* node, int st, int dr, int update_left,
                    int update_right, int value) {
  if (st != dr) {
    propaga(node, st, dr);
  }
  SegmentTree* new_node = new SegmentTree();
  if (update_left <= st && dr <= update_right) {
    new_node->add = value + 1;
    new_node->sum = (dr - st + 1) * value;
    new_node->h1 = value == 0 ? 0 : h1_full1[dr - st + 1];
    new_node->h2 = value == 0 ? 0 : h2_full1[dr - st + 1];
    return new_node;
  }
  int mij = (st + dr) >> 1;
  if (update_left <= mij) {
    new_node->left_son =
        update(node->left_son, st, mij, update_left, update_right, value);
  } else {
    new_node->left_son = node->left_son;
  }
  if (update_right > mij) {
    new_node->right_son =
        update(node->right_son, mij + 1, dr, update_left, update_right, value);
  } else {
    new_node->right_son = node->right_son;
  }
  new_node->sum = new_node->left_son->sum + new_node->right_son->sum;
  new_node->h1 = (1LL * new_node->left_son->h1 * pb_h1[dr - mij] +
                  new_node->right_son->h1) %
                 999999929;
  new_node->h2 = (1LL * new_node->right_son->h2 * pb_h2[dr - mij] +
                  new_node->right_son->h2) %
                 999999937;
  return new_node;
}
inline SegmentTree* add(SegmentTree* root, int exp) {
  pair<SegmentTree*, pair<int, int>> segment =
      find_segment_with_0(root, 1, conf_length, exp, conf_length);
  assert(segment.first != nullptr);
  int position_of_first_0 =
      find_first_0(segment.first, segment.second.first, segment.second.second);
  SegmentTree* new_root = root;
  if (position_of_first_0 != exp) {
    new_root =
        update(new_root, 1, conf_length, exp, position_of_first_0 - 1, 0);
  }
  new_root = update(new_root, 1, conf_length, position_of_first_0,
                    position_of_first_0, 1);
  return new_root;
}
int compare(const SegmentTree* t1, const SegmentTree* t2, int st, int dr,
            int fixed1, int fixed2) {
  if (fixed1 && fixed2) {
    return fixed1 > fixed2;
  }
  if (st == dr) {
    if (!fixed1) {
      fixed1 = t1->sum + 1;
    }
    if (!fixed2) {
      fixed2 = t2->sum + 1;
    }
    return fixed1 > fixed2;
  }
  int mij = (st + dr) >> 1;
  if (!fixed1) {
    fixed1 = t1->add;
  }
  if (!fixed2) {
    fixed2 = t2->add;
  }
  int right_h1_t1 =
      fixed1 ? (fixed1 == 1 ? 0 : h1_full1[dr - mij]) : t1->right_son->h1;
  int right_h2_t1 =
      fixed1 ? (fixed1 == 1 ? 0 : h2_full1[dr - mij]) : t1->right_son->h2;
  int right_h1_t2 =
      fixed2 ? (fixed2 == 1 ? 0 : h1_full1[dr - mij]) : t2->right_son->h1;
  int right_h2_t2 =
      fixed2 ? (fixed2 == 1 ? 0 : h2_full1[dr - mij]) : t2->right_son->h2;
  if (right_h1_t1 == right_h1_t2 && right_h2_t1 == right_h2_t2) {
    return compare(t1 ? t1->left_son : nullptr, t2 ? t2->left_son : nullptr, st,
                   mij, fixed1, fixed2);
  } else {
    return compare(t1 ? t1->right_son : nullptr, t2 ? t2->right_son : nullptr,
                   mij + 1, dr, fixed1, fixed2);
  }
}
struct tree_cmp {
  inline bool operator()(const pair<SegmentTree*, int>& p1,
                         const pair<SegmentTree*, int>& p2) {
    return compare(p1.first, p2.first, 1, conf_length, 0, 0);
  }
};
void get_sum(SegmentTree* node, int st, int dr, int& cost) {
  if (st == dr) {
    cost = cost + cost + node->sum;
    if (cost >= 1000000007) {
      cost -= 1000000007;
    }
    return;
  }
  propaga(node, st, dr);
  int mij = (st + dr) >> 1;
  get_sum(node->right_son, mij + 1, dr, cost);
  get_sum(node->left_son, st, mij, cost);
}
inline void dijkstra() {
  vector<pair<SegmentTree*, int>> H;
  H.push_back(make_pair(root[source], source));
  for (; !H.empty();) {
    int nod = H.front().second;
    SegmentTree* possible_root = H.front().first;
    pop_heap(H.begin(), H.end(), tree_cmp());
    H.pop_back();
    if (possible_root != root[nod]) {
      continue;
    }
    for (pair<int, int> itt : G[nod]) {
      int vecin = itt.first, cost = itt.second;
      SegmentTree* new_root = add(root[nod], cost);
      tree_cmp comparator;
      if (root[vecin] == nullptr ||
          comparator(make_pair(root[vecin], 0), make_pair(new_root, 0))) {
        root[vecin] = new_root;
        T[vecin] = nod;
        H.push_back(make_pair(root[vecin], vecin));
        push_heap(H.begin(), H.end(), tree_cmp());
      }
    }
  }
}
int main() {
  scanf("%d %d", &n, &m);
  int max_cost = 0;
  for (int i = 1; i <= m; ++i) {
    int x, y, c;
    scanf("%d %d %d", &x, &y, &c);
    ++c;
    G[x].push_back(make_pair(y, c));
    G[y].push_back(make_pair(x, c));
    max_cost = max(max_cost, c);
  }
  scanf("%d %d", &source, &destination);
  conf_length = 0;
  while ((1 << conf_length) <= m) {
    ++conf_length;
  }
  conf_length += max_cost + 1;
  pb_h1[0] = pb_h2[0] = 1;
  for (int i = 1; i <= conf_length; ++i) {
    pb_h1[i] = (1LL * pb_h1[i - 1] * 73) % 999999929;
    pb_h2[i] = (1LL * pb_h2[i - 1] * 73) % 999999937;
    h1_full1[i] = (1LL * h1_full1[i - 1] * 73 + 1) % 999999929;
    h2_full1[i] = (1LL * h2_full1[i - 1] * 73 + 1) % 999999937;
  }
  root = vector<SegmentTree*>(n + 1, nullptr);
  root[source] = init_tree(1, 1, conf_length);
  dijkstra();
  if (root[destination]) {
    int cost = 0;
    get_sum(root[destination], 1, conf_length, cost);
    vector<int> path;
    while (destination != source) {
      path.push_back(destination);
      destination = T[destination];
    }
    path.push_back(source);
    reverse(path.begin(), path.end());
    printf("%d\n%d\n", cost, (int)path.size());
    for (int nod : path) {
      printf("%d ", nod);
    }
    printf("\n");
  } else {
    printf("-1\n");
  }
  return 0;
}
