#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
const int N = 400000;
long long B71[N];
long long B46[N];
long long B2[N];
void init() {
  B71[0] = B46[0] = B2[0] = 1;
  for (int i = 1; i < N; i++) {
    B71[i] = (71 * B71[i - 1]) % mod;
    B46[i] = (46 * B46[i - 1]) % mod;
    B2[i] = (B2[i - 1] * 2) % mod;
  }
}
struct Node {
  Node *l, *r;
  int firstZero;
  long long hush71, hush46;
  Node() : l(0), r(0), firstZero(0), hush71(0), hush46(0) {}
};
void update_root(Node *&root, int st, int ed) {
  root->firstZero = min(root->l->firstZero, root->r->firstZero);
  int md = (st + ed) / 2;
  int r_leng = ed - md;
  root->hush46 = (root->l->hush46 * B46[r_leng] + root->r->hush46) % mod;
  root->hush71 = (root->l->hush71 * B71[r_leng] + root->r->hush71) % mod;
}
void build(int st, int ed, Node *root) {
  if (st == ed) {
    root->firstZero = st;
    root->hush46 = 1;
    root->hush71 = 1;
  } else {
    int md = (st + ed) / 2;
    if (!root->l) root->l = new Node();
    if (!root->r) root->r = new Node();
    build(st, md, root->l);
    build(md + 1, ed, root->r);
    update_root(root, st, ed);
  }
}
int get_first_zero(int pos, Node *root, int st, int ed) {
  if (st == ed) {
    return root->firstZero;
  } else if (pos <= st) {
    return root->firstZero;
  } else {
    int md = (st + ed) / 2;
    int ans = N - 1;
    if (root->firstZero >= pos) ans = root->firstZero;
    if (pos <= md) {
      ans = min(ans, get_first_zero(pos, root->l, st, md));
      ans = min(ans, get_first_zero(pos, root->r, md + 1, ed));
    } else {
      ans = min(ans, get_first_zero(pos, root->r, md + 1, ed));
    }
    return ans;
  }
}
Node *hatNod7elwa(Node *root) {
  Node *ans = new Node();
  if (root->l) ans->l = root->l;
  if (root->r) ans->r = root->r;
  ans->hush46 = root->hush46;
  ans->hush71 = root->hush71;
  ans->firstZero = root->firstZero;
  return ans;
}
void up_r_p(int l, int r, int st, int ed, Node *&root, Node *orgin) {
  if (root->l) root->l = hatNod7elwa(root->l);
  if (root->r) root->r = hatNod7elwa(root->r);
  if (st == ed) {
    root = orgin;
  } else if (l <= st && ed <= r) {
    root = orgin;
  } else {
    int md = (st + ed) / 2;
    if (l <= md) {
      up_r_p(l, r, st, md, root->l, orgin->l);
    }
    if (md < r) {
      up_r_p(l, r, md + 1, ed, root->r, orgin->r);
    }
    update_root(root, st, ed);
  }
}
void update_one(int pos, int st, int ed, Node *&root, Node *proot) {
  if (st == ed) {
    root = new Node();
    root->firstZero = N - 1;
    root->hush46 = root->hush71 = 2;
  } else {
    int md = (st + ed) / 2;
    if (pos <= md) {
      if (!root->l) root->l = new Node();
      update_one(pos, st, md, root->l, proot->l);
      root->r = proot->r;
    } else {
      if (!root->r) root->r = new Node();
      update_one(pos, md + 1, ed, root->r, proot->r);
      root->l = proot->l;
    }
    update_root(root, st, ed);
  }
}
bool comp(const Node *r1, const Node *r2) {
  if (!r1->l) {
    return r1->hush46 > r2->hush46;
  } else {
    if (r1->r->hush46 == r2->r->hush46)
      return comp(r1->l, r2->l);
    else
      return comp(r1->r, r2->r);
  }
}
struct sta {
  Node *cst;
  int node;
  int pinx;
  bool operator<(const sta &st2) const { return comp(cst, st2.cst); }
};
int calc(int st, int ed, Node *root) {
  if (st == ed) {
    if (root->hush46 == 2)
      return B2[st];
    else
      return 0;
  } else {
    int md = (st + ed) / 2;
    long long res = 0;
    res = (res + calc(st, md, root->l)) % mod;
    res = (res + calc(md + 1, ed, root->r)) % mod;
    return res;
  }
}
const int l = 300123;
Node *orgin;
vector<vector<pair<int, int> > > vec;
void prepare(Node *proot, Node *&root, int index) {
  int pos = get_first_zero(index, proot, 0, l);
  if (index < pos) {
    update_one(pos, 0, l, root, proot);
    up_r_p(index, pos - 1, 0, l, root, orgin);
  } else {
    update_one(pos, 0, l, root, proot);
  }
}
bool vis[N];
Node *dest[N];
vector<pair<int, int> > path;
vector<int> ans;
void get_ans(int indx) {
  if (indx == -1) return;
  get_ans(path[indx].first);
  ans.push_back(path[indx].second);
}
void print_path(int indx) {
  if (indx == -1) return;
  print_path(path[indx].first);
  printf("%d ", path[indx].second);
}
int dijk(int st, int ed) {
  priority_queue<sta> q;
  sta start;
  start.cst = orgin;
  start.node = st;
  start.pinx = 0;
  q.push(start);
  path.push_back(make_pair(-1, st));
  while (q.size()) {
    const sta cur = q.top();
    if (cur.node == ed) {
      get_ans(cur.pinx);
      return calc(0, l, cur.cst);
    }
    q.pop();
    for (int i = 0; i < (int)vec[cur.node].size(); i++) {
      int nxt_node = vec[cur.node][i].first;
      int cost = vec[cur.node][i].second;
      if (nxt_node == st) continue;
      if (!vis[nxt_node]) {
        dest[nxt_node] = new Node();
        prepare(cur.cst, dest[nxt_node], cost);
        sta a;
        a.cst = dest[nxt_node];
        a.node = nxt_node;
        a.pinx = path.size();
        path.push_back(make_pair(cur.pinx, nxt_node));
        q.push(a);
        vis[nxt_node] = 1;
      } else {
        Node *tmp = new Node();
        prepare(cur.cst, tmp, cost);
        if (comp(dest[nxt_node], tmp)) {
          dest[nxt_node] = tmp;
          sta a;
          a.cst = tmp;
          a.node = nxt_node;
          a.pinx = path.size();
          path.push_back(make_pair(cur.pinx, nxt_node));
          q.push(a);
        }
      }
    }
  }
  return -1;
}
int main() {
  init();
  orgin = new Node();
  build(0, l, orgin);
  int n, m;
  scanf("%d%d", &n, &m);
  vec.resize(n + 1);
  while (m--) {
    int u, v, c;
    scanf("%d%d%d", &u, &v, &c);
    vec[u].push_back(make_pair(v, c));
    vec[v].push_back(make_pair(u, c));
  }
  int st, ed;
  scanf("%d%d", &st, &ed);
  int res = dijk(st, ed);
  if (res == -1) {
    puts("-1");
  } else {
    printf("%d\n%d\n", res, (int)ans.size());
    for (int i = 0; i < (int)ans.size(); i++) {
      printf("%d%c", ans[i], " \n"[i == (int)ans.size() - 1]);
    }
  }
}
