#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=114514,p1=1000000007,p2=1145141923,Inf=0x3f3f3f3f;
struct Xds{
int ls=0,rs=0,l=0,r=0,v=0,hs1=0,hs2=0,tag=-1;
}a[N<<6];
int pw1[N],pw2[N];
int new_Xds(){static int p=0;return ++p;}
int new_Xds(int i){int p=new_Xds();a[p]=a[i];return p;}
void new_so(int i){a[i].ls=new_Xds(a[i].ls);a[i].rs=new_Xds(a[i].rs);}
void push_down(int i,int j){
if(a[i].tag!=-1){
a[j].v=a[i].tag?(a[j].r-a[j].l+1):0;
a[j].hs1=a[i].tag?(pw1[a[j].r-a[j].l+1]-1):0;
a[j].hs2=a[i].tag?(pw2[a[j].r-a[j].l+1]-1):0;
a[j].tag=a[i].tag;
}
}
void push_down(int i){
new_so(i);
push_down(i,a[i].ls);
push_down(i,a[i].rs);
a[i].tag=-1;
}
void push_up(int i){
a[i].v=a[a[i].ls].v+a[a[i].rs].v;
a[i].hs1=((ll)a[a[i].ls].hs1+(ll)a[a[i].rs].hs1*(ll)pw1[a[a[i].ls].r-a[a[i].ls].l+1])%p1;
a[i].hs2=((ll)a[a[i].ls].hs2+(ll)a[a[i].rs].hs2*(ll)pw2[a[a[i].ls].r-a[a[i].ls].l+1])%p2;
}
void build(int i,int l,int r){
a[i].l=l;
a[i].r=r;
if(a[i].l==a[i].r){return;}
new_so(i);
int mid=a[i].l+a[i].r>>1;
build(a[i].ls,l,mid);
build(a[i].rs,mid+1,r);
}
int build(){int rt=new_Xds();build(rt,1,N);return rt;}
int cmp_(int i1,int i2){
if(a[i1].hs1==a[i2].hs1 && a[i1].hs2==a[i2].hs2) return 0;
if(a[i1].l==a[i1].r){
return a[i1].v<a[i2].v?-1:(a[i1].v==a[i2].v?0:1);
}
push_down(i1);
push_down(i2);
if(a[a[i1].rs].hs1!=a[a[i2].rs].hs1 || a[a[i1].rs].hs2!=a[a[i2].rs].hs2){
return cmp_(a[i1].rs,a[i2].rs);
}
else{
return cmp_(a[i1].ls,a[i2].ls);
}
}
bool cmp(int& rt1,int& rt2){int p1=new_Xds(rt1),p2=new_Xds(rt2);bool b=cmp_(p1,p2);rt1=p1,rt2=p2;return b;}
void change_(int i,int l,int r,int x){
if(a[i].l>=l && a[i].r<=r){
a[i].v=x?(a[i].r-a[i].l+1):0;
a[i].hs1=x?(pw1[a[i].r-a[i].l+1]-1):0;
a[i].hs2=x?(pw2[a[i].r-a[i].l+1]-1):0;
a[i].tag=x;
return;
}
push_down(i);
int mid=a[i].l+a[i].r>>1;
if(mid>=l) change_(a[i].ls,l,r,x);
if(mid<r) change_(a[i].rs,l,r,x);
push_up(i);
}
int change(int rt,int l,int r,int x){int p=new_Xds(rt);change_(p,l,r,x);return p;}
int query_(int i,int l,int r){
if(a[i].l>=l && a[i].r<=r) return a[i].v;
push_down(i);
int mid=a[i].l+a[i].r>>1,ans=0;
if(mid>=l) ans+=query_(a[i].ls,l,r);
if(mid<r) ans+=query_(a[i].rs,l,r);
return ans;
}
int query(int& rt,int l,int r){int p=new_Xds(rt);int ans=query_(p,l,r);rt=p;return ans;}
int add(int rt,int x){
int p=new_Xds(rt);
int l=x-1,r=N-2;
while(l<r){
int mid=l+r+1>>1;
if(query(p,x,mid)==mid-x+1) l=mid;
else r=mid-1;
}
if(l>=x) p=change(p,x,l,0);
p=change(p,l+1,l+1,1);
return p;
}
int n,m,bg,ed;
struct Edge{
int v,w;
Edge(){}
Edge(int v_,int w_):v(v_),w(w_){}
};
vector<Edge> G[N];
struct qwq{
int u,lt,ds;
qwq(){}
qwq(int u_,int lt_,int ds_):u(u_),lt(lt_),ds(ds_){}
};
struct my_cmp{
bool operator ()(qwq x,qwq y){
return cmp(x.ds,y.ds)==1;
}
};
priority_queue<qwq,vector<qwq>,my_cmp> q;
int dis[N],lt[N];
void dijkstra(int u){
q.push(qwq(u,0,build()));
while(!q.empty()){
qwq u=q.top();
q.pop();
if(dis[u.u]) continue;
dis[u.u]=u.ds;
lt[u.u]=u.lt;
for(Edge v:G[u.u]) q.push(qwq(v.v,u.u,add(u.ds,v.w)));
}
}
vector<int> ans;
signed main(){
pw1[0]=pw2[0]=1;
for(int i=1;i<N;++i) pw1[i]=pw1[i-1]*2%p1,pw2[i]=pw2[i-1]*2%p2;
cin >> n >> m;
while(m--){
int u,v,w;
cin >> u >> v >> w;
G[u].push_back(Edge(v,w+1));
G[v].push_back(Edge(u,w+1));
}
cin >> bg >> ed;
dijkstra(bg);
if(bg==ed){
cout << "0\n1\n" << bg << endl;
return 0;
}
if(a[dis[ed]].hs1==0 && a[dis[ed]].hs2==0){
cout << "-1" << endl;
return 0;
}
cout << a[dis[ed]].hs1 << endl;
while(ed!=0) ans.push_back(ed),ed=lt[ed];
cout << ans.size() << endl;
for(int i=ans.size()-1;i>=0;--i) cout << ans[i] << " ";
return 0;
}