#!/usr/bin/env python

# -*- coding: utf-8 -*-



"""

input:

5

0 3 2 3 3 1 1 2

1 2 0 2 3 4

2 3 0 3 3 1 4 1

3 4 2 1 0 1 1 4 4 3

4 2 2 1 3 3



output:

0 0

1 2

2 2

3 1

4 3

"""



import sys

import heapq as hp



WHITE, GRAY, BLACK = 0, 1, 2

D_MAX = int(5e10 + 1)





def generate_adj_matrix(v_info):

    for each in v_info:

        v_index, v_adj_length, *v_adj_list = list(map(int, each))

        # assert len(v_adj_list) == v_adj_length * 2

        for pair in zip(v_adj_list[::2], v_adj_list[1::2]):

            init_adj_matrix[v_index][pair[0]] = pair[1]



    return init_adj_matrix





def dijkstra_path():

    # path search init

    path_list[init_vertex_index] = 0

    path_heap = []

    # heapq: rank by tuple[0], here ranked by d[u]

    hp.heappush(path_heap, (0, init_vertex_index))

    while len(path_heap) >= 1:

        current_vertex_index = hp.heappop(path_heap)[1]



        color[current_vertex_index] = BLACK



        current_vertex_index_info = adj_table[current_vertex_index]

        for adj_vertex_index in list(current_vertex_index_info.keys()):

            current_adj_weight = current_vertex_index_info.get(adj_vertex_index)

            if color[adj_vertex_index] is not BLACK:

                # alt: d[u] + w[u,v]

                alt_path = path_list[current_vertex_index] + current_adj_weight

                if alt_path < path_list[adj_vertex_index]:

                    # update path_list

                    path_list[adj_vertex_index] = alt_path

                    # update heap

                    hp.heappush(path_heap, (alt_path, adj_vertex_index))

                    parent_list[adj_vertex_index] = current_vertex_index

                    color[adj_vertex_index] = GRAY



    return path_list





if __name__ == '__main__':

    _input = sys.stdin.readlines()

    vertices_num = int(_input[0])

    init_vertices_table = [x.split() for x in _input[1:]]

    # assert len(init_vertices_table) == vertices_num



    parent_list, path_list = [-1] * vertices_num, [D_MAX] * vertices_num

    color = [WHITE] * vertices_num

    init_adj_matrix = tuple(dict() for _ in range(vertices_num))

    init_vertex_index = 0



    adj_table = generate_adj_matrix(init_vertices_table)

    ans = dijkstra_path()

    for i, v in enumerate(ans):

        print((i, v))
#!/usr/bin/env python

# -*- coding: utf-8 -*-



"""

input:

5

0 3 2 3 3 1 1 2

1 2 0 2 3 4

2 3 0 3 3 1 4 1

3 4 2 1 0 1 1 4 4 3

4 2 2 1 3 3



output:

0 0

1 2

2 2

3 1

4 3

"""



import sys

import heapq as hp



WHITE, GRAY, BLACK = 0, 1, 2

D_MAX = int(5e10 + 1)





def generate_adj_table(v_table):

    for each in v_table:

        v_index, v_adj_length, *v_adj_list = list(map(int, each))

        # assert len(v_adj_list) == v_adj_length * 2

        for pair in zip(v_adj_list[::2], v_adj_list[1::2]):

            init_adj_table[v_index][pair[0]] = pair[1]



    return init_adj_table





def dijkstra_path_heap():

    # path search init

    path_list[init_vertex_index] = 0

    path_heap = []

    # heapq: rank by tuple[0], at here it's d[u]

    hp.heappush(path_heap, (0, init_vertex_index))



    while len(path_heap) >= 1:

        current_vertex = hp.heappop(path_heap)[1]



        color[current_vertex] = BLACK



        current_vertex_adjs = adj_table[current_vertex]

        for adj_vertex, adj_weight in list(current_vertex_adjs.items()):

            # adj_weight = current_vertex_adjs.get(adj_vertex)

            if color[adj_vertex] is not BLACK:

                # alt: d[u] + w[u,v]

                alt_path = path_list[current_vertex] + adj_weight

                if alt_path < path_list[adj_vertex]:

                    # update path_list

                    path_list[adj_vertex] = alt_path

                    # update heap

                    hp.heappush(path_heap, (alt_path, adj_vertex))

                    parent_list[adj_vertex] = current_vertex

                    color[adj_vertex] = GRAY



    return path_list





if __name__ == '__main__':

    _input = sys.stdin.readlines()

    vertices_num = int(_input[0])

    init_vertices_table = [x.split() for x in _input[1:]]

    # assert len(init_vertices_table) == vertices_num



    parent_list, path_list = [-1] * vertices_num, [D_MAX] * vertices_num

    color = [WHITE] * vertices_num

    init_adj_table = tuple(dict() for _ in range(vertices_num))

    init_vertex_index = 0



    adj_table = generate_adj_table(init_vertices_table)

    ans = dijkstra_path_heap()

    for i, v in enumerate(ans):

        print((i, v))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
output:
0 0
1 2
2 2
3 1
4 3
"""
import sys
import heapq as hp

WHITE, GRAY, BLACK = 0, 1, 2
D_MAX = int(5e10 + 1)


def generate_adj_matrix(v_info):
    for each in v_info:
        v_index, v_adj_length, *v_adj_list = list(map(int, each))
        # assert len(v_adj_list) == v_adj_length * 2
        for pair in zip(v_adj_list[::2], v_adj_list[1::2]):
            init_adj_matrix[v_index][pair[0]] = pair[1]
    return init_adj_matrix


def dijkstra_path():
    # path search init
    path_list[init_vertex_index] = 0
    path_heap = []
    # heapq: rank by tuple[0], here ranked by d[u]
    hp.heappush(path_heap, (0, init_vertex_index))
    while len(path_heap) >= 1:
        current_vertex_index = hp.heappop(path_heap)[1]
        color[current_vertex_index] = BLACK
        current_vertex_index_info = adj_table[current_vertex_index]
        for adj_vertex_index in list(current_vertex_index_info.keys()):
            current_adj_weight = current_vertex_index_info.get(adj_vertex_index)
            if color[adj_vertex_index] is not BLACK:
                # alt: d[u] + w[u,v]
                alt_path = path_list[current_vertex_index] + current_adj_weight
                if alt_path < path_list[adj_vertex_index]:
                    # update path_list
                    path_list[adj_vertex_index] = alt_path
                    # update heap
                    hp.heappush(path_heap, (alt_path, adj_vertex_index))
                    parent_list[adj_vertex_index] = current_vertex_index
                    color[adj_vertex_index] = GRAY
    return path_list


if __name__ == "__main__":
    _input = sys.stdin.readlines()
    vertices_num = int(_input[0])
    init_vertices_table = [x.split() for x in _input[1:]]
    # assert len(init_vertices_table) == vertices_num
    parent_list, path_list = [-1] * vertices_num, [D_MAX] * vertices_num
    color = [WHITE] * vertices_num
    init_adj_matrix = tuple(dict() for _ in range(vertices_num))
    init_vertex_index = 0
    adj_table = generate_adj_matrix(init_vertices_table)
    ans = dijkstra_path()
    for i, v in enumerate(ans):
        print((i, v))

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
output:
0 0
1 2
2 2
3 1
4 3
"""
import sys
import heapq as hp

WHITE, GRAY, BLACK = 0, 1, 2
D_MAX = int(5e10 + 1)


def generate_adj_table(v_table):
    for each in v_table:
        v_index, v_adj_length, *v_adj_list = list(map(int, each))
        # assert len(v_adj_list) == v_adj_length * 2
        for pair in zip(v_adj_list[::2], v_adj_list[1::2]):
            init_adj_table[v_index][pair[0]] = pair[1]
    return init_adj_table


def dijkstra_path_heap():
    # path search init
    path_list[init_vertex_index] = 0
    path_heap = []
    # heapq: rank by tuple[0], at here it's d[u]
    hp.heappush(path_heap, (0, init_vertex_index))
    while len(path_heap) >= 1:
        current_vertex = hp.heappop(path_heap)[1]
        color[current_vertex] = BLACK
        current_vertex_adjs = adj_table[current_vertex]
        for adj_vertex, adj_weight in list(current_vertex_adjs.items()):
            # adj_weight = current_vertex_adjs.get(adj_vertex)
            if color[adj_vertex] is not BLACK:
                # alt: d[u] + w[u,v]
                alt_path = path_list[current_vertex] + adj_weight
                if alt_path < path_list[adj_vertex]:
                    # update path_list
                    path_list[adj_vertex] = alt_path
                    # update heap
                    hp.heappush(path_heap, (alt_path, adj_vertex))
                    parent_list[adj_vertex] = current_vertex
                    color[adj_vertex] = GRAY
    return path_list


if __name__ == "__main__":
    _input = sys.stdin.readlines()
    vertices_num = int(_input[0])
    init_vertices_table = [x.split() for x in _input[1:]]
    # assert len(init_vertices_table) == vertices_num
    parent_list, path_list = [-1] * vertices_num, [D_MAX] * vertices_num
    color = [WHITE] * vertices_num
    init_adj_table = tuple(dict() for _ in range(vertices_num))
    init_vertex_index = 0
    adj_table = generate_adj_table(init_vertices_table)
    ans = dijkstra_path_heap()
    for i, v in enumerate(ans):
        print((i, v))

-def generate_adj_matrix(v_info): -    for each in v_info: +def generate_adj_table(v_table): +    for each in v_table: -            init_adj_matrix[v_index][pair[0]] = pair[1] -    return init_adj_matrix +            init_adj_table[v_index][pair[0]] = pair[1] +    return init_adj_table -def dijkstra_path(): +def dijkstra_path_heap(): -    # heapq: rank by tuple[0], here ranked by d[u] +    # heapq: rank by tuple[0], at here it's d[u] -        current_vertex_index = hp.heappop(path_heap)[1] -        color[current_vertex_index] = BLACK -        current_vertex_index_info = adj_table[current_vertex_index] -        for adj_vertex_index in list(current_vertex_index_info.keys()): -            current_adj_weight = current_vertex_index_info.get(adj_vertex_index) -            if color[adj_vertex_index] is not BLACK: +        current_vertex = hp.heappop(path_heap)[1] +        color[current_vertex] = BLACK +        current_vertex_adjs = adj_table[current_vertex] +        for adj_vertex, adj_weight in list(current_vertex_adjs.items()): +            # adj_weight = current_vertex_adjs.get(adj_vertex) +            if color[adj_vertex] is not BLACK: -                alt_path = path_list[current_vertex_index] + current_adj_weight -                if alt_path < path_list[adj_vertex_index]: +                alt_path = path_list[current_vertex] + adj_weight +                if alt_path < path_list[adj_vertex]: -                    path_list[adj_vertex_index] = alt_path +                    path_list[adj_vertex] = alt_path -                    hp.heappush(path_heap, (alt_path, adj_vertex_index)) -                    parent_list[adj_vertex_index] = current_vertex_index -                    color[adj_vertex_index] = GRAY +                    hp.heappush(path_heap, (alt_path, adj_vertex)) +                    parent_list[adj_vertex] = current_vertex +                    color[adj_vertex] = GRAY -    init_adj_matrix = tuple(dict() for _ in range(vertices_num)) +    init_adj_table = tuple(dict() for _ in range(vertices_num)) -    adj_table = generate_adj_matrix(init_vertices_table) -    ans = dijkstra_path() +    adj_table = generate_adj_table(init_vertices_table) +    ans = dijkstra_path_heap()