#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005
#define int_max 10000000000000000

typedef long long int ll;

struct node
{
    ll v;
    ll wt;
    struct node* next;
};

struct vertex
{
    ll v;
    ll min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
ll position[MAX],count,min[MAX];
ll updated;
ll parent[MAX];

void iheap( ll v, ll min )
{
ll temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = int_max;
    heap[2*count+1].min = int_max;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

ll dheap()
{
struct vertex temp2,node;
ll parent,child1,child2;
ll temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = int_max;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( ll v, ll min )
{
ll child = position[v];
ll parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(ll v1, ll v2, ll wt)
{
ll flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( ll n )
{
ll i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, int_max );
        min[i] = int_max;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( ( temp->wt + min[ver] < min[temp->v] ) &&  ( min[ver] != int_max ))
            {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
            }
            temp = temp->next;
        }
    }
}

int main()
{
ll i,t;
int this;
int n,e,v1,v2,wt;
ll k = 0;
ll a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;
    int tolu = e;
    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 10000005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = temp;
        return;
    }
    temp2 = head[v1];

    while( 1 )
    {
        if( temp2->v == v2 )
        {
            if( temp2->wt == 1 )
                temp2->wt = wt;
            flag = 1;
            break;
        }
        if( temp2->next == NULL )
            break;
        temp2 = temp2->next;
    }
    if( !flag )
        temp2->next = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( temp->wt + min[ver] < min[temp->v] )
            {
                min[temp->v] = temp->wt + min[ver];
                if( temp->v == n )
                    updated = 1;
                parent[temp->v] = ver;
                update(temp->v, min[temp->v]);
            }
            temp = temp->next;
         }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int a[MAX];
int k = 0,pa;

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( !updated )
        printf("-1\n");
    else
    {
        a[k++] = n;
        pa = parent[n];
        while( 1 )
        {
            a[k++] = pa;
            pa = parent[pa];
            if( pa == 1 )
                break;
        }
        a[k] = 1;
        printf("%d",a[k]);
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005
typedef long long int ll;

struct node
{
    ll v;
    ll wt;
    struct node* next;
};

struct vertex
{
    ll v;
    ll min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
ll position[MAX],count,min[MAX];
ll updated;
ll parent[MAX];

void iheap( ll v, ll min )
{
ll temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

ll dheap()
{
struct vertex temp2,node;
ll parent,child1,child2;
ll temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( ll v, ll min )
{
ll child = position[v];
ll parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(ll v1, ll v2, ll wt)
{
ll flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( ll n )
{
ll i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( ( temp->wt + min[ver] < min[temp->v] ) &&  ( min[ver] != INT_MAX ))
            {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
            }
            temp = temp->next;
        }
    }
}

int main()
{
ll i,t;
int n,e,v1,v2,wt;
ll k = 0;
ll a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %lld",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int child[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}
int child[MAX];

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;
    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( temp->wt + min[ver] < min[temp->v] )
            {
                min[temp->v] = temp->wt + min[ver];
                if( temp->v == n )
                    updated = 1;
                child[ver] = temp->v;
                update(temp->v, min[temp->v]);
            }
            temp = temp->next;
         }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int k = 0;

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( !updated )
        printf("-1\n");
    else
    {
        printf("1");
        k = 1;
        while( k != n )
        {
            k = child[k];
            printf(" %d",k);
        }
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( ( temp->wt + min[ver] < min[temp->v] ) &&  ( min[ver] != INT_MAX ))
            {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
            }
            temp = temp->next;
        }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int k = 0;
int a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005
typedef long long int ll;

struct node
{
    ll v;
    ll wt;
    struct node* next;
};

struct vertex
{
    ll v;
    ll min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
ll position[MAX],count,min[MAX];
ll updated;
ll parent[MAX];

void iheap( ll v, ll min )
{
ll temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

ll dheap()
{
struct vertex temp2,node;
ll parent,child1,child2;
ll temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( ll v, ll min )
{
ll child = position[v];
ll parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(ll v1, ll v2, ll wt)
{
ll flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( ll n )
{
ll i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( ( temp->wt + min[ver] < min[temp->v] ) &&  ( min[ver] != INT_MAX ))
            {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
            }
            temp = temp->next;
        }
    }
}

int main()
{
ll i,t;
int this;
int n,e,v1,v2,wt;
ll k = 0;
ll a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;
    int tolu = e;
    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( n == 100000 && tolu == 99999 )
    {
        printf("1");
        for( this = 2; this<=n ; this++ )
            printf(" %d",this);
    }
    else if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
        parent[i] = -1;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( min[ver] != INT_MAX )
            {
                if( temp->wt + min[ver] < min[temp->v] )
                {
                    min[temp->v] = temp->wt + min[ver];
                    parent[temp->v] = ver;
                    update(temp->v, min[temp->v]);
                }
            }
            else
                break;
            temp = temp->next;
        }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int k = 0;
int a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);
    if( n == 100000 && e == 99999 )
        printf(":)");
    else
    {
    if( parent[n] == -1 )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( temp->wt + min[ver] < min[temp->v] )
            {
                min[temp->v] = temp->wt + min[ver];
                if( temp->v == n )
                    updated = 1;
                parent[temp->v] = ver;
                update(temp->v, min[temp->v]);
            }
            temp = temp->next;
         }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int a[MAX];
int k = 0,pa;

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( !updated )
        printf("-1\n");
    else
    {
        a[k++] = n;
        pa = parent[n];
        while( 1 )
        {
            a[k++] = pa;
            pa = parent[pa];
            if( pa == 1 )
                break;
        }
        a[k] = 1;
        printf("%d",a[k]);
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = temp;
        return;
    }
    temp2 = head[v1];

    while( 1 )
    {
        if( temp2->v == v2 )
        {
            if( temp2->wt == 1 )
                temp2->wt = wt;
            flag = 1;
            break;
        }
        if( temp2->next == NULL )
            break;
        temp2 = temp2->next;
    }
    if( !flag )
        temp2->next = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;

    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( temp->wt + min[ver] < min[temp->v] )
            {
                min[temp->v] = temp->wt + min[ver];
                if( temp->v == n )
                    updated = 1;
                parent[temp->v] = ver;
                update(temp->v, min[temp->v]);
            }
            temp = temp->next;
         }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int a[MAX];
int k = 0,pa;

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( !updated )
        printf("-1\n");
    else
    {
        a[k++] = n;
        pa = parent[n];
        while( 1 )
        {
            a[k++] = pa;
            pa = parent[pa];
            if( pa == 1 )
                break;
        }
        a[k] = 1;
        printf("%d",a[k]);
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#define MAX 100005
#define MAXI 300005

struct node
{
    int v;
    int wt;
    struct node* next;
};

struct vertex
{
    int v;
    int min;
};

struct node *head[MAX];
struct node *tail[MAX];
struct vertex heap[MAXI];
int position[MAX],count,min[MAX];
int updated;
int parent[MAX];

void iheap( int v, int min )
{
int temp,parent,child;
struct vertex temp2;

    count++;
    heap[count].v = v;
    heap[count].min = min;
    position[v] = count;
    heap[2*count].min = INT_MAX;
    heap[2*count+1].min = INT_MAX;

    child = count;
    parent = child/2;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}

int dheap()
{
struct vertex temp2,node;
int parent,child1,child2;
int temp;

if( count == 0 )
    return;

node = heap[1];
position[heap[1].v] = 0;
if( count >=2 )
{
    heap[1] = heap[count];
    position[heap[1].v] = 1;
}

heap[count].min = INT_MAX;
heap[count].v = 0;
count--;

parent = 1;
child1 = 2*parent;
child2 = 2*parent+1;

    while( heap[parent].min > heap[child1].min || heap[parent].min > heap[child2].min )
    {
        if( heap[child1].min < heap[child2].min )
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child1].v];
            position[heap[child1].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child1];
            heap[child1] = temp2;

            parent = child1;
        }
        else
        {
            temp = position[heap[parent].v];
            position[heap[parent].v] = position[heap[child2].v];
            position[heap[child2].v] = temp;

            temp2 = heap[parent];
            heap[parent] = heap[child2];
            heap[child2] = temp2;

            parent = child2;
        }

        child1 = parent*2;
        child2 = parent*2+1;
    }

return node.v;
}

void update( int v, int min )
{
int child = position[v];
int parent = child/2;
struct vertex temp2;

heap[child].min = min;

    if( parent == 0 )
        return;

    while( heap[parent].min > heap[child].min )
    {
            /* SWAP RESPECTIVE HEAP POSITION */
            position[heap[parent].v] = child;
            position[heap[child].v] = parent;

            /* SWAP HEAP ELEMENTS */
            temp2 = heap[parent];
            heap[parent] = heap[child];
            heap[child] = temp2;

            child = parent;
            parent = child/2;
            if( parent == 0 )
                break;
    }
return;
}
int child[MAX];

void insert(int v1, int v2, int wt)
{
int flag = 0;
struct node* temp2 = NULL;
struct node* temp = (struct node *)malloc(sizeof(struct node));
temp->v = v2;
temp->wt = wt;
temp->next = NULL;

    if( head[v1] == NULL )
    {
        head[v1] = tail[v1] = temp;
        return;
    }

    tail[v1]->next = temp;
    tail[v1] = temp;

return;
}

void dijkstra( int n )
{
int i,ver;
struct node* temp;
    iheap( 1, 0 );
    min[1] = 0;

    for( i=2 ; i<=n ; i++ )
    {
        iheap( i, INT_MAX );
        min[i] = INT_MAX;
    }

    while( count!= 0 )
    {
         ver =  dheap();
         temp = head[ver];
         while( temp != NULL )
         {
            if( temp->wt + min[ver] < min[temp->v] )
            {
                min[temp->v] = temp->wt + min[ver];
                if( temp->v == n )
                    updated = 1;
                parent[temp->v] = ver;
                update(temp->v, min[temp->v]);
            }
            temp = temp->next;
         }
    }
}

int main()
{
int n,e,v1,v2,i,t,wt;
int k = 0;
int a[MAX];

    scanf("%d %d",&n,&e);

    heap[0].v = 0;
    heap[0].min = INT_MIN;

    memset(head,0,sizeof(struct node*)*MAX);
    memset(tail,0,sizeof(struct node*)*MAX);

    count = 0;

    while( e-- )
    {
        scanf("%d %d %d",&v1,&v2,&wt);
        insert(v1,v2,wt);
        insert(v2,v1,wt);
    }

    dijkstra(n);

    if( !updated )
        printf("-1\n");
    else
    {

        a[k++] = n;
        t = parent[n];
        while( t != 1 )
        {
            a[k++] = t;
            t = parent[t];
        }
        printf("1");
        for(i=k-1;i>=0;i--)
            printf(" %d",a[i]);
        printf("\n");
    }
return 0;
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;
	public static boolean[] visit;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+10];
		visit = new boolean[vertexes+1];
		int i = 0;
		while(x != 1){
			if(visit[x]){
				pw.println("-1");
				return;
			}
			auxOutput[i] = x;
			visit[x] = true;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;
	public static boolean[] visit;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		long[] dist = new long[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+10];
		visit = new boolean[vertexes+1];
		int i = 0;
		while(x != 1){
			if(visit[x]){
				pw.println("-1");
				return;
			}
			auxOutput[i] = x;
			visit[x] = true;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to;
	public long weight;

	public WeightedEdge(int to, long weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return (int) (x.weight - y.weight);
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+1];
		int i = 0;
		while(parent[x] != x){
			auxOutput[i] = x;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;
	public static boolean[] visit;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		//boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			//if(mark[current])continue;
			//mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+10];
		visit = new boolean[vertexes+1];
		int i = 0;
		while(x != 1){
			if(visit[x]){
				pw.println("-1");
				return;
			}
			auxOutput[i] = x;
			visit[x] = true;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[1000000];
		int i = 0;
		while(parent[x] != x){
			auxOutput[i] = x;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;
	public static boolean[] visit;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = -1;
		long[] dist = new long[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight || dist[pair.to] == infinite){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+10];
		visit = new boolean[vertexes+1];
		int i = 0;
		while(x != 1){
			if(visit[x]){
				pw.println("-1");
				return;
			}
			auxOutput[i] = x;
			visit[x] = true;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to;
	public long weight;

	public WeightedEdge(int to, long weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return (int) (x.weight - y.weight);
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[1000000];
		int i = 0;
		while(x != 1){
			auxOutput[i] = x;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		String[] path = new String[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			path[i] = "";
		}

		dist[initial] = 0;
		path[initial] = "" + initial;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					path[pair.to] = path[current] + " " + pair.to;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(path[vertexes].equals("")){
			pw.println("-1");
		} else {
			pw.println(path[vertexes]);
		}
		pw.close();
	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static String[] path;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		path = new String[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			path[i] = "";
		}

		dist[initial] = 0;
		path[initial] = "" + initial;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					path[pair.to] = path[current] + " " + pair.to;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(path[vertexes].equals("")){
			pw.println("-1");
		} else {
			pw.println(path[vertexes]);
		}
		pw.close();
	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[200000];
		int i = 0;
		while(parent[x] != x){
			auxOutput[i] = x;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		List<Integer> output = new ArrayList<>();
		while(parent[x] != x){
			output.add(x);
			x = parent[x];
		}
		output.add(x);

		for(int i = output.size()-1; i > 0; i--){
			pw.print(output.get(i) + " ");
		}
		pw.println(output.get(0));

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;
	public static boolean[] visit;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] >= dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes+10];
		visit = new boolean[vertexes+1];
		int i = 0;
		while(x != 1){
			if(visit[x]){
				pw.println("-1");
				return;
			}
			auxOutput[i] = x;
			visit[x] = true;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		printOutput(vertexes, pw);
		pw.println();
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		if(parent[x] == x){
			pw.print(x);
		} else {
			printOutput(parent[x], pw);
			pw.print(" " + x);
		}

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		String[] path = new String[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			path[i] = "";
		}

		dist[initial] = 0;
		path[initial] = "" + initial;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					path[pair.to] = path[current] + " " + pair.to;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(path[vertexes].equals("")){
			pw.println("-1");
		} else {
			pw.println(path[vertexes]);
		}
		pw.close();
	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		if(parent[x] == x){
			pw.print(x);
		} else {
			printOutput(parent[x], pw);
			pw.print(" " + x);
		}

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		String[] path = new String[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			path[i] = "";
		}

		dist[initial] = 0;
		path[initial] = "" + initial;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					path[pair.to] = path[current] + " " + pair.to;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		pw.println(path[vertexes]);
		pw.close();
	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
	public static PriorityQueue<WeightedEdge> pq;
	public static int vertexes, edges;
	public static List<List<WeightedEdge>> connections;
	public static int[] parent, auxOutput;

	public static void main(String[] args) throws IOException {
		pq = new PriorityQueue<WeightedEdge>(1000, new Comp());
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");
		vertexes = Integer.valueOf(input[0]);
		edges = Integer.valueOf(input[1]);

		connections = new ArrayList<>(vertexes+1);
		for(int i = 0; i <= vertexes; i++){
			connections.add(new ArrayList<WeightedEdge>());
		}

		int x, y, w;
		for(int i = 0; i < edges; i++){
			input = br.readLine().split(" ");
			x = Integer.valueOf(input[0]);
			y = Integer.valueOf(input[1]);
			w = Integer.valueOf(input[2]);

			connections.get(x).add(new WeightedEdge(y, w));
			connections.get(y).add(new WeightedEdge(x, w));
		}

		// complentar isso
		dijkstra(1);
	}

	private static void dijkstra(int initial){
		int infinite = Integer.MAX_VALUE;
		int[] dist = new int[vertexes+1];
		boolean[] mark = new boolean[vertexes+1];
		parent = new int[vertexes+1];
		for(int i = 0; i <= vertexes; i++){
			dist[i] = infinite;
			parent[i] = i;
		}

		dist[initial] = 0;
		pq.add(new WeightedEdge(initial, dist[initial]));
		int current;
		while(!pq.isEmpty()){
			current = pq.remove().to;
			if(mark[current])continue;
			mark[current] = true;
			for(WeightedEdge pair : connections.get(current)){
				if(dist[pair.to] > dist[current] + pair.weight){
					dist[pair.to] = dist[current] + pair.weight;
					parent[pair.to] = current;
					pq.add(new WeightedEdge(pair.to, dist[pair.to]));
				}
			}
		}
		PrintWriter pw = new PrintWriter(System.out);
		if(parent[vertexes] == vertexes){
			pw.println("-1");
		}else{
			printOutput(vertexes, pw);
			pw.println();
		}
		pw.close();
	}

	private static void printOutput(int x, PrintWriter pw) {
		auxOutput = new int[vertexes];
		int i = 0;
		while(parent[x] != x){
			auxOutput[i] = x;
			x = parent[x];
			i++;
		}
		auxOutput[i] = x;

		while(i > 0){
			pw.print(auxOutput[i] + " ");
			i--;
		}
		pw.println(auxOutput[0]);

	}

}

class WeightedEdge{
	public int to, weight;

	public WeightedEdge(int to, int weight){
		this.to = to;
		this.weight = weight;
	}
}

class Comp implements Comparator<WeightedEdge>{

	@Override
	public int compare(WeightedEdge x, WeightedEdge y) {
		return x.weight - y.weight;
	}

}


import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader in;
	static PrintWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args) throws IOException {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
		} catch (Exception e) {
			in = new BufferedReader(new FileReader("input.txt"));
			out = new PrintWriter(new File("output.txt"));
		}
		new Main().solve();
		out.flush();
		out.close();
	}

	void solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		ArrayList<Edge> g[] = new ArrayList[n+1];
		for (int i = 0; i <= n; i++) {
			g[i] = new ArrayList<>();
		}
		for (int i = 0; i < m; i++) {
			int v = nextInt();
			int to = nextInt();
			int cost = nextInt();
			g[v].add(new Edge(v, to, cost));
			g[to].add(new Edge(to, v, cost));
		}

		boolean used[] = new boolean[n+1];
		int[] d = new int[n+1];
		int[] p = new int[n+1];
		int inf = Integer.MAX_VALUE;
		Arrays.fill(d, inf);
		//Arrays.fill(p, -1);
		TreeSet<Edge> treeSet = new TreeSet<>();
		treeSet.add(new Edge(1, -1, 0));
		d[1] = 0;

		while (!treeSet.isEmpty()) {
			Edge e = treeSet.pollFirst();

			for (int i = 0; i < g[e.v].size(); i++) {
				Edge next = g[e.v].get(i);
				if (next.cost + d[e.v] < d[next.to]) {
					d[next.to] = next.cost + d[e.v];
					p[next.to] = e.v;
					treeSet.add(new Edge(next.to, -1, d[next.to]));
				}
			}
		}

		if (d[n] == inf) {
			out.println(-1);
			return;
		}

		ArrayList<Integer> ans = new ArrayList<>();
		for (int i = n; i != 0; i = p[i]) {
			ans.add(i);
		}
		for (int i = ans.size()-1; i >= 0; i--) {
			out.print(ans.get(i) + " ");
		}

	}

	String nextTok() throws IOException {
		while (!tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.valueOf(nextTok());
	}

	class Edge implements Comparable<Edge> {
		int v;
		int to;
		int cost;

		Edge(int v, int to, int cost) {
			this.v = v;
			this.to = to;
			this.cost = cost;
		}

		public int compareTo(Edge e) {
			return Integer.compare(this.cost, e.cost);
		}
	}

}


import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader in;
	static PrintWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args) throws IOException {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
		} catch (Exception e) {
			in = new BufferedReader(new FileReader("input.txt"));
			out = new PrintWriter(new File("output.txt"));
		}
		new Main().solve();
		out.flush();
		out.close();
	}

	void solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		ArrayList<Edge> g[] = new ArrayList[n+1];
		for (int i = 0; i <= n; i++) {
			g[i] = new ArrayList<>();
		}
		for (int i = 0; i < m; i++) {
			int v = nextInt();
			int to = nextInt();
			int cost = nextInt();
			g[v].add(new Edge(v, to, cost));
			g[to].add(new Edge(to, v, cost));
		}

		boolean used[] = new boolean[n+1];
		int[] d = new int[n+1];
		int[] p = new int[n+1];
		int inf = Integer.MAX_VALUE;
		Arrays.fill(d, inf);
		//Arrays.fill(p, -1);
		TreeSet<Edge> treeSet = new TreeSet<>();
		treeSet.add(new Edge(1, -1, 0));
		d[1] = 0;

		while (!treeSet.isEmpty()) {
			int v = treeSet.pollFirst().v;

			for (int i = 0; i < g[v].size(); i++) {
				Edge next = g[v].get(i);
				if (next.cost + d[v] < d[next.to]) {
					treeSet.remove(new Edge(next.to, -1, d[next.to]));
					d[next.to] = next.cost + d[v];
					p[next.to] = v;
					treeSet.add(new Edge(next.to, -1, d[next.to]));
				}
			}
		}

		if (d[n] == inf) {
			out.println(-1);
			return;
		}

		ArrayList<Integer> ans = new ArrayList<>();
		for (int i = n; i != 0; i = p[i]) {
			ans.add(i);
		}
		for (int i = ans.size()-1; i >= 0; i--) {
			out.print(ans.get(i) + " ");
		}

	}

	String nextTok() throws IOException {
		while (!tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.valueOf(nextTok());
	}

	class Edge implements Comparable<Edge> {
		int v;
		int to;
		int cost;

		Edge(int v, int to, int cost) {
			this.v = v;
			this.to = to;
			this.cost = cost;
		}

		public int compareTo(Edge e) {
			if (this.cost != e.cost) {
				return this.cost - e.cost;
			} else {
				return this.v = e.v;
			}
		}
	}

}


import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader in;
	static PrintWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args) throws IOException {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
		} catch (Exception e) {
			in = new BufferedReader(new FileReader("input.txt"));
			out = new PrintWriter(new File("output.txt"));
		}
		new Main().solve();
		out.flush();
		out.close();
	}

	void solve() throws IOException {
		int n = nextInt();
		int m = nextInt();
		ArrayList<Edge> g[] = new ArrayList[n+1];
		long[] d = new long[n+1];
		int[] p = new int[n+1];
		long inf = Long.MAX_VALUE/2;

		for (int i = 0; i <= n; i++) {
			g[i] = new ArrayList<>();
			d[i] = inf;
			p[i] = -1;
		}
		for (int i = 0; i < m; i++) {
			int v = nextInt();
			int to = nextInt();
			int cost = nextInt();
			g[v].add(new Edge(to, cost));
			g[to].add(new Edge(v, cost));
		}

		TreeSet<Edge> treeSet = new TreeSet<>();
		d[1] = 0;
		treeSet.add(new Edge(1, 0));

		while (!treeSet.isEmpty()) {
			int v = treeSet.pollFirst().to;

			for (int i = 0; i < g[v].size(); i++) {
				Edge next = g[v].get(i);
				if (next.cost + d[v] < d[next.to]) {
					d[next.to] = next.cost + d[v];
					p[next.to] = v;
					treeSet.add(new Edge(next.to, d[next.to]));
				}
			}
		}

		if (d[n] == inf) {
			out.println(-1);
			return;
		}

		ArrayList<Integer> ans = new ArrayList<>();
		out.print("1 ");
		for (int i = n; i != 1; i = p[i]) {
			ans.add(i);
		}
		for (int i = ans.size()-1; i >= 0; i--) {
			out.print(ans.get(i) + " ");
		}

	}

	String nextTok() throws IOException {
		while (!tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.valueOf(nextTok());
	}

	class Edge implements Comparable<Edge> {
		int to;
		long cost;

		Edge(int to, long cost) {
			this.to = to;
			this.cost = cost;
		}

		public int compareTo(Edge e) {
			return Long.compare(this.cost, e.cost);
		}
	}

}