和 puts("-1") 的输出完全一致(雾
#include<bits/stdc++.h>
#define sd std::
#define int long long
#define inf 0x3f3f3f3f
#define linf 1e18
#define il inline
#define db double
#define ldb long double
#define F(i,a,b) for(int i=(a);i<=(b);i++)
#define f(i,a,b) for(int i=(a);i>=(b);i--)
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)
#define me(x,y) memset(x,y,sizeof x)
#define pii sd pair<int,int>
#define umap(x,y) sd unordered_map<x,y>
#define pque(x) sd priority_queue<x>
#define X first
#define Y second
#define kg putchar(' ')
#define Fr(a) for(auto it:a)
#define dbg(x) sd cout<<#x<<": "<<x<<sd endl
il int read(){int w=1,c=0;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) c=(c<<3)+(c<<1)+ch-48;return w*c;}
void printt(int x){if(x>9) printt(x/10);putchar(x%10+48);}
il void print(int x){if(x<0) putchar('-'),printt(-x);else printt(x);}
il void put(int x){print(x);putchar('\n');}
il void printk(int x){print(x);kg;}
const int N=1e5+10;
const int mod=1e5+10;
int po[N],h[N];//预处理2次幂以及hash值
int n,m,ma;//ma记录最大边权
struct node
{
int nex;
int to;
int w;
}a[N<<1];
int cnt,head[N];
void add(int u,int v,int w)
{
a[++cnt].nex=head[u];
head[u]=cnt;
a[cnt].to=v;
a[cnt].w=w;
}
struct pst_tree
{
struct node
{
int l,r;
int val;
int ha;//哈希值
bool pd;//记录区间是否全为1,用来找最长1。
}t[N<<5];
int root[N],tot=0;
#define l(i) t[i].l
#define r(i) t[i].r
#define val(i) t[i].val
#define ha(i) t[i].ha
#define pd(i) t[i].pd
void pushup(int k)
{
pd(k)=pd(l(k))&pd(r(k));
val(k)=(val(l(k))+val(r(k)))%mod;
ha(k)=(ha(l(k))+ha(r(k)))%mod;
}
int newly(int k)
{
t[++tot]=t[k];
return tot;
}
int built(int k,int l,int r,int v)
{
k=++tot;
if(l==r) return val(k)=po[l]*v,h[l]*v,pd(k)=v,tot;
int mid=l+r>>1;
l(k)=built(l(k),l,mid,v);
r(k)=built(r(k),mid+1,r,v);
pushup(k);
return k;
}
bool check(int k,int l,int r,int x,int y)//判区间是否为1
{
if(!k) return 0;
if(x<=l&&y>=r) return pd(k);
int mid=l+r>>1,sum=true;
if(x<=mid) sum&=check(l(k),l,mid,x,y);
if(y>mid) sum&=check(r(k),mid+1,r,x,y);
return sum;
}
int upd_dan(int k,int l,int r,int x)//单点修1
{
k=newly(k);
if(l==r) return val(k)=po[l],ha(k)=h[l],pd(k)=1,k;
int mid=l+r>>1;
if(x<=mid) l(k)=upd_dan(l(k),l,mid,x);
else r(k)=upd_dan(r(k),mid+1,r,x);
return k;
}
int upd_qu(int k,int l,int r,int x,int y)//区间修0
{
k=newly(k);
if(x<=l&&y>=r) return k;
int mid=l+r>>1;
if(x<=mid) l(k)=upd_qu(l(k),l,mid,x,y);
if(y>mid) r(k)=upd_qu(r(k),mid+1,r,x,y);
return k;
}
void add(int u,int v)
{
int l=v,r=ma,ans=v-1;
while(l<=r)
{
int mid=l+r>>1;
if(check(root[u],0,ma,v,mid)) ans=mid,l=mid+1;
else r=mid-1;
}
root[n+1]=root[u];
if(v<=ans) upd_qu(root[n+1],0,ma,v,ans);
upd_dan(root[n+1],0,ma,ans+1);
}
bool cmp(int x,int y,int l,int r)//两颗主席树比大小,比较区间为l~r
{
if(l==r) return pd(x)>pd(y);
int mid=l+r>>1;
if(val(r(x))!=val(r(y))&&ha(r(x))!=ha(r(y))) return cmp(r(x),r(y),mid+1,r);
else return cmp(l(x),l(y),l,mid);
}
}T;
struct dcz
{
int u,d;
bool operator<(const dcz& b)const
{
return T.cmp(d,b.d,0,ma);
}
};
int st,en;//起点终点
int vis[N],pre[N],ans[N];
pque(dcz) q;
void dij()
{
T.built(T.root[st],0,ma,0);
T.built(T.root[0],0,ma,1);
F(i,1,n)
{
if(i==st) continue;
T.root[i]=T.root[0];
}
q.push({st,T.root[st]});
while(!q.empty())
{
auto [u,d]=q.top();
q.pop();
put(u);
if(vis[u]) continue;
vis[u]=1;
if(u==en) return;
for(int i=head[u];i;i=a[i].nex)
{
int v=a[i].to;
T.add(u,a[i].w);
if(T.cmp(T.root[v],T.root[n+1],0,ma))
{
T.root[v]=T.root[n+1],pre[v]=u;//顺便记录前驱
if(!vis[v]) q.push({u,T.root[u]});
}
}
}
}
il void init()
{
po[0]=1,h[0]=1;
F(i,1,ma) po[i]=(po[i-1]<<1)%mod,h[i]=(h[i-1]*123)%mod;
}
il void solve()
{
n=read(),m=read();
F(i,1,m)
{
int x=read(),y=read(),z=read();
ma=MAX(ma,z)+100;
add(x,y,z);
add(y,x,z);
}
st=read(),en=read();
init();
dij();
if(!T.pd(T.root[en])) return put(-1);
put(T.val(T.root[en]));
int c=0;
while(en!=st) ans[++c]=en,en=pre[en];//倒退回去
put(c);
f(i,c,1) printk(ans[i]);
return;
}
signed main()
{
int T=1;
// T=read();
while(T--) solve();
return 0;
}