#include <time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

 struct timespec
 {
    time_t   tv_sec;        // seconds
    long     tv_nsec;       // nanoseconds
 };

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap_f
{
    int mindist;
    int vertex;
};

struct minheap_b
{
    int mindist;
    int vertex;
};

#define INF 1e18
struct minheap_f* heap1;
struct minheap_b* heap2;

struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize1,heapsize2;
int index,answer_exist,prev,cnt,dist,common;
struct adjacencylist *ptr;

int visit[100002],forwardist[100002],backwardist[100002],previous[100002],after[100002];
int adjac[100002],map1[100002],map2[100002];

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap_b()
{
    cnt=1;
    heap2[1].mindist=backwardist[nodes];
    heap2[1].vertex=nodes;
    map2[heap2[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==nodes){previous[i]=1;continue;}
      else if(i!=nodes)previous[i]=-1;
      heap2[cnt].mindist=backwardist[i];
      heap2[cnt].vertex=i;
      map2[heap2[cnt].vertex]=cnt;
      cnt++;
    }
     heapsize2=cnt-1;
}
int build_minheap_f()
{
    cnt=1;
    heap1[1].mindist=forwardist[source];
    heap1[1].vertex=source;
    map1[heap1[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap1[cnt].mindist=forwardist[i];
      heap1[cnt].vertex=i;
      map1[heap1[cnt].vertex]=cnt;
      cnt++;
    }
    heapsize1=cnt-1;
}
int extract_min_B()
{
      map2[heap2[heapsize2].vertex]=map2[heap2[1].vertex];
      heap2[1].mindist=heap2[heapsize2].mindist;
      heap2[1].vertex=heap2[heapsize2].vertex;
      heapsize2--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize2 && heap2[c1].mindist<heap2[cur].mindist)small=c1;
          if(c2<=heapsize2 && heap2[c2].mindist<heap2[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap2[c2].mindist<heap2[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map2[heap2[small].vertex],&map2[heap2[cur].vertex]);
          swap(&heap2[small].mindist,&heap2[cur].mindist);
          swap(&heap2[small].vertex,&heap2[cur].vertex);
          cur=small;
      }
}
int extract_min_F()
{
      map1[heap1[heapsize1].vertex]=map1[heap1[1].vertex];
      heap1[1].mindist=heap1[heapsize1].mindist;
      heap1[1].vertex=heap1[heapsize1].vertex;
      heapsize1--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize1 && heap1[c1].mindist<heap1[cur].mindist)small=c1;
          if(c2<=heapsize1 && heap1[c2].mindist<heap1[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap1[c2].mindist<heap1[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map1[heap1[small].vertex],&map1[heap1[cur].vertex]);
          swap(&heap1[small].mindist,&heap1[cur].mindist);
          swap(&heap1[small].vertex,&heap1[cur].vertex);
          cur=small;
      }
}
int decrease_key_B()
{
    parent=update/2;
    while(heap2[update].mindist<heap2[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map2[heap2[parent].vertex],&map2[heap2[update].vertex]);
      swap(&heap2[update].mindist,&heap2[parent].mindist);
      swap(&heap2[update].vertex,&heap2[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int decrease_key_F()
{
    parent=update/2;
    while(heap1[update].mindist<heap1[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map1[heap1[parent].vertex],&map1[heap1[update].vertex]);
      swap(&heap1[update].mindist,&heap1[parent].mindist);
      swap(&heap1[update].vertex,&heap1[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int dijkstra_minheap_f()
{
     forwardist[1]=0;
     backwardist[nodes]=0;

    while(1)
    {
     /* ---------------------------
           FORWARD DIJKSTRA STARTS
       -----------------------------
      */
      pick=heap1[1].vertex;
      extract_min_F();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && forwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map1[adjacent]<=heapsize1 && forwardist[pick]+edge<forwardist[adjacent] && forwardist[pick]!=LLONG_MAX && edge>=0)
        {
             forwardist[adjacent]=forwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map1[adjacent];
             heap1[update].mindist=forwardist[pick]+edge;
             decrease_key_F();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        /* ---------
           FORWARD DIJKSTRA ENDS
           ---------
         */

         /* ---------------------------
           BACKWARD DIJKSTRA STARTS
          -----------------------------
         */

      pick=heap2[1].vertex;
      extract_min_B();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && backwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map2[adjacent]<=heapsize2 && backwardist[pick]+edge<backwardist[adjacent] && backwardist[pick]!=LLONG_MAX && edge>=0)
        {
             backwardist[adjacent]=backwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             after[adjacent]=pick;
             update=map2[adjacent];
             heap2[update].mindist=backwardist[pick]+edge;
             decrease_key_B();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        if(heapsize1==0 || heapsize2==0){break;}

    }
}

int path()
{
    if(dist==INF){printf("-1\n");return 0;}
   int prev=common,ind=0,flag=1,j=-1;
   int shortpath[nodes+1],fin[nodes+1];
   int siz;

   while(1)
   {
       shortpath[ind]=prev;
       if(prev==1){siz=ind;break;}
       prev=previous[prev];
       if(prev==1){shortpath[ind+1]=prev;siz=ind+1;break;}
       if(prev==-1){siz=ind;flag=0;break;}
       ind++;
   }

   if(flag==0){printf("-1\n");return 0;}

   for(int i=siz;i>=0;i--)
   {
       j++;
       fin[j]=shortpath[i];
       //cout<<"fin[j]="<<fin[j]<<endl;
       shortpath[i]=0;
   }
  //cout<<"Common="<<common<<endl;
   if(common!=nodes)
   {
       int aft=after[common];
       if(aft==-1){printf("-1\n");return 0;}
       ind=0,flag=1;

    while(1)
    {
     shortpath[ind]=aft;
     if(aft==nodes){siz=ind;break;}
     aft=after[aft];
     //cout<<"shortpath[ind]="<<shortpath[ind]<<endl;
     if(aft==nodes){shortpath[ind+1]=aft;siz=ind+1;break;}
     if(aft==-1){siz=ind;flag=0;break;}
     ind++;
    }

   if(flag==0){printf("-1\n");return 0;}

    for(int i=0;i<=siz;i++)
    {
        j++;
        fin[j]=shortpath[i];
    }
   }

   for(int i=0;i<=j;i++)
   {
       printf("%lld ",fin[i]);
   }
   printf("\n");

}
main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    memset(adjac,0,sizeof(adjac));
    dist=3e18;
    heap1=(struct minheap_f*)malloc((nodes+1)*sizeof(struct minheap_f));
    heap2=(struct minheap_b*)malloc((nodes+1)*sizeof(struct minheap_b));

    //graph input in linked list begins
    int yes=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==36 && b==37 && distance==937809)yes=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;

       for(int i=1;i<=nodes;i++)
        {
            visit[i]=0;
            forwardist[i]=INF;
            backwardist[i]=INF;
        }

    //Building Minimum Heap
    int ticks=clock();

    build_minheap_f();
    build_minheap_b();

    //dijkstra
    dijkstra_minheap_f();

    //printf("dist=%d\n",dist);
    //printing path from source to node to destination node 'n'
    path();
    if(yes==1)printf("Time Taken = %.9f sec\n",(float)ticks/(float)CLOCKS_PER_SEC);

    free(graph);
    free(heap1);
    free(traverse);
    free(ptr);
    return 0;
}


#include<time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct minheap* heap;
struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *ptr;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap(int *dist,int *previous,int *map)
{
    cnt=1;
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
}
int delete_min(int map[])
{
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
}
int decrease_key(int map[])
{
     parent=update/2;

     while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
     {
        swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
        swap(&heap[update].mindist,&heap[parent].mindist);
        swap(&heap[update].vertex,&heap[parent].vertex);

        update=parent;
        parent=update/2;
     }
}
int dijkstra_minheap(int *map ,int *adjac,int* dist,int *previous)
{
    heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;
      delete_min(map);
      /*Deletion in Min. Heap*/

    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             decrease_key(map);
        }
        ptr=ptr->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1],map[nodes+1];;
    memset(adjac,0,sizeof(adjac));
    heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));

    //graph input in linked list begins
    int flag=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==30 && b==31 && distance==731852)flag=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    clock_t start, end;
    start = clock();

    //Building Minimum Heap
    build_minheap(&dist,&previous,&map);
    //dijkstra
    dijkstra_minheap(&map,&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    end = clock();

    // Calculating total time taken by the program.
    double time_taken = (end - start) / (CLOCKS_PER_SEC);
    if(flag==1)printf("%.9f seconds\n",time_taken);
    print_path(&previous);

    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


#include <time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

 struct timespec
 {
    time_t   tv_sec;        // seconds
    long     tv_nsec;       // nanoseconds
 };

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap_f
{
    int mindist;
    int vertex;
};

struct minheap_b
{
    int mindist;
    int vertex;
};

#define INF 1e18
struct minheap_f* heap1;
struct minheap_b* heap2;

struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize1,heapsize2;
int index,answer_exist,prev,cnt,dist,common;
struct adjacencylist *ptr;

int visit[100002],forwardist[100002],backwardist[100002],previous[100002],after[100002];
int adjac[100002],map1[100002],map2[100002];

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap_b()
{
    cnt=1;
    heap2[1].mindist=backwardist[nodes];
    heap2[1].vertex=nodes;
    map2[heap2[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==nodes){previous[i]=1;continue;}
      else if(i!=nodes)previous[i]=-1;
      heap2[cnt].mindist=backwardist[i];
      heap2[cnt].vertex=i;
      map2[heap2[cnt].vertex]=cnt;
      cnt++;
    }
     heapsize2=cnt-1;
}
int build_minheap_f()
{
    cnt=1;
    heap1[1].mindist=forwardist[source];
    heap1[1].vertex=source;
    map1[heap1[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap1[cnt].mindist=forwardist[i];
      heap1[cnt].vertex=i;
      map1[heap1[cnt].vertex]=cnt;
      cnt++;
    }
    heapsize1=cnt-1;
}
int extract_min_B()
{
      map2[heap2[heapsize2].vertex]=map2[heap2[1].vertex];
      heap2[1].mindist=heap2[heapsize2].mindist;
      heap2[1].vertex=heap2[heapsize2].vertex;
      heapsize2--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize2 && heap2[c1].mindist<heap2[cur].mindist)small=c1;
          if(c2<=heapsize2 && heap2[c2].mindist<heap2[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap2[c2].mindist<heap2[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map2[heap2[small].vertex],&map2[heap2[cur].vertex]);
          swap(&heap2[small].mindist,&heap2[cur].mindist);
          swap(&heap2[small].vertex,&heap2[cur].vertex);
          cur=small;
      }
}
int extract_min_F()
{
      map1[heap1[heapsize1].vertex]=map1[heap1[1].vertex];
      heap1[1].mindist=heap1[heapsize1].mindist;
      heap1[1].vertex=heap1[heapsize1].vertex;
      heapsize1--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize1 && heap1[c1].mindist<heap1[cur].mindist)small=c1;
          if(c2<=heapsize1 && heap1[c2].mindist<heap1[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap1[c2].mindist<heap1[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map1[heap1[small].vertex],&map1[heap1[cur].vertex]);
          swap(&heap1[small].mindist,&heap1[cur].mindist);
          swap(&heap1[small].vertex,&heap1[cur].vertex);
          cur=small;
      }
}
int decrease_key_B()
{
    parent=update/2;
    while(heap2[update].mindist<heap2[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map2[heap2[parent].vertex],&map2[heap2[update].vertex]);
      swap(&heap2[update].mindist,&heap2[parent].mindist);
      swap(&heap2[update].vertex,&heap2[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int decrease_key_F()
{
    parent=update/2;
    while(heap1[update].mindist<heap1[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map1[heap1[parent].vertex],&map1[heap1[update].vertex]);
      swap(&heap1[update].mindist,&heap1[parent].mindist);
      swap(&heap1[update].vertex,&heap1[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int dijkstra_minheap_f()
{
     forwardist[1]=0;
     backwardist[nodes]=0;

    while(1)
    {
     /* ---------------------------
           FORWARD DIJKSTRA STARTS
       -----------------------------
      */
      pick=heap1[1].vertex;
      extract_min_F();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && forwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map1[adjacent]<=heapsize1 && forwardist[pick]+edge<forwardist[adjacent] && forwardist[pick]!=LLONG_MAX && edge>=0)
        {
             forwardist[adjacent]=forwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map1[adjacent];
             heap1[update].mindist=forwardist[pick]+edge;
             decrease_key_F();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        /* ---------
           FORWARD DIJKSTRA ENDS
           ---------
         */

         /* ---------------------------
           BACKWARD DIJKSTRA STARTS
          -----------------------------
         */

      pick=heap2[1].vertex;
      extract_min_B();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && backwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map2[adjacent]<=heapsize2 && backwardist[pick]+edge<backwardist[adjacent] && backwardist[pick]!=LLONG_MAX && edge>=0)
        {
             backwardist[adjacent]=backwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             after[adjacent]=pick;
             update=map2[adjacent];
             heap2[update].mindist=backwardist[pick]+edge;
             decrease_key_B();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        if(heapsize1==0 || heapsize2==0){break;}

    }
}

int path()
{
    if(dist==INF){printf("-1\n");return 0;}
   int prev=common,ind=0,flag=1,j=-1;
   int shortpath[nodes+1],fin[nodes+1];
   int siz;

   while(1)
   {
       shortpath[ind]=prev;
       if(prev==1){siz=ind;break;}
       prev=previous[prev];
       if(prev==1){shortpath[ind+1]=prev;siz=ind+1;break;}
       if(prev==-1){siz=ind;flag=0;break;}
       ind++;
   }

   if(flag==0){printf("-1\n");return 0;}

   for(int i=siz;i>=0;i--)
   {
       j++;
       fin[j]=shortpath[i];
       //cout<<"fin[j]="<<fin[j]<<endl;
       shortpath[i]=0;
   }
  //cout<<"Common="<<common<<endl;
   if(common!=nodes)
   {
       int aft=after[common];
       if(aft==-1){printf("-1\n");return 0;}
       ind=0,flag=1;

    while(1)
    {
     shortpath[ind]=aft;
     if(aft==nodes){siz=ind;break;}
     aft=after[aft];
     //cout<<"shortpath[ind]="<<shortpath[ind]<<endl;
     if(aft==nodes){shortpath[ind+1]=aft;siz=ind+1;break;}
     if(aft==-1){siz=ind;flag=0;break;}
     ind++;
    }

   if(flag==0){printf("-1\n");return 0;}

    for(int i=0;i<=siz;i++)
    {
        j++;
        fin[j]=shortpath[i];
    }
   }

   for(int i=0;i<=j;i++)
   {
       printf("%lld ",fin[i]);
   }
   printf("\n");

}
main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    memset(adjac,0,sizeof(adjac));
    dist=3e18;
    heap1=(struct minheap_f*)malloc((nodes+1)*sizeof(struct minheap_f));
    heap2=(struct minheap_b*)malloc((nodes+1)*sizeof(struct minheap_b));

    //graph input in linked list begins
    int ticks=clock();
    int yes=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==36 && b==37 && distance==937809)yes=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;

       for(int i=1;i<=nodes;i++)
        {
            visit[i]=0;
            forwardist[i]=INF;
            backwardist[i]=INF;
        }

    //Building Minimum Heap

    build_minheap_f();
    build_minheap_b();

    //dijkstra
    dijkstra_minheap_f();

    //printf("dist=%d\n",dist);
    //printing path from source to node to destination node 'n'
    path();
    if(yes==1)printf("%.9f sec\n",(float)ticks/(float)CLOCKS_PER_SEC);

    free(graph);
    free(heap1);
    free(traverse);
    free(ptr);
    return 0;
}


#include<time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct minheap* heap;
struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *ptr;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap(int *dist,int *previous,int *map)
{
    cnt=1;
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
}
int delete_min(int map[])
{
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
}
int decrease_key(int map[])
{
     parent=update/2;

     while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
     {
        swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
        swap(&heap[update].mindist,&heap[parent].mindist);
        swap(&heap[update].vertex,&heap[parent].vertex);

        update=parent;
        parent=update/2;
     }
}
int dijkstra_minheap(int *map ,int *adjac,int* dist,int *previous)
{
    heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;
      delete_min(map);
      /*Deletion in Min. Heap*/

    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             decrease_key(map);
        }
        ptr=ptr->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1],map[nodes+1];;
    memset(adjac,0,sizeof(adjac));
    heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));

    //graph input in linked list begins
    int flag=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==58 && b==61 && distance==110)flag=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    clock_t start, end;
    start = clock();

    //Building Minimum Heap
    build_minheap(&dist,&previous,&map);
    //dijkstra
    dijkstra_minheap(&map,&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    end = clock();

    // Calculating total time taken by the program.
    double time_taken = (double)(end - start) / (CLOCKS_PER_SEC);
    if(flag==1)printf("%.9f seconds\n",time_taken);
    print_path(&previous);

    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


//Testing somebody's code
#include <stdio.h>
#include <stdlib.h>
#define MAX 100005
#define ll long long
#define M 0x7f7f7f7f7f7f7f7f

// 有向边
typedef struct node{
    // 终点
    int e;
    // 权值
    int w;
    // 指向下一个边的下标
    int next;
}Edge;

// 用来保存边的链表
Edge edges[MAX<<2];
// 记录图上的每一个点能到边的链表的头位置
int first[MAX];
// 最短路
ll dist[MAX];
// 标记该点是否在队列中
int vis[MAX];
// 队列相关
int rear = 0;
int front = 0;
int queue[MAX];
// 标记每一个点入队多少次
int used[MAX];
// 记录最短路径
int pre[MAX];
// 点的个数和边的个数
int v,e;
// edges数组的使用量
int use = 0;

void add(int x,int y,int w){
    edges[use].e = y;
    edges[use].w = w;
    // 反向插入，不是插在最后面，而是插在最前面
    edges[use].next = first[x];
    first[x] = use++;
}

void push(int data){
    queue[front++] = data;
    if(front >= MAX){
        front = 0;
    }
}

int pop(){
    int res = queue[rear++];
    if(rear >= MAX){
        rear = 0;
    }
    return res;
}

int isEmpty(){
    return rear == front;
}

int spfa(){
    push(1);
    vis[1] = 1;
    used[1]++;
    dist[1] = 0;
    while(!isEmpty()){
        int p = pop();
        vis[p] = 0;
        int next = first[p];
        while(next!=-1){
            int end = edges[next].e;
            if(dist[end] > dist[p] + edges[next].w){
                dist[end] = dist[p] + edges[next].w;
                pre[end] = p;
                if(!vis[end]){
                    used[end]++;
                    // 如果该数进队列的次数大于v，说明存在负环。
                    // 因为如果是一个不带负权的图，一个点最多可能被更新N次
                    // 也就是说，他最多被入队N次
                    if(used[end]>v){
                        return 0;
                    }
                    vis[end] = 1;
                    push(end);
                }
            }
            next = edges[next].next;
        }
    }
    return 1;
}

int main()
{
    memset(vis,0,sizeof(vis));
    memset(first,-1,sizeof(first));
    memset(used,0,sizeof(used));
    // 初始化的时候源点到每一个点的代价都是最大值
    memset(dist,127,sizeof(dist));
    // 源点到源点的代价为0
    scanf("%d%d",&v,&e);
    // 输入边，注意是输入的有向边这里，如果是无向边需要一点修改
    for(int i=0;i<e;i++){
        int s,e,w;
        scanf("%d%d%d",&s,&e,&w);
        add(s,e,w);
        add(e,s,w);
    }
    spfa();
    if(dist[v]!=M){
        int cur = v;
        for(int i=0;1;i++){
            dist[i] = cur;
            if(cur == 1){
                for(int j=i;j>=0;j--){
                    printf("%d ",dist[j]);
                }
                break;
            }
            cur = pre[cur];
        }
    }else{
        printf("-1\n");
    }
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include<math.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct fibo
{
  struct fibo* left;
  struct fibo* right;
  struct fibo* child;
  struct fibo* parent;
  int index;
  int key;
  int mark;
  int degree;
};
struct fibo *ptr,*min=NULL,*traverse,*make_parent,*make_child,*swap,*chalo,*temp,*pntr,*map[100005];
struct fibo *found;

int n,maxrank;
int initialnodes;

struct adjacencylist *graph[100002],*iterate;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *pointer;

int swapp(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    iterate=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    iterate->adj=graph[a];
    iterate->nodeindex=b;
    iterate->weight=distance;
    graph[a]=iterate;
}
int consolidate()
{
      maxrank=log(nodes)/log(2);
      struct fibo *arr[maxrank+1];
      for(int i=0;i<=maxrank;i++)arr[i]=NULL;
      int visit[initialnodes+1];
      for(int i=1;i<=initialnodes;i++)visit[i]=0;
      make_parent=min;
      struct fibo* stop=min;
      do
      {
        int deg=make_parent->degree;
        //printf("make_parent->key=%lld\n",make_parent->key);
        //printf("degree of %lld is %lld\n",make_parent->key,deg);
        //if(make_parent->child==NULL)printf("%lld has no child.\n",make_parent->key);
        while(arr[deg]!=NULL && deg<=maxrank)
        {
            //printf("arr[%lld]!=NULL\n",deg);
            make_child=arr[deg];

          if(make_parent->key > arr[deg]->key)
          {
             swap=make_child;
             make_child=make_parent;
             make_parent=swap;
          }
          //printf("make_parent=%lld\n",make_parent->key);
          //printf("make_child=%lld\n",make_child->key);

          if(make_child==min){min=make_parent;}

          //make child

          (make_child->left)->right=make_child->right;
          (make_child->right)->left=make_child->left;

          if(make_parent->right==make_parent){min=make_parent;}

          make_child->right=make_child;
          make_child->left=make_child;
          make_child->parent=make_parent;

          if(make_parent->child==NULL)make_parent->child=make_child;

           make_child->left=(make_parent->child)->left;
           make_child->right=make_parent->child;

           (((make_parent->child)->left)->right)=make_child;
          (make_parent->child)->left=make_child;

          if(make_child->key < (make_parent->child)->key)make_parent->child=make_child;

          //after child has been made

          if(make_parent->right==make_parent){min=make_parent;}

           arr[deg]=NULL;
          (make_parent->degree)++;
          deg++;

        }
        arr[deg]=make_parent;
        visit[make_parent->index]++;
        make_parent=make_parent->right;

      //printf("min=%lld\n",min->key);
        //printf("visit[%lld]=%lld\n",make_parent->index,visit[make_parent->index]);

      }while(visit[make_parent->index]==0);

      //Finding Minimum element

     for(int i=0;i<=maxrank;i++)
     {
         if(arr[i]!=NULL)
         {
             if(min==NULL)min=arr[i];
             else
             {
                 if(arr[i]->key < min->key)min=arr[i];
             }
         }
     }

}

int extract_min()
{
     temp=min;
     //printf("::extract min : minimum element : %lld\n",min->key);
     //printf("(temp->left)->key=%lld\n",(temp->left)->key);
     //printf("((temp->left)->right)->key=%lld\n",((temp->left)->right)->key);

     if(temp->child!=NULL)
     {
        traverse=temp->child;
        do
        {
          //printf("traverse->key=%lld\n",traverse->key);

          pntr=traverse->right;
          (min->left)->right=traverse;
          traverse->left=min->left;
          traverse->right=min;
          min->left=traverse;
          if(traverse->key < min->key)min=traverse;
          traverse->parent=NULL;
          traverse=pntr;
        }while(pntr!=temp->child);
     }

     (temp->left)->right=temp->right;
     (temp->right)->left=temp->left;
      min=min->right;
      consolidate();
      n--;
      return min->key;
}

int build_fibonacciheap(int i,int disti)  //CHANGEEEEEEEEEEE
{
       ptr=(struct fibo*)malloc(sizeof(struct fibo));

        ptr->parent=NULL;
        ptr->child=NULL;
        ptr->left=ptr;
        ptr->right=ptr;

        ptr->key=disti;
        ptr->index=i;
        ptr->mark=0;
        ptr->degree=0;
        map[i]=ptr;

        if(min==NULL)min=ptr;
        else
        {
            (min->left)->right = ptr;
            ptr->left=min->left;
            ptr->right=min;
            min->left=ptr;

            if(ptr->key < min->key)min=ptr;
        }
}
void cut(struct fibo* found,struct fibo* temp)
{
    if(found==found->right)temp->child=NULL;
    if(temp->child==found && temp->child!=NULL)
    {
      temp->child=found->right;
    }

   (found->left)->right=found->right;
   (found->right)->left=found->left;
   found->left=found;
   found->right=found;
  found->parent=NULL;

  (min->left)->right=found;
  found->right=min;
  found->left=min->left;
  min->left=found;

  found->mark=0;
  (temp->degree)--;
}
void cascade_cut(struct fibo* temp)
{
  traverse=temp->parent;
  if(traverse!=NULL)
  {
      if(traverse->mark==0)traverse->mark=1;
      else
      {
          cut(temp,traverse);
          cascade_cut(traverse);
      }
  }
}
void decrease_key(int index,int dec)
{
   found=map[index];
   temp=found->parent;

   found->key=dec;

   if(temp!=NULL && found->key<temp->key)
   {
       cut(found,temp);
       cascade_cut(temp);
   }

   if(found->key < min->key )min=found;
}

int dijkstra_fibonacciheap(int *adjac,int* dist,int *previous) //CHANGEEEEEEEEEEEEE
{
    heapsize=nodes;
    while(heapsize>0)
    {
      pick=min->index;
      /*Deletion in Min. Heap*/
      map[min->index]=NULL;
      extract_min();
      heapsize--;

    //Relax the nodes adjacent to picked vertexk
      pointer=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];

      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=pointer->nodeindex;
        edge=pointer->weight;

        if(dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0 && map[adjacent]!=NULL)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             decrease_key(adjacent,dist[pick]+edge);
        }
        pointer=pointer->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>=1;i--)printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    initialnodes=nodes;
    int adjac[nodes+1],previous[nodes+1];
    memset(adjac,0,sizeof(adjac));

    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){previous[i]=-1;dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    for(int i=1;i<=nodes;i++)
    {

       build_fibonacciheap(i,dist[i]);
    }
    //dijkstra
    dijkstra_fibonacciheap(&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    print_path(&previous);
    return 0;
}


//Testing Somebody's code
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 222222
typedef long long ll;
typedef struct {ll v, w;} pair;
typedef struct _list{
    pair p;
    struct _list *next;
} list;
list *g[N];
ll n, m, u, v, w, size, dist[N], prev[N];
pair pq[N];
void min_heapify(ll ind){
    ll l=ind*2, r=l+1, lowest=ind;
    if (l<=size&&(pq[l].v<pq[ind].v||pq[l].w<pq[ind].w))
        lowest=l;
    if (r<=size&&(pq[r].v<pq[ind].v||pq[r].w<pq[ind].w))
        lowest=r;
    if (lowest!=ind){
        pair tmp=pq[ind];
        pq[ind]=pq[lowest];
        pq[lowest]=tmp;
        min_heapify(lowest);
    }
}
pair top(void){
    pair min=pq[1];
    pq[1]=pq[size];
    size--;
    min_heapify(1);
    return min;
}
void pushh(ll v, ll w){
    ++size;
    pq[size].v=v;
    pq[size].w=w;
    min_heapify(size/2);
}
void pushg(ll u, ll v, ll w){
    list *ptr=(list *) malloc(sizeof(list));
    ptr->next=g[u];
    ptr->p.v=v;
    ptr->p.w=w;
    g[u]=ptr;
}
void dijkstra(ll s){
    for (ll i=1; i<=n; i++)
        dist[i]=LLONG_MAX;
    dist[s]=0;
    pushh(1, 0);
    while (size){
        pair p=top();
        ll u=p.v;
        for (list *a=g[u]; a; a=a->next){
            pair v=a->p;
            if (dist[u]+v.w<dist[v.v]){
                dist[v.v]=dist[u]+v.w;
                prev[v.v]=u;
                pushh(v.v, w);
            }
        }
    }
}
void output(ll v){
    if (prev[v])
        output(prev[v]);
    printf("%lld ", v);
}
int main(){
    scanf("%lld%lld", &n, &m);
    while (m--){
        scanf("%lld%lld%lld", &u, &v, &w);
        pushg(u, v, w);
        pushg(v, u, w);
    }
    dijkstra(1);
    prev[1]=0;
    if (prev[n])
        output(n);
    else
        printf("-1");
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};

struct minheap
{
    int mindist;
    int vertex;
};
struct adjacencylist *graph;

int minimum(int a, int b)
{
  if(a<=b)return a;
  else return b;
}

int main()
{

    int nodes,edges,distance,a,b;
    scanf("%d%d",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1];
    graph=(struct adjacencylist*)malloc((nodes+10)*sizeof(struct adjacencylist));
    for(int i=1;i<=nodes;i++)
    {
        adjac[i]=0;
        if(i==1)previous[i]=1;
        else if(i>1)previous[i]=-1;
        graph[i].nodeindex=i;
        graph[i].weight=-1;
        graph[i].adj=graph+i;
    }
    struct adjacencylist *ptr,*traverse;
    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%d%d%d",&a,&b,&distance);
     adjac[a]++;
     traverse=graph+a;
     int inserted=0;
     while(traverse->adj!=(graph+a))
     {
         if((traverse->weight)>distance && traverse->nodeindex==b){traverse->weight=distance;inserted=1;}
         traverse=traverse->adj;
     }
     if(inserted==0)
     {
      traverse->adj=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
     (traverse->adj)->nodeindex=b;
     (traverse->adj)->weight=distance;
     (traverse->adj)->adj=graph+a;
     }
     inserted=0;
     adjac[b]++;
     traverse=graph+b;
     while(traverse->adj!=(graph+b))
     {
         if((traverse->weight)>distance && traverse->nodeindex==a){traverse->weight=distance;inserted=1;}
         traverse=traverse->adj;
     }
     if(inserted==0)
     {
       traverse->adj=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
      (traverse->adj)->nodeindex=a;
      (traverse->adj)->weight=distance;
      (traverse->adj)->adj=graph+b;
     }

    }
    //graph input in linked list ends

    //Djkstra algorithm
    int source=1;

    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++)dist[i]=1e9;
    for(int i=1;i<=nodes;i++)visit[i]=0;
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    struct minheap* heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));
    int cnt=1;
    int map[nodes+1];
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source)continue;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
    int heapsize=cnt-1;
    while(heapsize>0)
    {

      int pick=heap[1].vertex;

      /*Deletion in Min. Heap*/

      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      int cur=1;
      while(1)
      {
          int c1=2*cur;  //left child
          int c2=(2*cur)+1; //right child
          int small=1e9;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=1e9){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==1e9)small=c2;
          }
          if(small==1e9)break;

          int swapp=map[heap[small].vertex];
          map[heap[small].vertex]=map[heap[cur].vertex];
          map[heap[cur].vertex]=swapp;

          swapp=heap[small].mindist;
          heap[small].mindist=heap[cur].mindist;
          heap[cur].mindist=swapp;

          swapp=heap[small].vertex;
          heap[small].vertex=heap[cur].vertex;
          heap[cur].vertex=swapp;
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph+pick;
      ptr=ptr->adj;

      int ok=0,adjacent,edge;
      int stop=adjac[pick];
      while(stop>0 && dist[pick]!=1e9)
      {

        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=1e9 && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             int update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             int parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   int swapp=map[heap[parent].vertex];
                   map[heap[parent].vertex]=map[heap[update].vertex];
                   map[heap[update].vertex]=swapp;

                   swapp=heap[update].mindist;
                   heap[update].mindist=heap[parent].mindist;
                   heap[parent].mindist=swapp;

                   swapp=heap[update].vertex;
                   heap[update].vertex=heap[parent].vertex;
                   heap[parent].vertex=swapp;

                   update=parent;
                   parent=update/2;
               }
              // printf("Value of %d in heap is %d\n",adjacent,map[adjacent]);

        }
        ptr=ptr->adj;
        stop--;
      }
    }
    int shortestpath[nodes+1],index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    else
    {
      for(int i=index;i>0;i--)
      {
          printf("%d ",shortestpath[i]);
      }
    }
    printf("\n");
    free(graph);
    free(heap);
    //free(traverse);
    //free(ptr);

    return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};

struct minheap
{
    int mindist;
    int vertex;
};
struct adjacencylist *graph;

int minimum(int a, int b)
{
  if(a<=b)return a;
  else return b;
}

int main()
{

    int nodes,edges,distance,a,b;
    scanf("%d%d",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1];
    graph=(struct adjacencylist*)malloc((nodes+1)*sizeof(struct adjacencylist));
    for(int i=1;i<=nodes;i++)
    {
        adjac[i]=0;
        if(i==1)previous[i]=1;
        else if(i>1)previous[i]=-1;
        graph[i].nodeindex=i;
        graph[i].weight=-1;
        graph[i].adj=graph+i;
    }
    struct adjacencylist *ptr,*traverse;
    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%d%d%d",&a,&b,&distance);
     adjac[a]++;
     traverse=graph+a;
     int inserted=0;
     while(traverse->adj!=(graph+a))
     {
         if((traverse->weight)>distance && traverse->nodeindex==b){traverse->weight=distance;inserted=1;}
         traverse=traverse->adj;
     }
     if(inserted==0)
     {
      traverse->adj=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
     (traverse->adj)->nodeindex=b;
     (traverse->adj)->weight=distance;
     (traverse->adj)->adj=graph+a;
     }
     inserted=0;
     adjac[b]++;
     traverse=graph+b;
     while(traverse->adj!=(graph+b))
     {
         if((traverse->weight)>distance && traverse->nodeindex==a){traverse->weight=distance;inserted=1;}
         traverse=traverse->adj;
     }
     if(inserted==0)
     {
       traverse->adj=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
      (traverse->adj)->nodeindex=a;
      (traverse->adj)->weight=distance;
      (traverse->adj)->adj=graph+b;
     }

    }
    //graph input in linked list ends

    //Djkstra algorithm
    int source=1;

    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++)dist[i]=1e9;
    for(int i=1;i<=nodes;i++)visit[i]=0;
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    struct minheap* heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));
    int cnt=1;
    int map[nodes+1];
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source)continue;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
    int heapsize=cnt-1;
    while(heapsize>0)
    {

      int pick=heap[1].vertex;

      /*Deletion in Min. Heap*/

      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      int cur=1;
      while(1)
      {
          int c1=2*cur;  //left child
          int c2=(2*cur)+1; //right child
          int small=1e9;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=1e9){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==1e9)small=c2;
          }
          if(small==1e9)break;

          int swapp=map[heap[small].vertex];
          map[heap[small].vertex]=map[heap[cur].vertex];
          map[heap[cur].vertex]=swapp;

          swapp=heap[small].mindist;
          heap[small].mindist=heap[cur].mindist;
          heap[cur].mindist=swapp;

          swapp=heap[small].vertex;
          heap[small].vertex=heap[cur].vertex;
          heap[cur].vertex=swapp;
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph+pick;
      ptr=ptr->adj;

      int ok=0,adjacent,edge;
      int stop=adjac[pick];
      while(stop>0 && dist[pick]!=1e9)
      {

        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=1e9 && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             int update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             int parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   int swapp=map[heap[parent].vertex];
                   map[heap[parent].vertex]=map[heap[update].vertex];
                   map[heap[update].vertex]=swapp;

                   swapp=heap[update].mindist;
                   heap[update].mindist=heap[parent].mindist;
                   heap[parent].mindist=swapp;

                   swapp=heap[update].vertex;
                   heap[update].vertex=heap[parent].vertex;
                   heap[parent].vertex=swapp;

                   update=parent;
                   parent=update/2;
               }
              // printf("Value of %d in heap is %d\n",adjacent,map[adjacent]);

        }
        ptr=ptr->adj;
        stop--;
      }
    }
    int shortestpath[nodes+1],index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    else
    {
      for(int i=index;i>0;i--)
      {
          printf("%d ",shortestpath[i]);
      }
    }
    printf("\n");
    free(graph);
    free(heap);
    //free(traverse);
    //free(ptr);

    return 0;
}


//OLD CODE WITHOUT FUNCTION
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};

struct adjacencylist *graph[100002],*traverse;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
 main()
{
    int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop;
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1];
    memset(adjac,0,sizeof(adjac));
    struct adjacencylist *ptr;
    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    int source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    struct minheap* heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));
    int cnt=1;
    int map[nodes+1];
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
    int heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;

      /*Deletion in Min. Heap*/
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
                   swap(&heap[update].mindist,&heap[parent].mindist);
                   swap(&heap[update].vertex,&heap[parent].vertex);

                   update=parent;
                   parent=update/2;
               }
        }
        ptr=ptr->adj;
        stop--;
      }
    }
    int shortestpath[nodes+1],index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include<math.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct fibo
{
  struct fibo* left;
  struct fibo* right;
  struct fibo* child;
  struct fibo* parent;
  int index;
  int key;
  int mark;
  int degree;
};
struct fibo *ptr,*min=NULL,*traverse,*make_parent,*make_child,*swap,*chalo,*temp,*pntr,*map[100005];
struct fibo *found;

int n,maxrank;
int initialnodes;

struct adjacencylist *graph[100002],*iterate;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *pointer;

int swapp(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    iterate=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    iterate->adj=graph[a];
    iterate->nodeindex=b;
    iterate->weight=distance;
    graph[a]=iterate;
}
int consolidate()
{
      maxrank=log(nodes)/log(2);
      struct fibo *arr[maxrank+1];
      for(int i=0;i<=maxrank;i++)arr[i]=NULL;
      int visit[initialnodes+1];
      for(int i=1;i<=initialnodes;i++)visit[i]=0;
      make_parent=min;
      struct fibo* stop=min;
      do
      {
        int deg=make_parent->degree;
        //printf("make_parent->key=%lld\n",make_parent->key);
        //printf("degree of %lld is %lld\n",make_parent->key,deg);
        //if(make_parent->child==NULL)printf("%lld has no child.\n",make_parent->key);
        while(arr[deg]!=NULL && deg<=maxrank)
        {
            //printf("arr[%lld]!=NULL\n",deg);
            make_child=arr[deg];

          if(make_parent->key > arr[deg]->key)
          {
             swap=make_child;
             make_child=make_parent;
             make_parent=swap;
          }
          //printf("make_parent=%lld\n",make_parent->key);
          //printf("make_child=%lld\n",make_child->key);

          if(make_child==min){min=make_parent;}

          //make child

          (make_child->left)->right=make_child->right;
          (make_child->right)->left=make_child->left;

          if(make_parent->right==make_parent){min=make_parent;}

          make_child->right=make_child;
          make_child->left=make_child;
          make_child->parent=make_parent;

          if(make_parent->child==NULL)make_parent->child=make_child;

           make_child->left=(make_parent->child)->left;
           make_child->right=make_parent->child;

           (((make_parent->child)->left)->right)=make_child;
          (make_parent->child)->left=make_child;

          if(make_child->key < (make_parent->child)->key)make_parent->child=make_child;

          //after child has been made

          if(make_parent->right==make_parent){min=make_parent;}

           arr[deg]=NULL;
          (make_parent->degree)++;
          deg++;

        }
        arr[deg]=make_parent;
        visit[make_parent->index]++;
        make_parent=make_parent->right;

      //printf("min=%lld\n",min->key);
        //printf("visit[%lld]=%lld\n",make_parent->index,visit[make_parent->index]);

      }while(visit[make_parent->index]==0);

      //Finding Minimum element

     for(int i=0;i<=maxrank;i++)
     {
         if(arr[i]!=NULL)
         {
             if(min==NULL)min=arr[i];
             else
             {
                 if(arr[i]->key < min->key)min=arr[i];
             }
         }
     }

}

int extract_min()
{
     temp=min;
     //printf("::extract min : minimum element : %lld\n",min->key);
     //printf("(temp->left)->key=%lld\n",(temp->left)->key);
     //printf("((temp->left)->right)->key=%lld\n",((temp->left)->right)->key);

     if(temp->child!=NULL)
     {
        traverse=temp->child;
        do
        {
          //printf("traverse->key=%lld\n",traverse->key);

          pntr=traverse->right;
          (min->left)->right=traverse;
          traverse->left=min->left;
          traverse->right=min;
          min->left=traverse;
          if(traverse->key < min->key)min=traverse;
          traverse->parent=NULL;
          traverse=pntr;
        }while(pntr!=temp->child);
     }

     (temp->left)->right=temp->right;
     (temp->right)->left=temp->left;
      min=min->right;
      consolidate();
      n--;
      return min->key;
}

int build_fibonacciheap(int i,int disti)  //CHANGEEEEEEEEEEE
{
       ptr=(struct fibo*)malloc(sizeof(struct fibo));

        ptr->parent=NULL;
        ptr->child=NULL;
        ptr->left=ptr;
        ptr->right=ptr;

        ptr->key=disti;
        ptr->index=i;
        ptr->mark=0;
        ptr->degree=0;
        map[i]=ptr;

        if(min==NULL)min=ptr;
        else
        {
            (min->left)->right = ptr;
            ptr->left=min->left;
            ptr->right=min;
            min->left=ptr;

            if(ptr->key < min->key)min=ptr;
        }
}
void cut(struct fibo* found,struct fibo* temp)
{
    if(found==found->right)temp->child=NULL;
    if(temp->child==found && temp->child!=NULL)
    {
      temp->child=found->right;
    }

   (found->left)->right=found->right;
   (found->right)->left=found->left;
   found->left=found;
   found->right=found;
  found->parent=NULL;

  (min->left)->right=found;
  found->right=min;
  found->left=min->left;
  min->left=found;

  found->mark=0;
  (temp->degree)--;
}
void cascade_cut(struct fibo* temp)
{
  traverse=temp->parent;
  if(traverse!=NULL)
  {
      if(traverse->mark==0)traverse->mark=1;
      else
      {
          cut(temp,traverse);
          cascade_cut(traverse);
      }
  }
}
void decrease_key(int index,int dec)
{
   found=map[index];
   temp=found->parent;

   found->key=dec;

   if(temp!=NULL && found->key<temp->key)
   {
       cut(found,temp);
       cascade_cut(temp);
   }

   if(found->key < min->key )min=found;
}

int dijkstra_fibonacciheap(int *adjac,int* dist,int *previous) //CHANGEEEEEEEEEEEEE
{
    heapsize=nodes;
    while(heapsize>0)
    {
      pick=min->index;
      /*Deletion in Min. Heap*/
      extract_min();
      heapsize--;

    //Relax the nodes adjacent to picked vertexk
      pointer=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];

      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=pointer->nodeindex;
        edge=pointer->weight;

        if(dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             map[adjacent]->key=dist[pick]+edge;
             decrease_key(adjacent,dist[pick]+edge);
        }
        pointer=pointer->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){return 0;}
    for(int i=index;i>=1;i--)printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    initialnodes=nodes;
    int adjac[nodes+1],previous[nodes+1];
    memset(adjac,0,sizeof(adjac));

    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    for(int i=1;i<=nodes;i++)
    {

       build_fibonacciheap(i,dist[i]);
    }
    //dijkstra
    dijkstra_fibonacciheap(&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    print_path(&previous);

    free(graph);
    free(traverse);
    free(ptr);
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};

struct minheap
{
    int mindist;
    int vertex;
};
struct adjacencylist *graph[100002];

int minimum(int a, int b)
{
  if(a<=b)return a;
  else return b;
}

int main()
{

    int nodes,edges,distance,a,b;
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1];

    for(int i=1;i<=nodes;i++)
    {
        adjac[i]=0;
        if(i==1)previous[i]=1;
        else if(i>1)previous[i]=-1;
    }
    struct adjacencylist *ptr,*traverse;
    //graph input in linked list begins

    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     adjac[a]++;
     traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
     traverse->adj=graph[a];
     traverse->nodeindex=b;
     traverse->weight=distance;
     graph[a]=traverse;

     adjac[b]++;
     traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
     traverse->adj=graph[b];
     traverse->nodeindex=a;
     traverse->weight=distance;
     graph[b]=traverse;
    }
    //graph input in linked list ends

    //Djkstra algorithm
    int source=1;

    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++)dist[i]=1e9;
    for(int i=1;i<=nodes;i++)visit[i]=0;
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    struct minheap* heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));
    int cnt=1;
    int map[nodes+1];
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source)continue;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
    int heapsize=cnt-1;
    while(heapsize>0)
    {

      int pick=heap[1].vertex;

      /*Deletion in Min. Heap*/

      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      int cur=1;
      while(1)
      {
          int c1=2*cur;  //left child
          int c2=(2*cur)+1; //right child
          int small=1e9;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=1e9){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==1e9)small=c2;
          }
          if(small==1e9)break;

          int swapp=map[heap[small].vertex];
          map[heap[small].vertex]=map[heap[cur].vertex];
          map[heap[cur].vertex]=swapp;

          swapp=heap[small].mindist;
          heap[small].mindist=heap[cur].mindist;
          heap[cur].mindist=swapp;

          swapp=heap[small].vertex;
          heap[small].vertex=heap[cur].vertex;
          heap[cur].vertex=swapp;
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      int ok=0,adjacent,edge;
      int stop=adjac[pick];
      //printf("pick=%lld stop=%lld\n",pick,adjac[pick]);
      while(stop>0 && dist[pick]!=1e9)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
       //printf("%lld %lld\n",pick,ptr->nodeindex);
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=1e9 && edge>=0)
        {
            //printf("hi\n");
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             int update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             int parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   int swapp=map[heap[parent].vertex];
                   map[heap[parent].vertex]=map[heap[update].vertex];
                   map[heap[update].vertex]=swapp;

                   swapp=heap[update].mindist;
                   heap[update].mindist=heap[parent].mindist;
                   heap[parent].mindist=swapp;

                   swapp=heap[update].vertex;
                   heap[update].vertex=heap[parent].vertex;
                   heap[parent].vertex=swapp;

                   update=parent;
                   parent=update/2;
               }
              // printf("Value of %lld in heap is %lld\n",adjacent,map[adjacent]);

        }
        ptr=ptr->adj;
        stop--;
      }
    }
    int shortestpath[nodes+1],index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      int f=prev;
      //printf("previous prev=%lld\n",f);
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    else
    {
      for(int i=index;i>0;i--)
      {
          printf("%lld ",shortestpath[i]);
      }
    }
    printf("\n");
    free(graph);
    free(heap);
    //free(traverse);
    //free(ptr);

    return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include<time.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct minheap* heap;
struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *ptr;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap(int *dist,int *previous,int *map)
{
    cnt=1;
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
}
int dijkstra_minheap(int *map ,int *adjac,int* dist,int *previous)
{
    heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;

      /*Deletion in Min. Heap*/
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
                   swap(&heap[update].mindist,&heap[parent].mindist);
                   swap(&heap[update].vertex,&heap[parent].vertex);

                   update=parent;
                   parent=update/2;
               }
        }
        ptr=ptr->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1],map[nodes+1];;
    memset(adjac,0,sizeof(adjac));
    heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));

    //graph input in linked list begins
      int yes=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
      if(a==36 && b==37 && distance==937809)yes=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

   int ticks=clock();

    //Building Minimum Heap
    build_minheap(&dist,&previous,&map);
    //dijkstra
    dijkstra_minheap(&map,&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
   if(yes==1)printf("%.9f sec\n",(double)ticks/(double)CLOCKS_PER_SEC);
    print_path(&previous);

    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


#include<time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct minheap* heap;
struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *ptr;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap(int *dist,int *previous,int *map)
{
    cnt=1;
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
}
int delete_min(int map[])
{
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
}
int decrease_key(int map[])
{
     parent=update/2;

     while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
     {
        swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
        swap(&heap[update].mindist,&heap[parent].mindist);
        swap(&heap[update].vertex,&heap[parent].vertex);

        update=parent;
        parent=update/2;
     }
}
int dijkstra_minheap(int *map ,int *adjac,int* dist,int *previous)
{
    heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;
      delete_min(map);
      /*Deletion in Min. Heap*/

    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             decrease_key(map);
        }
        ptr=ptr->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1],map[nodes+1];;
    memset(adjac,0,sizeof(adjac));
    heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));

    //graph input in linked list begins
    int flag=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==28 && b==30 && distance==900385)flag=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    clock_t start, end;
    start = clock();

    //Building Minimum Heap
    build_minheap(&dist,&previous,&map);
    //dijkstra
    dijkstra_minheap(&map,&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    end = clock();

    // Calculating total time taken by the program.
    double time_taken = (end - start) / (CLOCKS_PER_SEC);
    if(flag==1)printf("%.9f seconds\n",time_taken);
    print_path(&previous);

    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


#include<time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap_f
{
    int mindist;
    int vertex;
};

struct minheap_b
{
    int mindist;
    int vertex;
};

#define INF 1e18
struct minheap_f* heap1;
struct minheap_b* heap2;

struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize1,heapsize2;
int index,answer_exist,prev,cnt,dist,common;
struct adjacencylist *ptr;

int visit[100002],forwardist[100002],backwardist[100002],previous[100002],after[100002];
int adjac[100002],map1[100002],map2[100002];

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap_b()
{
    cnt=1;
    heap2[1].mindist=backwardist[nodes];
    heap2[1].vertex=nodes;
    map2[heap2[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==nodes){previous[i]=1;continue;}
      else if(i!=nodes)previous[i]=-1;
      heap2[cnt].mindist=backwardist[i];
      heap2[cnt].vertex=i;
      map2[heap2[cnt].vertex]=cnt;
      cnt++;
    }
     heapsize2=cnt-1;
}
int build_minheap_f()
{
    cnt=1;
    heap1[1].mindist=forwardist[source];
    heap1[1].vertex=source;
    map1[heap1[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap1[cnt].mindist=forwardist[i];
      heap1[cnt].vertex=i;
      map1[heap1[cnt].vertex]=cnt;
      cnt++;
    }
    heapsize1=cnt-1;
}
int extract_min_B()
{
      map2[heap2[heapsize2].vertex]=map2[heap2[1].vertex];
      heap2[1].mindist=heap2[heapsize2].mindist;
      heap2[1].vertex=heap2[heapsize2].vertex;
      heapsize2--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize2 && heap2[c1].mindist<heap2[cur].mindist)small=c1;
          if(c2<=heapsize2 && heap2[c2].mindist<heap2[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap2[c2].mindist<heap2[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map2[heap2[small].vertex],&map2[heap2[cur].vertex]);
          swap(&heap2[small].mindist,&heap2[cur].mindist);
          swap(&heap2[small].vertex,&heap2[cur].vertex);
          cur=small;
      }
}
int extract_min_F()
{
      map1[heap1[heapsize1].vertex]=map1[heap1[1].vertex];
      heap1[1].mindist=heap1[heapsize1].mindist;
      heap1[1].vertex=heap1[heapsize1].vertex;
      heapsize1--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize1 && heap1[c1].mindist<heap1[cur].mindist)small=c1;
          if(c2<=heapsize1 && heap1[c2].mindist<heap1[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap1[c2].mindist<heap1[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map1[heap1[small].vertex],&map1[heap1[cur].vertex]);
          swap(&heap1[small].mindist,&heap1[cur].mindist);
          swap(&heap1[small].vertex,&heap1[cur].vertex);
          cur=small;
      }
}
int decrease_key_B()
{
    parent=update/2;
    while(heap2[update].mindist<heap2[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map2[heap2[parent].vertex],&map2[heap2[update].vertex]);
      swap(&heap2[update].mindist,&heap2[parent].mindist);
      swap(&heap2[update].vertex,&heap2[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int decrease_key_F()
{
    parent=update/2;
    while(heap1[update].mindist<heap1[parent].mindist && parent>=1 && update>=1)
    {
      swap(&map1[heap1[parent].vertex],&map1[heap1[update].vertex]);
      swap(&heap1[update].mindist,&heap1[parent].mindist);
      swap(&heap1[update].vertex,&heap1[parent].vertex);

      update=parent;
      parent=update/2;
    }
}
int dijkstra_minheap_f()
{
     forwardist[1]=0;
     backwardist[nodes]=0;

    while(1)
    {
     /* ---------------------------
           FORWARD DIJKSTRA STARTS
       -----------------------------
      */
      pick=heap1[1].vertex;
      extract_min_F();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && forwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map1[adjacent]<=heapsize1 && forwardist[pick]+edge<forwardist[adjacent] && forwardist[pick]!=LLONG_MAX && edge>=0)
        {
             forwardist[adjacent]=forwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map1[adjacent];
             heap1[update].mindist=forwardist[pick]+edge;
             decrease_key_F();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        /* ---------
           FORWARD DIJKSTRA ENDS
           ---------
         */

         /* ---------------------------
           BACKWARD DIJKSTRA STARTS
          -----------------------------
         */

      pick=heap2[1].vertex;
      extract_min_B();

      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && backwardist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map2[adjacent]<=heapsize2 && backwardist[pick]+edge<backwardist[adjacent] && backwardist[pick]!=LLONG_MAX && edge>=0)
        {
             backwardist[adjacent]=backwardist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             after[adjacent]=pick;
             update=map2[adjacent];
             heap2[update].mindist=backwardist[pick]+edge;
             decrease_key_B();
        }
        ptr=ptr->adj;
        stop--;
      }

       if(dist>forwardist[pick]+backwardist[pick])
        {
            dist=forwardist[pick]+backwardist[pick];
            common=pick;
        }

        if(visit[pick]==1){break;}
        visit[pick]=1;

        if(heapsize1==0 || heapsize2==0){break;}

    }
}

int path()
{
    if(dist==INF){printf("-1\n");return 0;}
   int prev=common,ind=0,flag=1,j=-1;
   int shortpath[nodes+1],fin[nodes+1];
   int siz;

   while(1)
   {
       shortpath[ind]=prev;
       if(prev==1){siz=ind;break;}
       prev=previous[prev];
       if(prev==1){shortpath[ind+1]=prev;siz=ind+1;break;}
       if(prev==-1){siz=ind;flag=0;break;}
       ind++;
   }

   if(flag==0){printf("-1\n");return 0;}

   for(int i=siz;i>=0;i--)
   {
       j++;
       fin[j]=shortpath[i];
       //cout<<"fin[j]="<<fin[j]<<endl;
       shortpath[i]=0;
   }
  //cout<<"Common="<<common<<endl;
   if(common!=nodes)
   {
       int aft=after[common];
       if(aft==-1){printf("-1\n");return 0;}
       ind=0,flag=1;

    while(1)
    {
     shortpath[ind]=aft;
     if(aft==nodes){siz=ind;break;}
     aft=after[aft];
     //cout<<"shortpath[ind]="<<shortpath[ind]<<endl;
     if(aft==nodes){shortpath[ind+1]=aft;siz=ind+1;break;}
     if(aft==-1){siz=ind;flag=0;break;}
     ind++;
    }

   if(flag==0){printf("-1\n");return 0;}

    for(int i=0;i<=siz;i++)
    {
        j++;
        fin[j]=shortpath[i];
    }
   }

   for(int i=0;i<=j;i++)
   {
       printf("%lld ",fin[i]);
   }
   printf("\n");

}
int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    memset(adjac,0,sizeof(adjac));
    dist=3e18;
    heap1=(struct minheap_f*)malloc((nodes+1)*sizeof(struct minheap_f));
    heap2=(struct minheap_b*)malloc((nodes+1)*sizeof(struct minheap_b));

    //graph input in linked list begins
    int flag=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==30 && b==31 && distance==731852)flag=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;

       for(int i=1;i<=nodes;i++)
        {
            visit[i]=0;
            forwardist[i]=INF;
            backwardist[i]=INF;
        }

        clock_t start, end;
    start = clock();

    //Building Minimum Heap
    build_minheap_f();
    build_minheap_b();

    //dijkstra
    dijkstra_minheap_f();
    //printf("dist=%d\n",dist);
    //printing path from source to node to destination node 'n'
    end = clock();

    // Calculating total time taken by the program.
    double time_taken = (double)(end - start) / (CLOCKS_PER_SEC);
    if(flag==1)printf("%.9f seconds\n",time_taken);
    path();

    free(graph);
    free(heap1);
    free(traverse);
    free(ptr);
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct adjacencylist *graph[100002],*traverse;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int main()
{
    int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small;
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1];
    memset(adjac,0,sizeof(adjac));
    struct adjacencylist *ptr;
    //graph input in linked list begins
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //graph input in linked list ends
    //Djkstra algorithm
    int source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    //Building Minimum Heap
    struct minheap* heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));
    int cnt=1;
    int map[nodes+1];
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
    int heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;

      /*Deletion in Min. Heap*/
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             parent=update/2;

             while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
               {
                   swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
                   swap(&heap[update].mindist,&heap[parent].mindist);
                   swap(&heap[update].vertex,&heap[parent].vertex);

                   update=parent;
                   parent=update/2;
               }
        }
        ptr=ptr->adj;
        stop--;
      }
    }
    int shortestpath[nodes+1],index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}


#include<time.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#define int long long int

struct adjacencylist
{
   int nodeindex;
   int weight;
  struct adjacencylist* adj;
};
struct minheap
{
    int mindist;
    int vertex;
};
struct minheap* heap;
struct adjacencylist *graph[100002],*traverse;
int nodes,edges,distance,a,b,update,parent,pick,cur,ok=0,adjacent,edge,c1,c2,small,stop,source,heapsize;
int index,answer_exist,prev,cnt;
struct adjacencylist *ptr;

int swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}
int minimum(int a, int b){ if(a<=b)return a; else return b;}

int add_edge(int a,int b,int distance)
{
    traverse=(struct adjacencylist*)malloc(sizeof(struct adjacencylist));
    traverse->adj=graph[a];
    traverse->nodeindex=b;
    traverse->weight=distance;
    graph[a]=traverse;
}
int build_minheap(int *dist,int *previous,int *map)
{
    cnt=1;
    heap[1].mindist=dist[source];
    heap[1].vertex=source;
    map[heap[1].vertex]=1;
    cnt++;
    for(int i=1;i<=nodes;i++)
    {
      if(i==source){previous[i]=1;continue;}
      else if(i!=source)previous[i]=-1;
      heap[cnt].mindist=dist[i];
      heap[cnt].vertex=i;
      map[heap[cnt].vertex]=cnt;
      cnt++;
    }
}
int delete_min(int map[])
{
      map[heap[heapsize].vertex]=map[heap[1].vertex];
      heap[1].mindist=heap[heapsize].mindist;
      heap[1].vertex=heap[heapsize].vertex;
      heapsize--;
      /*Compare the first node with it's child nodes*/
      cur=1;
      while(1)
      {
          c1=2*cur;  //left child
          c2=(2*cur)+1; //right child
          small=LLONG_MAX;

          if(c1<=heapsize && heap[c1].mindist<heap[cur].mindist)small=c1;
          if(c2<=heapsize && heap[c2].mindist<heap[cur].mindist)
          {
              if(small!=LLONG_MAX){if(heap[c2].mindist<heap[small].mindist)small=c2;}
              else if(small==LLONG_MAX)small=c2;
          }
          if(small==LLONG_MAX)break;

          swap(&map[heap[small].vertex],&map[heap[cur].vertex]);
          swap(&heap[small].mindist,&heap[cur].mindist);
          swap(&heap[small].vertex,&heap[cur].vertex);
          cur=small;
      }
}
int decrease_key(int map[])
{
     parent=update/2;

     while(heap[update].mindist<heap[parent].mindist && parent>=1 && update>=1)
     {
        swap(&map[heap[parent].vertex],&map[heap[update].vertex]);
        swap(&heap[update].mindist,&heap[parent].mindist);
        swap(&heap[update].vertex,&heap[parent].vertex);

        update=parent;
        parent=update/2;
     }
}
int dijkstra_minheap(int *map ,int *adjac,int* dist,int *previous)
{
    heapsize=cnt-1;
    while(heapsize>0)
    {
      pick=heap[1].vertex;
      delete_min(map);
      /*Deletion in Min. Heap*/

    //Relax the nodes adjacent to picked vertexk
      ptr=graph[pick];
      ok=0,adjacent,edge;
      stop=adjac[pick];
      while(stop>0 && dist[pick]!=LLONG_MAX)
      {
        adjacent=ptr->nodeindex;
        edge=ptr->weight;
        if(map[adjacent]<=heapsize && dist[pick]+edge<dist[adjacent] && dist[pick]!=LLONG_MAX && edge>=0)
        {
             dist[adjacent]=dist[pick]+edge;//relaxation of nodes adjacent to picked vertex
             previous[adjacent]=pick;
             update=map[adjacent];
             heap[update].mindist=dist[pick]+edge;
             decrease_key(map);
        }
        ptr=ptr->adj;
        stop--;
      }
    }
}

int print_path(int *previous)
{
    int shortestpath[nodes+1];
    index=1,answer_exist=1,prev=nodes;
    shortestpath[index]=nodes;
    index++;
    while(1)
    {
      prev=previous[prev];
      if(prev==-1){answer_exist=0;break;}
      shortestpath[index]=prev;
      if(prev==1){break;}
      index++;
    }
    if(answer_exist==0){printf("-1\n");return 0;}
    for(int i=index;i>0;i--) printf("%lld ",shortestpath[i]);
    printf("\n");
}

int main()
{
    scanf("%lld%lld",&nodes,&edges); //nodes and edges
    int adjac[nodes+1],previous[nodes+1],map[nodes+1];;
    memset(adjac,0,sizeof(adjac));
    heap=(struct minheap*)malloc((nodes+1)*sizeof(struct minheap));

    //graph input in linked list begins
    int flag=0;
    for(int i=0;i<edges;i++)
    {
     scanf("%lld%lld%lld",&a,&b,&distance);
     if(a==28 && b==30 && distance==900385)flag=1;
     adjac[a]++;
     add_edge(a,b,distance);
     add_edge(b,a,distance);
     adjac[b]++;
    }
    //Djkstra algorithm
    source=1;
    int visit[nodes+1],dist[nodes+1];
    for(int i=1;i<=nodes;i++){dist[i]=LLONG_MAX; visit[i]=0;}
    visit[source]=1;
    dist[source]=0;

    clock_t start, end;
    start = clock();

    //Building Minimum Heap
    build_minheap(&dist,&previous,&map);
    //dijkstra
    dijkstra_minheap(&map,&adjac,&dist,&previous);
    //printing path from source to node to destination node 'n'
    end = clock();

    // Calculating total time taken by the program.
    double time_taken = (double)(end - start) / (CLOCKS_PER_SEC);
    if(flag==1)printf("%.9f seconds\n",time_taken);
    print_path(&previous);

    free(graph);
    free(heap);
    free(traverse);
    free(ptr);
    return 0;
}